using System; using System.Collections; using System.Collections.Generic; using CriWare; using UnityEngine; namespace Cute; public class AudioManager : MonoBehaviour, IManager { [SerializeField] private GameObject _bgmParent; [SerializeField] private CriAtomSource[] _bgm; private int _bgmSourceCount; [SerializeField] private GameObject _seParent; [SerializeField] private CriAtomSource[] _se; private int _seSourceCount; private SoundData[] _playingSe; [SerializeField] private GameObject _voiceParent; [SerializeField] private CriAtomSource[] _voice; private int _voiceSourceCount; private bool _bgmPlaySuspend; private const int BGM_FADEOUT_TIME = 500; private const int SONG_PREVIEW_FADE_TIME = 500; private const int SONG_PREVIEW_FADE_SPACE_TIME = 1500; private const float SE_FADE_TIME = 0.5f; public const int DELAY_TIME_OFFSET = -4; private const float VOULMN_BOOST_FACTOR = 1.5f; public const string ACB_EXTENSION_WITHPARAM = "{0}.acb"; public const string ACB_EXTENSION = ".acb"; public const string AWB_EXTENSION_WITHPARAM = "{0}.awb"; public const string AWB_EXTENSION = ".awb"; private const string STR_SUBFOLDER_BGM = "b/"; public const string STR_SUBFOLDER_SE = "s/"; private const string STR_SUBFOLDER_SONG = "l/"; private const string STR_SUBFOLDER_VOICE = "v/"; private const string STR_SUBFOLDER_STORY = "c/"; private const string STR_SUBFOLDER_ROOM = "r/"; public bool isDownloadVoiceUse = true; protected bool _isRedy; private bool _noSeMode; private CriAtomExPlayback _playback; private CriAtomExPlayback _bgmPlayback; private float _sampleTime; private int _delayTime; private int _criDelayTime; private int _criInitializeCount; private const int CRI_RETRY_COUNT = 3; private Dictionary _acbDictionary = new Dictionary(); private string[] STR_PREINSTALL_FILENAME = new string[1] { "preinstall" }; public const float VOICE_MASTER_VOLUME = 0.8f; private Action _callbackVoiseEnd; private string _bgmName = ""; private int _cueId = -1; private string _bgmCue = ""; public bool isRedy => _isRedy; public int delayTime { get { return _delayTime; } set { _delayTime = value; } } public string bgmName { get { return _bgmName; } set { _bgmName = value; } } public int cueId { get { return _cueId; } set { _cueId = value; } } public string bgmCue { get { return _bgmCue; } set { _bgmCue = value; } } private void Awake() { } private IEnumerator Start() { _bgm = _bgmParent.GetComponentsInChildren(); _bgmSourceCount = _bgm.Length; for (int i = 0; i < _bgmSourceCount; i++) { CriAtomExPlayer player = _bgm[i].player; player.AttachFader(); player.ResetFaderParameters(); player.SetFadeOutTime(500); } _se = _seParent.GetComponentsInChildren(); _seSourceCount = _se.Length; _playingSe = new SoundData[_seSourceCount]; for (int j = 0; j < _seSourceCount; j++) { CriAtomExPlayer player2 = _se[j].player; player2.AttachFader(); player2.ResetFaderParameters(); } _voice = _voiceParent.GetComponentsInChildren(); _voiceSourceCount = _voice.Length; for (int k = 0; k < _voiceSourceCount; k++) { CriAtomExPlayer player3 = _voice[k].player; player3.AttachFader(); player3.ResetFaderParameters(); } Toolbox.AudioManager = this; yield break; } public void ResetSoundMode() { _noSeMode = false; } private void Update() { } public void PauseAllBgm(bool pauseStatus) { if (pauseStatus) { _bgmPlaySuspend = false; for (int i = 0; i < _bgmSourceCount; i++) { if (_bgm[i].status == CriAtomSource.Status.Prep || _bgm[i].status == CriAtomSource.Status.Playing) { _bgm[i].Pause(sw: true); _bgmPlaySuspend = true; } } } else if (_bgmPlaySuspend) { for (int j = 0; j < _bgmSourceCount; j++) { _bgm[j].Pause(sw: false); } } } public long GetMusicLength(string acbName) { CriAtomExAcb acb = CriAtom.GetAcb(acbName); if (acb != null && acb.GetCueInfo(0, out var info)) { return info.length; } return -1L; } public bool IsAvailableCueSheet(string cueName) { CriAtomCueSheet cueSheet = CriAtom.GetCueSheet(cueName); if (cueSheet != null) { return cueSheet.acb != null; } return false; } public bool AddCueSheet(string _name, string acbFile, string subFolderPath, string awbname = "") { _name = _name.Replace(".acb", ""); if (CriAtom.GetCueSheet(_name) != null || CriAtom.GetCueSheet(acbFile) != null) { return true; } bool flag = false; int num = STR_PREINSTALL_FILENAME.Length; for (int i = 0; i < num; i++) { if (string.Compare(_name, STR_PREINSTALL_FILENAME[i]) == 0) { flag = true; break; } } if (flag) { acbFile = $"{subFolderPath}{acbFile}"; awbname = $"{subFolderPath}{awbname}"; } else { acbFile = string.Format("{0}{1}{2}{3}", Application.persistentDataPath, "/", subFolderPath, acbFile); awbname = string.Format("{0}{1}{2}{3}", Application.persistentDataPath, "/", subFolderPath, awbname); } CriAtomCueSheet criAtomCueSheet = CriAtom.AddCueSheet(_name, acbFile, awbname); if (criAtomCueSheet == null) { return false; } if (criAtomCueSheet.acb == null) { RemoveCueSheet(_name); return false; } return true; } public bool AddCueSheetFromFileName(string _name, string acbFile, string awbname) { _name = _name.Replace(".acb", ""); int num = STR_PREINSTALL_FILENAME.Length; for (int i = 0; i < num && string.Compare(_name, STR_PREINSTALL_FILENAME[i]) != 0; i++) { } if (CriAtom.GetCueSheet(_name) != null) { return true; } CriAtomCueSheet criAtomCueSheet = CriAtom.AddCueSheet(_name, acbFile, awbname); if (criAtomCueSheet == null) { return false; } if (criAtomCueSheet.acb == null) { RemoveCueSheet(_name); return false; } return true; } public void RemoveCueSheet(string name) { name = name.Replace(".awb", ""); name = name.Replace(".acb", ""); name = name.Replace("s/", ""); name = name.Replace("b/", ""); CriAtom.RemoveCueSheet(name); } public void RemoveCueSheet(List nameList) { for (int i = 0; i < nameList.Count; i++) { RemoveCueSheet(nameList[i]); } } public float GetSampleTime() { long numSamples = 0L; int samplingRate = 0; if (_playback.GetNumPlayedSamples(out numSamples, out samplingRate)) { _sampleTime = (float)numSamples / (float)samplingRate; } return _sampleTime; } private void OnDestroy() { foreach (KeyValuePair item in _acbDictionary) { item.Value.Dispose(); } } public int GetDelayTimeFromCRI() { int result = 0; if (_criInitializeCount >= 3) { return result; } return _criDelayTime / 10; } public CriAtomSource GetBgmSource(int bgmId) { return _bgm[bgmId]; } public int GetBgmMaxCount() { return _bgmSourceCount; } public void VolumeUpdate_Bgm(int level, bool mute, int bgmId = -1) { if (bgmId < 0) { int num = _bgm.Length; for (int i = 0; i < num; i++) { Volume_Bgm((float)level * 0.1f, mute, i); } } else { Volume_Bgm((float)level * 0.1f, mute, bgmId); } } public void Volume_Bgm(float level, bool mute, int bgmId = -1) { if (mute) { level = 0f; } if (bgmId < 0) { int num = _bgm.Length; for (int i = 0; i < num; i++) { _bgm[i].volume = level; _bgm[i].player.Update(_bgmPlayback); } } else { _bgm[bgmId].volume = level; _bgm[bgmId].player.Update(_bgmPlayback); } } public bool IsPlayBgm(int bgmId = 0) { if (_bgm[bgmId].status == CriAtomSource.Status.Prep || _bgm[bgmId].status == CriAtomSource.Status.Playing) { return true; } return false; } public int PlayBgmFromName(string cueSheet, string cueName, string acbName, string awbName = "", int bgmId = 0, bool loop = true, float FadeInfime = 0f, float OffsetTime = 0f, long startTime = 0L) { if (_bgmName == cueName) { return -1; } string acbFile = ""; string awbname = ""; if (acbName.CompareTo("") != 0) { acbFile = acbName + ".acb"; } if (awbName.CompareTo("") != 0) { awbname = awbName + ".awb"; } if (AddCueSheet(cueSheet, acbFile, "b/", awbname)) { StopBgm(bgmId); _bgm[bgmId].cueSheet = cueSheet; _bgm[bgmId].cueName = cueName; _bgm[bgmId].player.ResetFaderParameters(); _bgm[bgmId].player.SetStartTime(startTime); _bgm[bgmId].player.SetFadeInTime((int)(FadeInfime * 1000f)); _bgm[bgmId].player.SetFadeInStartOffset((int)(OffsetTime * 1000f)); _bgm[bgmId].loop = loop; _bgmPlayback = _bgm[bgmId].Play(); _bgmName = cueName; return 0; } return -1; } public int PlayBgmFromId(string cueSheet, int cueId, int bgmId = 0, bool loop = true, float FadeInfime = 0f, float OffsetTime = 0f, long startTime = 0L) { if (_bgmCue == cueSheet && cueId == _cueId) { return -1; } if (CriAtom.GetCueSheet(cueSheet) != null) { StopBgm(bgmId); _bgm[bgmId].cueSheet = cueSheet; _bgm[bgmId].player.ResetFaderParameters(); _bgm[bgmId].player.SetStartTime(startTime); _bgm[bgmId].player.SetFadeInTime((int)(FadeInfime * 1000f)); _bgm[bgmId].player.SetFadeInStartOffset((int)(OffsetTime * 1000f)); _bgm[bgmId].loop = loop; _bgmPlayback = _bgm[bgmId].Play(cueId); _cueId = cueId; _bgmCue = ""; return 1; } return 0; } public void StopBgm(int bgmId = 0) { _bgmName = ""; _bgm[bgmId].Stop(); } public void PauseBgm(bool isPause, int bgmId = 0) { _bgm[bgmId].Pause(isPause); } public void StopFadeBgm(int bgmId = 0, float time = 0.5f) { _bgm[bgmId].player.SetFadeOutTime((int)(time * 1000f)); StopBgm(bgmId); } public void SetBgmVolume(float volume) { GameMgr.GetIns().GetSoundMgr().SetBgmVolume(volume); } public void StartCoroutine_DelayMethod(float waitTime, Action process) { StartCoroutine(Timer.DelayMethod(waitTime, process)); } public void VolumeUpdate_Se(int level, bool mute) { Volume_Se((float)level * 0.1f, mute); } public void Volume_Se(float level, bool mute) { if (mute) { level = 0f; } for (int i = 0; i < _seSourceCount; i++) { _se[i].volume = level; } } public int PlaySeFromId(ref SoundData seData, bool loop = false) { int index = -1; CriAtomSource criAtomSource = FindSe(ref seData, out index); if (criAtomSource != null) { criAtomSource.cueSheet = seData._acbName; criAtomSource.loop = loop; CriAtomExPlayer player = criAtomSource.player; player.ResetFaderParameters(); player.SetFadeOutTime(0); criAtomSource.Play(seData._cueName); return index; } return index; } public int PlaySeFromId(string cueName, int cueId, bool loop = false) { if (!IsAvailableCueSheet(cueName)) { return -1; } for (int i = 0; i < _seSourceCount; i++) { if (_se[i].status == CriAtomSource.Status.PlayEnd) { _se[i].Stop(); } if (_se[i].status == CriAtomSource.Status.Stop) { _se[i].cueSheet = cueName; _se[i].loop = loop; _se[i].Play(cueId); return i; } } return -1; } private CriAtomSource FindSe(ref SoundData seData, out int index) { index = -1; if (_noSeMode) { return null; } if (!IsAvailableCueSheet(seData._acbName)) { Debug.LogError($"No Include Acb!!!:{seData._acbName},{seData._cueName}"); return null; } for (int i = 0; i < _seSourceCount; i++) { if (_se[i].status == CriAtomSource.Status.PlayEnd) { _se[i].Stop(); } if (_se[i].status == CriAtomSource.Status.Stop) { index = i; return _se[i]; } } return null; } public int PlaySe(string cueName, int cueId, bool loop = false) { if (!IsAvailableCueSheet(cueName)) { return -1; } for (int i = 0; i < _seSourceCount; i++) { if (_se[i].status == CriAtomSource.Status.PlayEnd) { _se[i].Stop(); } if (_se[i].status == CriAtomSource.Status.Stop) { _se[i].cueSheet = cueName; _se[i].loop = loop; _se[i].Play(cueId); return i; } } return -1; } public void StopSe(int index, float fadeout = 500f) { if (index >= 0 && index < _seSourceCount) { ResumeSe(index); _se[index].player.SetFadeOutTime((int)(fadeout * 1000f)); _se[index].Stop(); } } public void StopSe(string cuename, float fadeout = 500f) { for (int i = 0; i < _se.Length; i++) { if (_se[i].cueName.CompareTo(cuename) == 0) { ResumeSe(i); _se[i].player.SetFadeOutTime((int)(fadeout * 1000f)); _se[i].Stop(); } } } public void StopSeAll(float fadeout = 500f) { for (int i = 0; i < _seSourceCount; i++) { StopSe(i, fadeout); } } public void PauseSe(int index) { if (index >= 0 && index < _seSourceCount && (_se[index].status == CriAtomSource.Status.Playing || _se[index].status == CriAtomSource.Status.Prep)) { _se[index].Pause(sw: true); } } public void ResumeSe(int index) { if (index >= 0 && index < _seSourceCount && _se[index].status == CriAtomSource.Status.Playing) { _se[index].Pause(sw: false); } } public bool IsPlaySe(string cueName, int cueId) { for (int i = 0; i < _seSourceCount; i++) { if (_playingSe[i]._cueName == cueName && _playingSe[i]._cueId == cueId && (_se[i].status == CriAtomSource.Status.Prep || _se[i].status == CriAtomSource.Status.Playing)) { return true; } } return false; } public bool IsPlaySe(string cueSheetName, string cueName, out int number) { number = 0; for (int i = 0; i < _seSourceCount; i++) { if (_playingSe[i]._acbName == cueSheetName && _playingSe[i]._cueName == cueName && _se[i].status == CriAtomSource.Status.Playing) { number++; } } if (number > 0) { return true; } return false; } public bool IsPrepSe(string cueSheetName, string cueName, out int number) { number = 0; for (int i = 0; i < _seSourceCount; i++) { if (_playingSe[i]._acbName == cueSheetName && _playingSe[i]._cueName == cueName && _se[i].status == CriAtomSource.Status.Prep) { number++; } } if (number > 0) { return true; } return false; } public void ResetSe() { for (int i = 0; i < _seSourceCount; i++) { _se[i].Stop(); _se[i].Pause(sw: false); } } public bool IsPlaySe(int index) { if (_se[index].status == CriAtomSource.Status.Prep || _se[index].status == CriAtomSource.Status.Playing) { return true; } return false; } public void SetAisac(string cuename, string param, float num) { for (int i = 0; i < _se.Length; i++) { if (_se[i].cueName.CompareTo(cuename) == 0) { _se[i].SetAisacControl(param, num); } } } public int PlaySeFromName(string acbName, string seName, bool loop = false, float fadeInfime = 0f, long startTime = 0L) { if (!IsAvailableCueSheet(acbName)) { return -1; } for (int i = 0; i < _seSourceCount; i++) { if (_se[i].status == CriAtomSource.Status.PlayEnd) { _se[i].Stop(); } if (_se[i].status == CriAtomSource.Status.Stop) { _se[i].cueSheet = acbName; _se[i].cueName = seName; _se[i].loop = loop; _se[i].player.ResetFaderParameters(); _se[i].player.SetStartTime(startTime); _se[i].player.SetFadeInTime((int)(fadeInfime * 1000f)); _se[i].Play(seName); return i; } } return -1; } public int GetVoiceSourceCount() { return _voiceSourceCount; } public void VolumeUpdate_Voice(int level, bool mute, int voiceId = -1) { Volume_Voice((float)level * 0.1f, mute, voiceId); } public void Volume_Voice(float level, bool mute, int voiceId = -1) { if (mute) { level = 0f; } if (voiceId < 0) { int num = _voice.Length; for (int i = 0; i < num; i++) { _voice[i].volume = level; } } else { _voice[voiceId].volume = level; } } public bool IsPlayVoice(int index) { if (_voice[index].status == CriAtomSource.Status.Prep || _voice[index].status == CriAtomSource.Status.Playing) { return true; } return false; } public void PlayVoice(int voiceId, string acbFile, string cueSheet, string cueName) { AddCueSheet(cueSheet, acbFile, "v/"); _voice[voiceId].Play(cueName); } public void PlayVoice(int voiceId, string cueName) { _voice[voiceId].Play(cueName); } public void StopVoice(int voiceId, float fadetout = 500f) { CriAtomSource criAtomSource = _voice[voiceId]; if (criAtomSource != null && criAtomSource.player != null) { criAtomSource.player.SetFadeOutTime((int)(fadetout * 1000f)); criAtomSource.Stop(); } } }