using GFramework.Core.system;
using GFramework.Game.assets;
using GFramework.Godot.assets;
using Godot;
namespace GFramework.Godot.system;
///
/// 音频管理器抽象基类,提供音频播放的基础实现
///
public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManagerSystem
{
///
/// 最大同时播放的音效数量
///
protected const int MaxSoundPlayers = 10;
///
/// 最大同时播放的3D音效数量
///
protected const int MaxSound3DPlayers = 5;
///
/// 可用3D音效播放器队列
///
protected readonly Queue AvailableSound3DPlayers = new();
///
/// 可用音效播放器队列
///
protected readonly Queue AvailableSoundPlayers = new();
///
/// 3D音效播放器列表
///
protected readonly List Sound3DPlayers = [];
///
/// 音效播放器列表
///
protected readonly List SoundPlayers = [];
///
/// 环境音量
///
protected float AmbientVolume = 1.0f;
///
/// 资源目录系统依赖
///
protected IAssetCatalogSystem? AssetCatalogSystem;
///
/// 主音量
///
protected float MasterVolume = 1.0f;
///
/// 音乐淡入淡出动画
///
protected Tween? MusicFadeTween;
///
/// 背景音乐播放器
///
protected AudioStreamPlayer? MusicPlayer;
///
/// 背景音乐音量
///
protected float MusicVolume = 1.0f;
///
/// 资源工厂系统依赖
///
protected IResourceFactorySystem? ResourceFactorySystem;
///
/// 音频资源加载系统依赖
///
protected IResourceLoadSystem? ResourceLoadSystem;
///
/// 特效音量
///
protected float SfxVolume = 1.0f;
///
/// 音效音量
///
protected float SoundVolume = 1.0f;
///
/// 语音音量
///
protected float VoiceVolume = 1.0f;
///
/// 所有者节点的抽象属性
///
protected abstract Node Owner { get; }
///
/// 播放背景音乐
///
/// 音频文件路径
/// 音量大小,范围0-1
/// 是否循环播放
public virtual void PlayMusic(string audioPath, float volume = 1.0f, bool loop = true)
{
var audioStream = ResourceLoadSystem?.LoadResource(audioPath);
if (audioStream == null || MusicPlayer == null) return;
// 停止当前正在进行的淡入淡出效果
MusicFadeTween?.Kill();
MusicPlayer.Stream = audioStream;
MusicPlayer.VolumeDb = LinearToDb(volume * MusicVolume * MasterVolume);
MusicPlayer.Play();
}
///
/// 播放音效
///
/// 音频文件路径
/// 音量大小,范围0-1
/// 音调调整
public virtual void PlaySound(string audioPath, float volume = 1.0f, float pitch = 1.0f)
{
if (AvailableSoundPlayers.Count == 0) return;
var audioStream = ResourceLoadSystem?.LoadResource(audioPath);
if (audioStream == null) return;
var player = AvailableSoundPlayers.Dequeue();
player.Stream = audioStream;
player.VolumeDb = LinearToDb(volume * SoundVolume * MasterVolume);
player.Play();
}
///
/// 播放特效音效
///
/// 音频文件路径
/// 音量大小,范围0-1
/// 音调调整
public virtual void PlaySfx(string audioPath, float volume = 1.0f, float pitch = 1.0f)
{
if (AvailableSoundPlayers.Count == 0) return;
var audioStream = ResourceLoadSystem?.LoadResource(audioPath);
if (audioStream == null) return;
var player = AvailableSoundPlayers.Dequeue();
player.Stream = audioStream;
player.VolumeDb = LinearToDb(volume * SfxVolume * MasterVolume);
player.Play();
}
///
/// 播放语音
///
/// 音频文件路径
/// 音量大小,范围0-1
/// 音调调整
public virtual void PlayVoice(string audioPath, float volume = 1.0f, float pitch = 1.0f)
{
if (AvailableSoundPlayers.Count == 0) return;
var audioStream = ResourceLoadSystem?.LoadResource(audioPath);
if (audioStream == null) return;
var player = AvailableSoundPlayers.Dequeue();
player.Stream = audioStream;
player.VolumeDb = LinearToDb(volume * VoiceVolume * MasterVolume);
player.Play();
}
///
/// 播放环境音效
///
/// 音频文件路径
/// 音量大小,范围0-1
/// 音调调整
public virtual void PlayAmbient(string audioPath, float volume = 1.0f, float pitch = 1.0f)
{
if (AvailableSoundPlayers.Count == 0) return;
var audioStream = ResourceLoadSystem?.LoadResource(audioPath);
if (audioStream == null) return;
var player = AvailableSoundPlayers.Dequeue();
player.Stream = audioStream;
player.VolumeDb = LinearToDb(volume * AmbientVolume * MasterVolume);
player.Play();
}
///
/// 播放3D音效
///
/// 音频文件路径
/// 3D空间中的位置
/// 音量大小,范围0-1
public virtual void PlaySound3D(string audioPath, Vector3 position, float volume = 1.0f)
{
if (AvailableSound3DPlayers.Count == 0) return;
var audioStream = ResourceLoadSystem?.LoadResource(audioPath);
if (audioStream == null) return;
var player = AvailableSound3DPlayers.Dequeue();
player.Stream = audioStream;
player.VolumeDb = LinearToDb(volume * SoundVolume * MasterVolume);
player.Position = position;
player.Play();
}
///
/// 停止背景音乐
///
public virtual void StopMusic()
{
MusicFadeTween?.Kill();
MusicPlayer?.Stop();
}
///
/// 暂停背景音乐
///
public virtual void PauseMusic()
{
MusicFadeTween?.Kill();
// todo 需要记录音乐播放位置,以便恢复播放时从正确位置开始
}
///
/// 恢复背景音乐播放
///
public virtual void ResumeMusic()
{
MusicPlayer?.Play();
}
///
/// 设置背景音乐音量
///
/// 音量大小,范围0-1
public virtual void SetMusicVolume(float volume)
{
MusicVolume = volume;
if (MusicPlayer != null) MusicPlayer.VolumeDb = LinearToDb(MusicVolume * MasterVolume);
}
///
/// 获取背景音乐音量
///
/// 音量大小,范围0-1
public virtual float GetMusicVolume()
{
return MusicVolume;
}
///
/// 设置音效音量
///
/// 音量大小,范围0-1
public virtual void SetSoundVolume(float volume)
{
SoundVolume = volume;
}
///
/// 获取音效音量
///
/// 音量大小,范围0-1
public virtual float GetSoundVolume()
{
return SoundVolume;
}
///
/// 设置主音量
///
/// 音量大小,范围0-1
public virtual void SetMasterVolume(float volume)
{
MasterVolume = volume;
// 更新音乐音量
if (MusicPlayer != null) MusicPlayer.VolumeDb = LinearToDb(MusicVolume * MasterVolume);
}
///
/// 获取主音量
///
/// 音量大小,范围0-1
public virtual float GetMasterVolume()
{
return MasterVolume;
}
///
/// 设置SFX音量
///
/// 音量大小,范围0-1
public virtual void SetSfxVolume(float volume)
{
SfxVolume = volume;
}
///
/// 获取SFX音量
///
/// 音量大小,范围0-1
public virtual float GetSfxVolume()
{
return SfxVolume;
}
///
/// 设置语音音量
///
/// 音量大小,范围0-1
public virtual void SetVoiceVolume(float volume)
{
VoiceVolume = volume;
}
///
/// 获取语音音量
///
/// 音量大小,范围0-1
public virtual float GetVoiceVolume()
{
return VoiceVolume;
}
///
/// 设置环境音量
///
/// 音量大小,范围0-1
public virtual void SetAmbientVolume(float volume)
{
AmbientVolume = volume;
}
///
/// 获取环境音量
///
/// 音量大小,范围0-1
public virtual float GetAmbientVolume()
{
return AmbientVolume;
}
///
/// 检查背景音乐是否正在播放
///
/// 正在播放返回true,否则返回false
public virtual bool IsMusicPlaying()
{
return MusicPlayer?.Playing ?? false;
}
///
/// 淡入背景音乐
///
/// 音频文件路径
/// 淡入持续时间(秒)
/// 目标音量
public virtual void FadeInMusic(string audioPath, float duration, float volume = 1.0f)
{
var audioStream = ResourceLoadSystem?.LoadResource(audioPath);
if (audioStream == null || MusicPlayer == null) return;
// 停止当前正在进行的淡入淡出效果
MusicFadeTween?.Kill();
MusicPlayer.Stream = audioStream;
MusicPlayer.VolumeDb = LinearToDb(0.0f); // 初始音量为0
MusicPlayer.Play();
// 创建淡入动画
MusicFadeTween = Owner.CreateTween();
MusicFadeTween.TweenProperty(MusicPlayer, "volume_db", LinearToDb(volume * MusicVolume * MasterVolume),
duration);
}
///
/// 淡出背景音乐
///
/// 淡出持续时间(秒)
public virtual void FadeOutMusic(float duration)
{
if (MusicPlayer == null) return;
// 停止当前正在进行的淡入淡出效果
MusicFadeTween?.Kill();
// 创建淡出动画
MusicFadeTween = Owner.CreateTween();
MusicFadeTween.TweenProperty(MusicPlayer, "volume_db", LinearToDb(0.0f), duration);
MusicFadeTween.TweenCallback(Callable.From(() => MusicPlayer.Stop()));
}
///
/// 设置低通滤波器强度
///
/// 滤波器强度,范围0-1
public virtual void SetLowPassFilter(float amount)
{
// TODO: 实现低通滤波器效果
// 可以通过AudioEffectLowPassFilter实现
}
///
/// 设置音频混响效果
///
/// 房间大小
/// 阻尼
/// 湿声级别
public virtual void SetReverb(float roomSize, float damping, float wetLevel)
{
// TODO: 实现音频混响效果
// 可以通过AudioEffectReverb实现
}
///
/// 系统初始化方法
///
protected override void OnInit()
{
// 获取依赖的系统
ResourceLoadSystem = Context.GetSystem();
AssetCatalogSystem = Context.GetSystem();
ResourceFactorySystem = Context.GetSystem();
// 初始化背景音乐播放器
MusicPlayer = new AudioStreamPlayer();
Owner.AddChild(MusicPlayer);
// 预创建音效播放器池
for (var i = 0; i < MaxSoundPlayers; i++)
{
var soundPlayer = new AudioStreamPlayer();
Owner.AddChild(soundPlayer);
soundPlayer.Finished += () => OnSoundFinished(soundPlayer);
SoundPlayers.Add(soundPlayer);
AvailableSoundPlayers.Enqueue(soundPlayer);
}
// 预创建3D音效播放器池
for (var i = 0; i < MaxSound3DPlayers; i++)
{
var sound3DPlayer = new AudioStreamPlayer3D();
Owner.AddChild(sound3DPlayer);
sound3DPlayer.Finished += () => OnSound3DFinished(sound3DPlayer);
Sound3DPlayers.Add(sound3DPlayer);
AvailableSound3DPlayers.Enqueue(sound3DPlayer);
}
}
///
/// 当音效播放完成时的回调
///
/// 完成播放的音频播放器
private void OnSoundFinished(AudioStreamPlayer player)
{
// 将播放器放回可用队列
AvailableSoundPlayers.Enqueue(player);
}
///
/// 当3D音效播放完成时的回调
///
/// 完成播放的3D音频播放器
private void OnSound3DFinished(AudioStreamPlayer3D player)
{
// 将播放器放回可用队列
AvailableSound3DPlayers.Enqueue(player);
}
///
/// 通过资源ID播放背景音乐
///
/// 音乐资源ID
/// 音量大小,范围0-1
/// 是否循环播放
public virtual void PlayMusic(AssetCatalog.AssetId musicId, float volume = 1.0f, bool loop = true)
{
PlayMusic(musicId.Path, volume, loop);
}
///
/// 通过资源ID播放音效
///
/// 音效资源ID
/// 音量大小,范围0-1
/// 音调调整
public virtual void PlaySound(AssetCatalog.AssetId soundId, float volume = 1.0f, float pitch = 1.0f)
{
PlaySound(soundId.Path, volume, pitch);
}
///
/// 将线性音量值转换为分贝值
///
/// 线性音量值(0-1)
/// 分贝值
protected static float LinearToDb(float linear)
{
return linear > 0 ? 20 * Mathf.Log(linear) : -100;
}
///
/// 将分贝值转换为线性音量值
///
/// 分贝值
/// 线性音量值(0-1)
protected static float DbToLinear(float db)
{
return db > -100 ? Mathf.Exp(db / 20) : 0;
}
///
/// 系统销毁时清理资源
///
protected override void OnDestroy()
{
// 停止并清理淡入淡出动画
MusicFadeTween?.Kill();
// 清理音乐播放器
MusicPlayer?.QueueFree();
// 清理音效播放器池
foreach (var player in SoundPlayers) player.QueueFree();
// 清理3D音效播放器池
foreach (var player in Sound3DPlayers) player.QueueFree();
SoundPlayers.Clear();
AvailableSoundPlayers.Clear();
Sound3DPlayers.Clear();
AvailableSound3DPlayers.Clear();
}
}