NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Audio/AudioCriManager.cs

701 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//流式播放的音频管理器
using System.Collections.Generic;
using CriWare;
using Framework;
using PhxhSDK;
using UnityEngine;
using AudioType = PhxhSDK.AudioBase.AudioType;
public class AudioCriManager: Singlenton<AudioCriManager>, IStart, IInitable, IUpdatable, IAudioPlay
{
public GameObject initGameObject;
public GameObject AudioRoot;
public GameObject CriAtomRoot;
public CriAtom CriAtom;
public ClipType curClipType;
private AudioInst _bgmAudio;
public enum EPlayType
{
Music,
Sound,
Speak
}
private GameObject _criError;
private Dictionary<int, AudioInst> _soundAudioDic;
private Dictionary<int, AudioInst> _musicAudioDic;
private Dictionary<int, AudioInst> _allAudioDic;
private List<GameObject> _soundAudioObj;
private List<GameObject> _musicAudioObj;
private List<AudioInst> _soundAudioQue;
private const int SOUND_MAX_NUM = 20;
private const int MUSIC_MAX_NUM = 2;
#region Property
private float _vol = 1f;
public float GlobalSoundsVolume
{
get => AudioCri.GlobalSoundVolume;
set => AudioCri.GlobalSoundVolume = value;
}
public float GlobalSpeakVolume{
get => AudioCri.GlobalSpeakVolume;
set => AudioCri.GlobalSpeakVolume = value;
}
public float GlobalMusicVolume {
get => AudioCri.GlobalMusicVolume;
set => AudioCri.GlobalMusicVolume = value;
}
public float GlobalVolume
{
get => AudioCri.GlobalVolume;
set => AudioCri.GlobalVolume = value;
}
public bool GlobalIsOpenSpeak;
public AudioInst BgmAudio => _bgmAudio;
public CriAtomExOutputAnalyzer analyzer=null;
public bool IsAnalyzer = false;
#endregion
#region Analyze
//在播放之前注册
public CriAtomExOutputAnalyzer RegisterAnalyzer()//CriAtomExOutputAnalyzer s
{
IsAnalyzer = true;
if (analyzer == null)
{
analyzer = new(NewAnalyzerConfig());
}
return analyzer;
//analyzer = s;
}
public void UnregisterAnalyzer()//CriAtomExOutputAnalyzer s
{
//s.DetachExPlayer();
IsAnalyzer = false;
//analyzer = null;
}
/// <summary>
/// 获取音频输出分析器配置
/// </summary>
/// <returns></returns>
private CriAtomExOutputAnalyzer.Config NewAnalyzerConfig()
{
CriAtomExOutputAnalyzer.Config config = new()
{
enableSpectrumAnalyzer = true, // 开启频谱分析
numSpectrumAnalyzerBands = 16, // 频谱分析数量SPECTRUM_SAMPLES_NUMBER
};
return config;
}
#endregion
#region Framework
public void Start()
{
if (!AudioRoot)
{
curClipType = ClipType.CriwareClip;
AudioRoot = new GameObject();
AudioRoot.name = "Audio(Singleton)";
Object.DontDestroyOnLoad(AudioRoot);
if (curClipType == ClipType.CriwareClip)
{
_criError = new GameObject();
_criError.name = "CriwareError";
_criError.AddComponent<CriWareErrorHandler>();
Object.DontDestroyOnLoad(_criError);
}
var initialize = GameObject.Find("CriWareLibraryInitializer");
Object.DontDestroyOnLoad(initialize);
CriAtomRoot = GameObject.Find("CriAtom");
CriAtom = CriAtomRoot.GetComponent<CriAtom>();
Object.DontDestroyOnLoad(CriAtomRoot);
}
// CriAtomRoot = new GameObject()
// {
// name = "CriAtom"
// };
// CriAtom = CriAtomRoot.AddComponent<CriAtom>();
// CriAtom.AddCueSheet()
// for (int i = 0; i < SOUND_MAX_NUM; i++)
// {
// var go = new GameObject
// {
// name = "Sound" + (i+1)
// };
// go.transform.SetParent(AudioRoot.transform);
// }
//
// for (int i = 0; i < MUSIC_MAX_NUM; i++)
// {
// var go = new GameObject
// {
// name = "Music" + (i+1)
// };
// go.transform.SetParent(AudioRoot.transform);
// }
}
public void Init()
{
_soundAudioDic = new Dictionary<int, AudioInst>();
_musicAudioDic = new Dictionary<int, AudioInst>();
_allAudioDic = new Dictionary<int, AudioInst>();
_soundAudioObj = new();
_musicAudioObj = new();
}
public void Release()
{
}
public void Update(float dt)
{
foreach (var kv in _musicAudioDic)
{
var audio = kv.Value;
if (!audio.IsStopped)
{
audio.Update();
}
}
foreach (var kv in _soundAudioDic)
{
var audio = kv.Value;
if (!audio.IsStopped)
{
audio.Update();
}
}
}
#endregion
#region LoadAsset
private string _GetCriPath(string name)
{
var commonStr = "CueSheet_";
var strArr = name.Split('_');
var pre = strArr[0];
if (pre != null)
{
if (pre == "Voice")
{
return commonStr + "VOICE";
}
if (pre == "skill")
{
return commonStr + "SE";
}
if (pre == "bgm")
{
return commonStr + "BGM";
}
}
return null;
}
private string _GetAcbPath(string name)
{
var path = _GetCriPath(name);
if (path == null)
{
DebugUtil.LogError($"获取不到对应的ACB文件key: {name}");
return "";
}
return path + ".acb";
}
private string _GetAwbPath(string name)
{
var path = _GetCriPath(name);
if (path == null)
{
DebugUtil.LogError($"获取不到对应的AWB文件key: {name}");
return "";
}
return path + ".awb";
}
private string _GetAcfPath(string name)
{
var path = _GetCriPath(name);
if (path == null)
{
DebugUtil.LogError($"获取不到对应的ACF文件key: {name}");
return "";
}
return path + ".acf";
}
#endregion
#region AudioObj
/// <summary>
/// 获取可用的Audio
/// </summary>
/// <param name="audioType"></param>
/// <returns></returns>
private AudioInst _GetUsableAudio(AudioBase.AudioType audioType)
{
var freeAudio = _GetFreeAudio(audioType);
return freeAudio?? _CreateNewAudio(audioType);
}
private Dictionary<int, AudioInst> _GetAudioDic(AudioBase.AudioType audioType)
{
switch (audioType)
{
case AudioBase.AudioType.Music:
return _musicAudioDic;
case AudioBase.AudioType.Sound:
return _soundAudioDic;
default:
{
DebugUtil.LogError("获取AudioDic出错传入AudioType有误");
return null;
}
}
}
private AudioInst _GetFreeAudio(AudioBase.AudioType audioType)
{
var dic = _GetAudioDic(audioType);
if (dic != null)
{
foreach (var kv in dic)
{
var audio = kv.Value;
if (audio.IsStopped)
{
return audio;
}
}
}
return null;
}
private AudioInst _CreateNewAudio(AudioBase.AudioType audioType)
{
var rootGo = new GameObject()
{
name = "Audio"
};
rootGo.transform.SetParent(AudioRoot.transform);
var audio = new AudioInst(audioType, rootGo, null);
if (audioType == AudioBase.AudioType.Music)
{
rootGo.name = "music";
rootGo.name += audio.audioID;
_musicAudioDic.TryAdd(audio.audioID, audio);
_musicAudioObj.Add(rootGo);
}
if (audioType == AudioBase.AudioType.Sound)
{
rootGo.name = "Sound";
rootGo.name += audio.audioID;
_soundAudioDic.TryAdd(audio.audioID, audio);
_soundAudioObj.Add(rootGo);
}
return audio;
}
private int _CreateAudio(AudioBase.AudioType audioType, GameObject rootGo, GameObject posGo = null)
{
var dic = _GetAudioDic(audioType);
if (audioType == AudioBase.AudioType.Music && dic.Count >= MUSIC_MAX_NUM)
{
DebugUtil.Log("音乐播放数量超过上限!!!");
return -1;
}
if (audioType == AudioBase.AudioType.Sound && dic.Count >= SOUND_MAX_NUM)
{
DebugUtil.Log("音效播放数量超过上限!!!");
return -1;
}
AudioInst audio = new AudioInst(audioType, rootGo, posGo);
return audio.audioID;
}
#endregion
#region Play
/// <summary>
/// 调用接口传obj
/// </summary>
/// <param name="key"></param>
/// <param name="type"></param>
/// <param name="posObj"></param>
/// <returns></returns>
private int _PlayAudio(string key, EPlayType type, GameObject posObj = null)
{
if (CriAtom)
{
var cueSheetName = _GetCriPath(key);
if (CriAtom.GetCueSheetInternal(cueSheetName) == null)
{
var acbPath = _GetAcbPath(key);
var awbPath = _GetAwbPath(key);
if (string.IsNullOrEmpty(acbPath) || string.IsNullOrEmpty(awbPath))
{
return -1;
}
CriAtom.AddCueSheet(cueSheetName, acbPath, awbPath, null);
}
}
string path = _GetCriPath(key);
switch (type)
{
case EPlayType.Music:
{
return _PlayMusic(key, path, posObj);
}
case EPlayType.Sound:
{
return _PlaySound(key, path, posObj);
}
case EPlayType.Speak:
{
return _PlaySpeakSound(key, path, posObj);
}
default: break;
}
return -1;
}
/// <summary>
/// 调用接口,传位置
/// </summary>
/// <param name="key"></param>
/// <param name="type"></param>
/// <param name="pos"></param>
/// <returns></returns>
private int _PlayAudio(string key, EPlayType type, Vector3 pos)
{
if (CriAtom)
{
if (CriAtom.GetCueSheetInternal(key) == null)
{
var acbPath = _GetAcbPath(key);
var awbPath = _GetAwbPath(key);
if (string.IsNullOrEmpty(acbPath) || string.IsNullOrEmpty(awbPath))
{
return -1;
}
CriAtom.AddCueSheet(key, acbPath, awbPath, null);
}
}
string path = _GetCriPath(key);
switch (type)
{
case EPlayType.Music:
{
return _PlayMusic(key, path, pos);
}
case EPlayType.Sound:
{
return _PlaySound(key, path, pos);
}
case EPlayType.Speak:
{
return _PlaySpeakSound(key, path, pos);
}
default: break;
}
return -1;
}
private int _PlayMusic(string key, string path, GameObject posObj = null)
{
if (_bgmAudio != null)
{
_bgmAudio.Stop();
}
AudioInfo audioInfo = new AudioInfo()
{
persist = true,
volume = 1,
fadeInValue = 0.3f,
fadeOutValue = 0.3f,
};
var audio = _GetUsableAudio(AudioBase.AudioType.Music);
audio.SetPosObj(posObj);
audio.SetIsSpeak(false);
audio.SetIsLoop(true);
if (_bgmAudio != null && _bgmAudio != audio)
{
_bgmAudio.Stop();
}
audio.Play(path, key);
_bgmAudio = audio;
return audio.audioID;
}
private int _PlayMusic(string key, string path, Vector3 pos)
{
if (_bgmAudio != null)
{
_bgmAudio.Stop();
}
AudioInfo audioInfo = new AudioInfo()
{
persist = true,
volume = 1,
fadeInValue = 0.3f,
fadeOutValue = 0.3f,
};
var audio = _GetUsableAudio(AudioBase.AudioType.Music);
audio.SetPos(pos);
audio.SetIsSpeak(false);
audio.SetIsLoop(true);
if (_bgmAudio != null && _bgmAudio != audio)
{
_bgmAudio.Stop();
}
audio.Play(path, key);
_bgmAudio = audio;
return audio.audioID;
}
private int _PlaySound(string key, string path, GameObject posObj = null)
{
AudioInfo audioInfo = new AudioInfo()
{
persist = true,
volume = 1,
fadeInValue = 0.3f,
fadeOutValue = 0.3f,
};
var audio = _GetUsableAudio(AudioBase.AudioType.Sound);
audio.SetPosObj(posObj);
audio.SetIsSpeak(false);
audio.SetIsLoop(false);
audio.Play(path, key);
return audio.audioID;
}
private int _PlaySound(string key, string path, Vector3 pos)
{
AudioInfo audioInfo = new AudioInfo()
{
persist = true,
volume = 1,
fadeInValue = 0.3f,
fadeOutValue = 0.3f,
};
var audio = _GetUsableAudio(AudioBase.AudioType.Sound);
audio.SetPos(pos);
audio.SetIsLoop(false);
audio.SetIsSpeak(false);
audio.Play(path, key);
return audio.audioID;
}
private int _PlaySpeakSound(string key, string path, GameObject posObj = null)
{
AudioInfo audioInfo = new AudioInfo()
{
persist = true,
volume = 1,
fadeInValue = 0.3f,
fadeOutValue = 0.3f,
};
var audio = _GetUsableAudio(AudioBase.AudioType.Sound);
audio.SetPosObj(posObj);
audio.SetIsSpeak(true);
audio.SetIsLoop(false);
audio.Play(path, key);
return -1;
}
private int _PlaySpeakSound(string key, string path, Vector3 pos)
{
AudioInfo audioInfo = new AudioInfo()
{
persist = true,
volume = 1,
fadeInValue = 0.3f,
fadeOutValue = 0.3f,
};
var audio = _GetUsableAudio(AudioBase.AudioType.Sound);
audio.SetPos(pos);
audio.SetIsLoop(false);
audio.SetIsSpeak(true);
audio.Play(path, key);
return -1;
}
#endregion
#region API
public int PlayAudio(string key, EPlayType type, GameObject posObj = null)
{
return _PlayAudio(key, type, posObj);
}
public int PlayAudio(string key, EPlayType type, Vector3 pos)
{
return _PlayAudio(key, type, pos);
}
public int PlayAudio()
{
return -1;
}
public AudioInst GetAudioByID(EPlayType audioType, int id)
{
if (audioType == EPlayType.Music)
{
if (!_musicAudioDic.ContainsKey(id))
{
return null;
}
return _musicAudioDic[id];
}
if (audioType == EPlayType.Sound || audioType == EPlayType.Speak)
{
if (!_soundAudioDic.ContainsKey(id))
{
return null;
}
return _soundAudioDic[id];
}
return null;
}
public void StopMusicById(int audioID)
{
if (audioID >= 0)
{
if(_musicAudioDic.TryGetValue(audioID, out var audio))
{
audio.Stop();
}
}
}
public void StopAllMusic()
{
if (_bgmAudio != null)
{
_bgmAudio.Stop();
}
// foreach (var kv in _musicAudioDic)
// {
// var audio = kv.Value;
// audio.Stop();
// }
}
public void StopAllSounds()
{
foreach (var kv in _soundAudioDic)
{
var audio = kv.Value;
audio.Stop();
}
}
public void StopAll()
{
foreach (var kv in _soundAudioDic)
{
var audio = kv.Value;
audio.Stop();
}
}
public void ResumeAllMusic()
{
if (_bgmAudio != null)
{
_bgmAudio.Resume();
}
}
public void StopBGM()
{
_bgmAudio.Stop();
}
public void AfterSwitchMainCamera(Camera camera)
{
var listener = camera.GetComponent<CriAtomListener>();
if (!listener)
{
camera.gameObject.AddComponent<CriAtomListener>();
}
}
public CriAtomExAcb GetAcb(string cueSheetName)
{
return CriAtom.GetAcb(cueSheetName);
}
#endregion
}
public class AudioInst : AudioCri
{
public AudioInst(AudioType audioType, GameObject rootGo, GameObject posGo, AudioInfo audioInfo = new(),
bool loop = false, bool is3D = false):base(audioType, rootGo, posGo, audioInfo, loop, is3D)
{
}
}