- Add XCEngine音频模块架构设计.md - Design audio system following Unity-style architecture - Include AudioSourceComponent, AudioListenerComponent, AudioClip, AudioMixer - Document DSP effect system (FFT, Reverb, EQ, Compressor) - Document 3D spatial audio with HRTF support - Define IAudioBackend abstraction layer with WASAPI/OpenAL backends - Outline 5-phase implementation priorities
47 KiB
47 KiB
XCEngine - 音频模块架构设计文档
借鉴 Unity 音频架构概念设计
音频流程图
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ 音频流程 │
└─────────────────────────────────────────────────────────────────────────────────────┘
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ AudioSource │────▶│ Spatialize │────▶│ EffectChain │────▶│ Output │
│ 声源组件 │ │ 3D空间化 │ │ 效果链 │ │ 音频输出 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ AudioClip │ │ HRTF │ │ FFT │ │ AudioBackend│
│ 音频资源 │ │ 头部相关传输 │ │ 傅里叶变换 │ │ 音频后端 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Reverbation │ │ WASAPI │
│ 混响效果 │ │ OpenAL │
└─────────────┘ │ CoreAudio │
└─────────────┘
流程说明:
1. AudioSourceComponent 负责播放 AudioClip,管理播放状态
2. AudioListenerComponent 接收声音,计算3D空间化参数
3. Spatialize 根据 Listener 位置计算 panning、distance attenuation、doppler
4. EffectChain 处理 DSP 效果链(FFT、Reverb、EQ等)
5. AudioBackend 抽象层负责与具体音频API交互
6. 最终输出到音频设备
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ AudioBackend 抽象层架构 │
└─────────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ AudioSystem │ 音频系统入口
└────────┬────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ WASAPIBackend│ │OpenALBackend │ │CoreAudioBackend│
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────────────┼───────────────────────┘
│
┌────────▼────────┐
│ IAudioBackend │ 抽象音频后端接口
└────────┬────────┘
│
┌──────────────────────────────────┼──────────────────────────────────┐
│ │ │ │ │ │ │
┌────▼────┐ ┌───▼────┐ ┌────▼┐ ┌──▼────┐ ┌───▼───┐ ┌───▼────┐ ┌──▼────┐
│AudioBuffer│ │AudioBus │ │Fence│ │Mixer │ │Effect │ │HRTF │ │Resampler│
│ 音频缓冲 │ │ 音频总线 │ │围栏 │ │ 混音器 │ │ 效果 │ │ 空间化 │ │ 重采样 │
└──────────┘ └────────┘ └─────┘ └────────┘ └───────┘ └────────┘ └────────┘
重要声明:本架构借鉴 Unity 音频系统的核心概念与设计模式,包括:
AudioSourceComponent/AudioListenerComponent- 声源与监听器组件AudioClip/AudioMixer- 音频资源与混音器EffectChain- 效果器链Spatializer- 3D空间化处理器AudioBackend- 音频后端抽象注:Unity底层C++音频架构未公开,本设计基于公开API概念与通用音频引擎模式实现。
版本: 1.0 日期: 2026-03-20 目标: 构建专业级游戏引擎音频系统
第一章 核心类型定义
1.1 音频基础类型
namespace XCEngine {
namespace Audio {
// ============================================
// 前置类型定义
// ============================================
enum class AudioResourceType {
AudioClip,
AudioMixer,
AudioBank
};
enum class AudioLoadState {
Unloaded,
Loading,
Loaded,
Failed
};
enum class AudioFormat {
Unknown,
WAV,
OGG,
MP3,
FLAC,
AAC
};
enum class SpeakerMode {
Mono,
Stereo,
Surround51,
Surround71,
Surround51_2,
Surround71_2
};
enum class AudioChannel {
FrontLeft,
FrontRight,
FrontCenter,
LFE,
BackLeft,
BackRight,
SideLeft,
SideRight
};
struct AudioConfig {
uint32_t sampleRate = 48000;
uint16_t channels = 2;
uint16_t bitsPerSample = 16;
SpeakerMode speakerMode = SpeakerMode::Stereo;
uint32_t bufferSize = 8192;
uint32_t bufferCount = 2;
};
// ============================================
// 3D 音频参数
// ============================================
struct Audio3DParams {
float dopplerLevel = 1.0f;
float speedOfSound = 343.0f;
float minDistance = 1.0f;
float maxDistance = 500.0f;
float panLevel = 1.0f;
float spread = 0.0f;
float reverbZoneMix = 1.0f;
};
enum class PanMode {
Pan3D,
Pan2D
};
enum class VolumeSource {
Direct,
Path Occlusion,
Transmission,
Obstruction
};
// ============================================
// 音频缓冲区描述
// ============================================
struct AudioBufferDesc {
uint32_t size = 0;
uint32_t channels = 2;
uint32_t sampleRate = 48000;
uint16_t bitsPerSample = 16;
bool isFloat = false;
bool isCompressed = false;
AudioFormat format = AudioFormat::Unknown;
};
// ============================================
// 播放状态
// ============================================
enum class PlayState {
Stopped,
Playing,
Paused
};
enum class StopMode {
Immediate,
AllowFadeOut
};
// ============================================
// 空间化参数
// ============================================
struct SpatializerParams {
float azimuth = 0.0f;
float elevation = 0.0f;
float distance = 0.0f;
float volumeDb = 0.0f;
float panCartesianX = 0.0f;
float panCartesianY = 0.0f;
bool isOccluded = false;
bool isObstructed = false;
};
} // namespace Audio
} // namespace XCEngine
1.2 IAudioResource 基类
namespace XCEngine {
namespace Audio {
class IAudioResource {
public:
virtual ~IAudioResource() = default;
virtual void SetName(const String& name) { m_name = name; }
virtual const String& GetName() const { return m_name; }
virtual AudioResourceType GetType() const = 0;
virtual AudioLoadState GetLoadState() const { return m_loadState; }
virtual bool IsValid() const { return m_loadState == AudioLoadState::Loaded; }
virtual void Load() = 0;
virtual void Unload() = 0;
virtual int GetRefCount() const { return m_refCount.load(); }
virtual void AddRef() { m_refCount.fetch_add(1); }
virtual void Release() {
if (m_refCount.fetch_sub(1) == 1) {
delete this;
}
}
protected:
IAudioResource() : m_loadState(AudioLoadState::Unloaded), m_memoryUsage(0) {}
String m_name;
AudioLoadState m_loadState;
uint64_t m_memoryUsage;
std::atomic<int32_t> m_refCount{1};
};
} // namespace Audio
} // namespace XCEngine
第二章 音频资源
2.1 AudioClip
namespace XCEngine {
namespace Audio {
class AudioClip : public IAudioResource {
public:
AudioClip();
AudioClip(const String& filePath);
~AudioClip();
AudioResourceType GetType() const override { return AudioResourceType::AudioClip; }
void Load() override;
void Unload() override;
// 音频数据访问
const int16_t* GetData() const { return m_data.data(); }
int16_t* GetData() { return m_data.data(); }
const float* GetDataFloat() const { return m_dataFloat.data(); }
float* GetDataFloat() { return m_dataFloat.data(); }
uint32_t GetDataSize() const { return m_dataSize; }
uint32_t GetSampleCount() const { return m_sampleCount; }
uint32_t GetChannelCount() const { return m_channels; }
uint32_t GetSampleRate() const { return m_sampleRate; }
uint16_t GetBitsPerSample() const { return m_bitsPerSample; }
float GetDuration() const { return m_duration; }
AudioFormat GetFormat() const { return m_format; }
bool IsCompressed() const { return m_isCompressed; }
bool IsStreamed() const { return m_isStreamed; }
// 频谱数据查询
bool HasFrequencyData() const { return m_hasFrequencyData; }
const float* GetFrequencyData() const { return m_frequencyData.data(); }
uint32_t GetFrequencyDataSize() const { return m_frequencyData.size(); }
// 资源路径
void SetResourcePath(const String& path) { m_resourcePath = path; }
const String& GetResourcePath() const { return m_resourcePath; }
private:
void ProcessWavFile();
void DecodeCompressedData();
void GenerateFrequencyData();
void ConvertToFloat();
private:
std::vector<int16_t> m_data;
std::vector<float> m_dataFloat;
std::vector<float> m_frequencyData;
uint32_t m_dataSize = 0;
uint32_t m_sampleCount = 0;
uint16_t m_channels = 2;
uint32_t m_sampleRate = 48000;
uint16_t m_bitsPerSample = 16;
float m_duration = 0.0f;
AudioFormat m_format = AudioFormat::Unknown;
bool m_isCompressed = false;
bool m_isStreamed = false;
bool m_hasFrequencyData = false;
String m_resourcePath;
};
} // namespace Audio
} // namespace XCEngine
2.2 AudioMixer
namespace XCEngine {
namespace Audio {
class AudioMixer : public IAudioResource {
public:
AudioMixer();
~AudioMixer();
AudioResourceType GetType() const override { return AudioResourceType::AudioMixer; }
void Load() override;
void Unload() override;
// 混音器参数
float GetVolume() const { return m_volume; }
void SetVolume(float volume, float fadeTime = 0.0f);
bool IsMuted() const { return m_isMuted; }
void SetMuted(bool muted) { m_isMuted = muted; }
// 子混音器组
class MixerGroup* GetGroup(const String& name);
class MixerGroup* CreateGroup(const String& name);
void RemoveGroup(const String& name);
const std::map<String, std::unique_ptr<MixerGroup>>& GetGroups() const { return m_groups; }
// 输出混音器
void SetOutputMixer(AudioMixer* mixer);
AudioMixer* GetOutputMixer() const { return m_outputMixer; }
private:
float m_volume = 1.0f;
bool m_isMuted = false;
std::map<String, std::unique_ptr<MixerGroup>> m_groups;
AudioMixer* m_outputMixer = nullptr;
};
class MixerGroup {
public:
MixerGroup(const String& name);
~MixerGroup();
const String& GetName() const { return m_name; }
float GetVolume() const { return m_volume; }
void SetVolume(float volume, float fadeTime = 0.0f);
bool IsMuted() const { return m_isMuted; }
void SetMuted(bool muted) { m_isMuted = muted; }
bool IsSoloed() const { return m_isSoloed; }
void SetSoloed(bool soloed) { m_isSoloed = soloed; }
// 效果器
void AddEffect(IAudioEffect* effect, size_t index = SIZE_MAX);
void RemoveEffect(IAudioEffect* effect);
void SetEffectEnabled(IAudioEffect* effect, bool enabled);
const std::vector<IAudioEffect*>& GetEffects() const { return m_effects; }
// 音频处理
void Process(float* buffer, uint32_t sampleCount, uint32_t channels);
private:
String m_name;
float m_volume = 1.0f;
bool m_isMuted = false;
bool m_isSoloed = false;
std::vector<IAudioEffect*> m_effects;
};
} // namespace Audio
} // namespace XCEngine
2.3 AudioBank (用于分段加载)
namespace XCEngine {
namespace Audio {
class AudioBank : public IAudioResource {
public:
AudioBank();
~AudioBank();
AudioResourceType GetType() const override { return AudioResourceType::AudioBank; }
void Load() override;
void Unload() override;
// 事件触发
void TriggerEvent(const String& eventName);
void TriggerEvent(int eventId);
// 获取嵌入的音频片段
AudioClip* GetClip(const String& name);
AudioClip* GetClip(int id);
const std::map<String, AudioClip*>& GetAllClips() const { return m_clips; }
private:
std::map<String, AudioClip*> m_clips;
std::map<String, int> m_eventMap;
};
} // namespace Audio
} // namespace XCEngine
第三章 DSP 效果系统
3.1 IAudioEffect 接口
namespace XCEngine {
namespace Audio {
class IAudioEffect {
public:
virtual ~IAudioEffect() = default;
virtual const char* GetName() const = 0;
virtual void Process(float* buffer, uint32_t sampleCount, uint32_t channels) = 0;
virtual void SetEnabled(bool enabled) { m_enabled = enabled; }
virtual bool IsEnabled() const { return m_enabled; }
virtual void SetParameter(const char* name, float value) = 0;
virtual float GetParameter(const char* name) const = 0;
virtual size_t GetParameterCount() const = 0;
virtual const char* GetParameterName(size_t index) const = 0;
protected:
bool m_enabled = true;
};
} // namespace Audio
} // namespace XCEngine
3.2 FFTFilter (频谱分析)
namespace XCEngine {
namespace Audio {
class FFTFilter : public IAudioEffect {
public:
FFTFilter(size_t fftSize = 1024);
~FFTFilter();
const char* GetName() const override { return "FFTFilter"; }
void Process(float* buffer, uint32_t sampleCount, uint32_t channels) override;
void SetEnabled(bool enabled) override;
void SetFFTSize(size_t size);
size_t GetFFTSize() const { return m_fftSize; }
void SetParameter(const char* name, float value) override;
float GetParameter(const char* name) const override;
size_t GetParameterCount() const override;
const char* GetParameterName(size_t index) const override;
// 频谱数据访问
const float* GetMagnitudeSpectrum() const { return m_magnitudeSpectrum.data(); }
const float* GetPhaseSpectrum() const { return m_phaseSpectrum.data(); }
size_t GetSpectrumSize() const { return m_spectrumSize; }
// 设置时域核(用于滤波)
void SetTimeDomainKernel(const std::vector<float>& kernel);
void AddTimeDomainKernel(const std::vector<float>& kernel);
// 频域核
void SetFreqDomainKernel(const std::vector<float>& kernel);
void AddFreqDomainKernel(const std::vector<float>& kernel);
private:
void Init();
void ComplexVectorProduct(const std::vector<kiss_fft_cpx>& inputA,
const std::vector<kiss_fft_cpx>& inputB,
std::vector<kiss_fft_cpx>* result);
void InverseFFTScaling(std::vector<float>* signal);
private:
size_t m_fftSize;
size_t m_spectrumSize;
bool m_analysisMode = true;
std::vector<float> m_magnitudeSpectrum;
std::vector<float> m_phaseSpectrum;
std::vector<float> m_filterState;
std::vector<float> m_window;
bool m_kernelDefined = false;
std::vector<kiss_fft_scalar> m_kernelTimeDomainBuffer;
std::vector<kiss_fft_cpx> m_kernelFreqDomainBuffer;
int m_bufferSelector = 0;
std::vector<std::vector<kiss_fft_scalar>> m_signalTimeDomainBuffer;
std::vector<std::vector<kiss_fft_cpx>> m_signalFreqDomainBuffer;
std::vector<kiss_fft_cpx> m_filteredFreqDomainBuffer;
kiss_fftr_cfg m_forwardFFT = nullptr;
kiss_fftr_cfg m_inverseFFT = nullptr;
};
} // namespace Audio
} // namespace XCEngine
3.3 Reverbation (混响)
namespace XCEngine {
namespace Audio {
class Reverbation : public IAudioEffect {
public:
Reverbation(int blockSize = 1024, int samplingRate = 48000, float reverbTime = 2.0f);
~Reverbation();
const char* GetName() const override { return "Reverbation"; }
void Process(float* buffer, uint32_t sampleCount, uint32_t channels) override;
void SetParameter(const char* name, float value) override;
float GetParameter(const char* name) const override;
size_t GetParameterCount() const override;
const char* GetParameterName(size_t index) const override;
// 混响参数
void SetReverbTime(float seconds);
float GetReverbTime() const { return m_reverbTime; }
void SetDecay(float decay) { m_decay = decay; }
float GetDecay() const { return m_decay; }
void SetPreDelay(float ms);
float GetPreDelay() const { return m_preDelayMs; }
void SetHighFreqDamping(float ratio);
float GetHighFreqDamping() const { return m_highFreqDamping; }
// 脉冲响应
const std::vector<float>& GetImpulseResponseLeft() const { return m_impulseResponseLeft; }
const std::vector<float>& GetImpulseResponseRight() const { return m_impulseResponseRight; }
float GetQuietPeriod() const { return m_quietPeriodSec; }
private:
void RenderImpulseResponse(int blockSize, int samplingRate, float reverbTime);
static float FloatRand();
private:
int m_blockSize;
float m_reverbTime = 2.0f;
float m_decay = 0.7f;
float m_preDelayMs = 20.0f;
float m_highFreqDamping = 0.5f;
std::vector<float> m_impulseResponseLeft;
std::vector<float> m_impulseResponseRight;
float m_quietPeriodSec;
std::unique_ptr<FFTFilter> m_leftReverbFilter;
std::unique_ptr<FFTFilter> m_rightReverbFilter;
std::vector<float> m_reverbInput;
std::vector<float> m_reverbOutputLeft;
std::vector<float> m_reverbOutputRight;
int m_reverbOutputReadPos = 0;
};
} // namespace Audio
} // namespace XCEngine
3.4 EQ (均衡器)
namespace XCEngine {
namespace Audio {
class Equalizer : public IAudioEffect {
public:
Equalizer();
~Equalizer();
const char* GetName() const override { return "Equalizer"; }
void Process(float* buffer, uint32_t sampleCount, uint32_t channels) override;
void SetParameter(const char* name, float value) override;
float GetParameter(const char* name) const override;
size_t GetParameterCount() const override;
const char* GetParameterName(size_t index) const override;
// 频段控制
enum class Band {
LowPass,
HighPass,
BandPass,
Notch,
LowShelf,
HighShelf,
Peaking
};
void SetBand(size_t index, Band type, float frequency, float gainDb, float Q);
void SetBandEnabled(size_t index, bool enabled);
struct BandParams {
Band type = Band::Peaking;
float frequency = 1000.0f;
float gainDb = 0.0f;
float Q = 1.0f;
bool enabled = true;
};
const BandParams& GetBand(size_t index) const { return m_bands[index]; }
private:
void UpdateCoefficients(size_t index);
void ProcessBand(float* buffer, uint32_t sampleCount, size_t bandIndex);
private:
static constexpr size_t MaxBands = 10;
std::array<BandParams, MaxBands> m_bands;
std::array<std::array<float, 5>, MaxBands> m_coefficients;
std::vector<float> m_x1, m_x2, m_y1, m_y2;
};
} // namespace Audio
} // namespace XCEngine
3.5 Dynamics (动态效果器)
namespace XCEngine {
namespace Audio {
class Compressor : public IAudioEffect {
public:
Compressor();
~Compressor();
const char* GetName() const override { return "Compressor"; }
void Process(float* buffer, uint32_t sampleCount, uint32_t channels) override;
void SetParameter(const char* name, float value) override;
float GetParameter(const char* name) const override;
size_t GetParameterCount() const override;
const char* GetParameterName(size_t index) const override;
void SetThreshold(float db);
float GetThreshold() const { return m_thresholdDb; }
void SetRatio(float ratio);
float GetRatio() const { return m_ratio; }
void SetAttack(float ms);
float GetAttack() const { return m_attackMs; }
void SetRelease(float ms);
float GetRelease() const { return m_releaseMs; }
float GetGainReduction() const { return m_gainReduction; }
private:
float m_thresholdDb = -20.0f;
float m_ratio = 4.0f;
float m_attackMs = 10.0f;
float m_releaseMs = 100.0f;
float m_gainReduction = 0.0f;
float m_envelope = 0.0f;
};
class Limiter : public IAudioEffect {
public:
Limiter();
~Limiter();
const char* GetName() const override { return "Limiter"; }
void Process(float* buffer, uint32_t sampleCount, uint32_t channels) override;
void SetParameter(const char* name, float value) override;
float GetParameter(const char* name) const override;
size_t GetParameterCount() const override;
const char* GetParameterName(size_t index) const override;
void SetCeiling(float db);
float GetCeiling() const { return m_ceilingDb; }
void SetRelease(float ms);
float GetRelease() const { return m_releaseMs; }
private:
float m_ceilingDb = -0.3f;
float m_releaseMs = 50.0f;
float m_envelope = 0.0f;
};
} // namespace Audio
} // namespace XCEngine
第四章 3D 空间音频
4.1 SpatializerParams 空间化参数
namespace XCEngine {
namespace Audio {
struct SpatializerParams {
Vector3 listenerPosition;
Quaternion listenerRotation;
Vector3 listenerVelocity;
Vector3 sourcePosition;
Vector3 sourceVelocity;
Quaternion sourceRotation;
Audio3DParams params;
float GetDistanceAttenuation() const;
float GetPan() const;
float GetDopplerShift() const;
};
4.2 HRTF 空间化
namespace XCEngine {
namespace Audio {
class HRTF {
public:
HRTF();
~HRTF();
// 方向设置
void SetDirection(int elevation, int azimuth);
void GetDirection(int& elevation, int& azimuth);
// HRTF 脉冲响应
void GetLeftEarTimeHRTF(std::vector<float>& data);
void GetLeftEarFreqHRTF(std::vector<float>& data);
void GetRightEarTimeHRTF(std::vector<float>& data);
void GetRightEarFreqHRTF(std::vector<float>& data);
// 空间化处理
void Process(const float* input, float* outputLeft, float* outputRight,
size_t sampleCount, size_t channels);
// 淡入淡出处理
void ApplyFadeWindow(const std::vector<float>& blockLast,
const std::vector<float>& blockNext,
std::vector<float>* fadeResult);
// 重采样
void Resample(const float* input, float* output, size_t inputSize,
size_t outputSize, size_t channels);
private:
void BuildReacherTree();
int SearchNearestIndex(int elevation, int azimuth);
double CalculateSphereDistance(int elev1, int azim1, int elev2, int azim2);
private:
int m_realAzimuth = 0;
int m_realElevation = 0;
int m_azimuth = 0;
int m_elevation = 0;
bool m_isSwapLeftRight = false;
int m_directionIndex = 0;
using ResampledHRTFT = std::vector<float>;
using ResampledHRTFPairT = std::pair<ResampledHRTFT, ResampledHRTFT>;
std::vector<ResampledHRTFPairT> m_hrtfResampledTimeDomain;
std::vector<ResampledHRTFPairT> m_hrtfResampledFreqDomain;
std::map<int, std::pair<std::vector<int>, std::vector<int>>> m_hrtfDirections;
std::unique_ptr<FFTFilter> m_filter;
std::unique_ptr<FFTFilter> m_hrtfFilterLeft;
std::unique_ptr<FFTFilter> m_hrtfFilterRight;
std::vector<float> m_fadeWindow;
};
} // namespace Audio
} // namespace XCEngine
4.3 DopplerEffect 多普勒效应
namespace XCEngine {
namespace Audio {
class DopplerEffect {
public:
DopplerEffect();
~DopplerEffect();
void SetSpeedOfSound(float metersPerSecond);
float GetSpeedOfSound() const { return m_speedOfSound; }
void SetDopplerLevel(float level);
float GetDopplerLevel() const { return m_dopplerLevel; }
float CalculatePitchShift(const Vector3& sourceVelocity,
const Vector3& listenerVelocity,
const Vector3& sourceToListener);
private:
float m_speedOfSound = 343.0f;
float m_dopplerLevel = 1.0f;
};
} // namespace Audio
} // namespace XCEngine
4.4 OcclusionSystem 遮蔽系统
namespace XCEngine {
namespace Audio {
class OcclusionSystem {
public:
OcclusionSystem();
~OcclusionSystem();
// 遮蔽计算
float CalculateOcclusion(const Vector3& sourcePos, const Vector3& listenerPos,
const std::vector<Vector3>& obstaclePositions);
float CalculateObstruction(const Vector3& sourcePos, const Vector3& listenerPos,
const Vector3& obstaclePos);
// 遮蔽参数
void SetOcclusionHighFreqAbsorption(float value);
float GetOcclusionHighFreqAbsorption() const { return m_occlusionHighFreqAbsorb; }
void SetObstructionHighFreqDamping(float value);
float GetObstructionHighFreqDamping() const { return m_obstructionHighFreqDamp; }
private:
float m_occlusionHighFreqAbsorb = 0.5f;
float m_obstructionHighFreqDamp = 0.5f;
};
} // namespace Audio
} // namespace XCEngine
第五章 音频后端抽象层
5.1 IAudioBackend 接口
namespace XCEngine {
namespace Audio {
class IAudioBackend {
public:
virtual ~IAudioBackend() = default;
// 初始化与销毁
virtual bool Initialize(const AudioConfig& config) = 0;
virtual void Shutdown() = 0;
// 设备查询
virtual String GetDeviceName() const = 0;
virtual void GetAvailableDevices(std::vector<String>& devices) = 0;
virtual bool SetDevice(const String& deviceName) = 0;
// 混音器控制
virtual float GetMasterVolume() const = 0;
virtual void SetMasterVolume(float volume) = 0;
virtual bool IsMuted() const = 0;
virtual void SetMuted(bool muted) = 0;
// 播放控制
virtual void Start() = 0;
virtual void Stop() = 0;
virtual void Suspend() = 0;
virtual void Resume() = 0;
// 音频处理
virtual void ProcessAudio(float* buffer, uint32_t bufferSize,
uint32_t channels, uint32_t sampleRate) = 0;
// 状态查询
virtual bool IsRunning() const = 0;
virtual AudioConfig GetConfig() const = 0;
};
} // namespace Audio
} // namespace XCEngine
5.2 WASAPI 后端
namespace XCEngine {
namespace Audio {
namespace WASAPI {
class WASAPIBackend : public IAudioBackend {
public:
WASAPIBackend();
~WASAPIBackend() override;
bool Initialize(const AudioConfig& config) override;
void Shutdown() override;
String GetDeviceName() const override;
void GetAvailableDevices(std::vector<String>& devices) override;
bool SetDevice(const String& deviceName) override;
float GetMasterVolume() const override;
void SetMasterVolume(float volume) override;
bool IsMuted() const override;
void SetMuted(bool muted) override;
void Start() override;
void Stop() override;
void Suspend() override;
void Resume() override;
void ProcessAudio(float* buffer, uint32_t bufferSize,
uint32_t channels, uint32_t sampleRate) override;
bool IsRunning() const override { return m_isRunning; }
AudioConfig GetConfig() const override { return m_config; }
private:
MMRESULT InitDevice();
MMRESULT InitClient();
MMRESULT InitBuffer();
static DWORD WINAPI AudioThreadProc(LPVOID lpParameter);
void AudioThread();
void OnAudioCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
DWORD_PTR dwParam1, DWORD_PTR dwParam2);
static void CALLBACK StaticAudioCallback(HWAVEOUT hwo, UINT uMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1, DWORD_PTR dwParam2);
private:
bool m_isRunning = false;
std::thread m_audioThread;
AudioConfig m_config;
WAVEFORMATEX m_waveFormat = {};
HWAVEOUT m_hWaveOut = nullptr;
HANDLE m_hEvent = nullptr;
std::vector<float> m_mixBuffer;
uint32_t m_mixBufferSize = 0;
std::vector<WAVEOUTCAPS> m_waveOutCaps;
String m_deviceName;
IAudioEffect* m_masterEffect = nullptr;
};
} // namespace WASAPI
} // namespace Audio
} // namespace XCEngine
5.3 OpenAL 后端
namespace XCEngine {
namespace Audio {
namespace OpenAL {
class OpenALBackend : public IAudioBackend {
public:
OpenALBackend();
~OpenALBackend() override;
bool Initialize(const AudioConfig& config) override;
void Shutdown() override;
String GetDeviceName() const override;
void GetAvailableDevices(std::vector<String>& devices) override;
bool SetDevice(const String& deviceName) override;
float GetMasterVolume() const override;
void SetMasterVolume(float volume) override;
bool IsMuted() const override;
void SetMuted(bool muted) override;
void Start() override;
void Stop() override;
void Suspend() override;
void Resume() override;
void ProcessAudio(float* buffer, uint32_t bufferSize,
uint32_t channels, uint32_t sampleRate) override;
bool IsRunning() const override { return m_isRunning; }
AudioConfig GetConfig() const override { return m_config; }
private:
bool m_isRunning = false;
AudioConfig m_config;
ALCdevice* m_device = nullptr;
ALCcontext* m_context = nullptr;
ALuint m_source = 0;
ALuint m_buffers[2];
std::vector<float> m_mixBuffer;
};
} // namespace OpenAL
} // namespace Audio
} // namespace XCEngine
第六章 音频系统核心
6.1 AudioSystem
namespace XCEngine {
namespace Audio {
class AudioSystem {
public:
static AudioSystem& Get();
void Initialize(const AudioConfig& config);
void Shutdown();
void Update(float deltaTime);
// 后端控制
void SetBackend(std::unique_ptr<IAudioBackend> backend);
IAudioBackend* GetBackend() const { return m_backend.get(); }
// 设备控制
String GetCurrentDevice() const;
void SetDevice(const String& deviceName);
void GetAvailableDevices(std::vector<String>& devices);
// 全局混音控制
float GetMasterVolume() const;
void SetMasterVolume(float volume);
bool IsMuted() const;
void SetMuted(bool muted);
// 音频处理
void ProcessAudio(float* buffer, uint32_t sampleCount, uint32_t channels);
// 资源管理
AudioClip* LoadAudioClip(const String& filePath);
void UnloadAudioClip(AudioClip* clip);
AudioMixer* CreateMixer(const String& name);
void DestroyMixer(AudioMixer* mixer);
// 空间化
void SetListenerTransform(const Vector3& position, const Quaternion& rotation);
void SetListenerVelocity(const Vector3& velocity);
const Vector3& GetListenerPosition() const { return m_listenerPosition; }
const Quaternion& GetListenerRotation() const { return m_listenerRotation; }
const Vector3& GetListenerVelocity() const { return m_listenerVelocity; }
// 统计信息
struct Stats {
uint32_t activeSources;
uint32_t totalSources;
uint64_t memoryUsage;
float cpuUsage;
};
const Stats& GetStats() const { return m_stats; }
private:
AudioSystem() = default;
~AudioSystem() = default;
AudioSystem(const AudioSystem&) = delete;
AudioSystem& operator=(const AudioSystem&) = delete;
void ProcessSource(AudioSourceComponent* source);
void ApplyGlobalEffects(float* buffer, uint32_t sampleCount, uint32_t channels);
private:
std::unique_ptr<IAudioBackend> m_backend;
Vector3 m_listenerPosition = Vector3::Zero();
Quaternion m_listenerRotation = Quaternion::Identity();
Vector3 m_listenerVelocity = Vector3::Zero();
std::vector<std::unique_ptr<AudioClip>> m_loadedClips;
std::map<String, std::unique_ptr<AudioMixer>> m_mixers;
std::vector<AudioSourceComponent*> m_activeSources;
Stats m_stats = {};
float m_deltaTime = 0.0f;
};
} // namespace Audio
} // namespace XCEngine
6.2 AudioSourceComponent
namespace XCEngine {
namespace Components {
class AudioSourceComponent : public Component {
public:
AudioSourceComponent();
~AudioSourceComponent();
// 播放控制
void Play();
void Pause();
void Stop(StopMode mode = StopMode::Immediate);
bool IsPlaying() const { return m_playState == Audio::PlayState::Playing; }
bool IsPaused() const { return m_playState == Audio::PlayState::Paused; }
// 音频剪辑
void SetClip(Audio::AudioClip* clip);
Audio::AudioClip* GetClip() const { return m_clip; }
// 播放参数
void SetVolume(float volume);
float GetVolume() const { return m_volume; }
void SetPitch(float pitch);
float GetPitch() const { return m_pitch; }
void SetPan(float pan);
float GetPan() const { return m_pan; }
// 循环
void SetLooping(bool loop);
bool IsLooping() const { return m_isLooping; }
// 3D 空间化
void SetSpatialize(bool spatialize);
bool IsSpatialize() const { return m_spatialize; }
void Set3DParams(const Audio::Audio3DParams& params);
const Audio::Audio3DParams& Get3DParams() const { return m_3DParams; }
void SetDopplerLevel(float level);
float GetDopplerLevel() const { return m_3DParams.dopplerLevel; }
void SetSpread(float spread);
float GetSpread() const { return m_3DParams.spread; }
void SetReverbZoneMix(float mix);
float GetReverbZoneMix() const { return m_3DParams.reverbZoneMix; }
// 混音器
void SetOutputMixer(Audio::AudioMixer* mixer);
Audio::AudioMixer* GetOutputMixer() const { return m_outputMixer; }
// 播放位置
void SetTime(float seconds);
float GetTime() const;
float GetDuration() const;
// 能量检测
float GetEnergy() const { return m_energy; }
void StartEnergyDetect();
void StopEnergyDetect();
bool IsEnergyDetecting() const { return m_isEnergyDetecting; }
// Component 虚函数
void Update(float deltaTime) override;
void OnEnable() override;
void OnDisable() override;
void OnDestroy() override;
private:
void Apply3DAttenuation();
void ProcessEffects(float* buffer, uint32_t sampleCount);
void UpdateEnergy(const float* buffer, uint32_t sampleCount);
private:
Audio::AudioClip* m_clip = nullptr;
Audio::AudioMixer* m_outputMixer = nullptr;
PlayState m_playState = PlayState::Stopped;
bool m_isLooping = false;
float m_volume = 1.0f;
float m_pitch = 1.0f;
float m_pan = 0.0f;
bool m_spatialize = true;
Audio::Audio3DParams m_3DParams;
// 播放状态
uint64_t m_samplePosition = 0;
double m_lastingTime = 0.0;
// 能量检测
bool m_isEnergyDetecting = false;
float m_energy = 0.0f;
float m_maxEnergy = 5.0f;
std::deque<float> m_energyHistory;
// 效果链
std::vector<Audio::IAudioEffect*> m_effects;
std::unique_ptr<Audio::HRTF> m_hrtf;
std::unique_ptr<Audio::DopplerEffect> m_doppler;
// 输出缓冲
static constexpr size_t BufferSize = 8192;
std::vector<float> m_outputBuffer;
};
} // namespace Components
} // namespace XCEngine
6.3 AudioListenerComponent
namespace XCEngine {
namespace Components {
class AudioListenerComponent : public Component {
public:
AudioListenerComponent();
~AudioListenerComponent();
// 能量检测
float GetEnergy() const { return m_energy; }
const float* GetFrequencyData() const { return m_frequencyData.data(); }
size_t GetFrequencyDataSize() const { return m_frequencyData.size(); }
// 全局参数
void SetMasterVolume(float volume);
float GetMasterVolume() const { return m_masterVolume; }
void SetMute(bool mute);
bool IsMute() const { return m_mute; }
// 空间化参数
void SetDopplerLevel(float level);
float GetDopplerLevel() const { return m_dopplerLevel; }
void SetSpeedOfSound(float metersPerSecond);
float GetSpeedOfSound() const { return m_speedOfSound; }
// 混响
void SetReverbLevel(float level);
float GetReverbLevel() const { return m_reverbLevel; }
void SetReverb(Audio::AudioMixer* reverb);
Audio::AudioMixer* GetReverb() const { return m_reverb; }
// Component 虚函数
void Update(float deltaTime) override;
private:
float m_masterVolume = 1.0f;
bool m_mute = false;
float m_dopplerLevel = 1.0f;
float m_speedOfSound = 343.0f;
float m_reverbLevel = 1.0f;
Audio::AudioMixer* m_reverb = nullptr;
float m_energy = 0.0f;
std::vector<float> m_frequencyData;
};
} // namespace Components
} // namespace XCEngine
第七章 事件系统
7.1 AudioEvent
namespace XCEngine {
namespace Audio {
class AudioEvent {
public:
AudioEvent() = default;
AudioEvent(const String& name) : m_name(name) {}
using Callback = std::function<void()>;
using FloatCallback = std::function<void(float)>;
uint64_t Subscribe(Callback callback);
uint64_t Subscribe(FloatCallback callback, float param);
void Unsubscribe(uint64_t id);
void ProcessUnsubscribes();
void Invoke() const;
void Invoke(float param) const;
void Clear();
const String& GetName() const { return m_name; }
void SetName(const String& name) { m_name = name; }
private:
struct ListenerBase {
virtual ~ListenerBase() = default;
virtual void Call() = 0;
virtual void CallFloat(float) = 0;
};
template<typename Func>
struct Listener : ListenerBase {
Listener(Func&& f) : func(std::move(f)) {}
void Call() override { func(); }
void CallFloat(float) override {
if constexpr (std::is_invocable_v<Func, float>) {
func(0.0f);
} else {
func();
}
}
Func func;
};
String m_name;
std::vector<std::pair<uint64_t, std::unique_ptr<ListenerBase>>> m_listeners;
std::vector<uint64_t> m_pendingUnsubscribes;
uint64_t m_nextId = 0;
};
} // namespace Audio
} // namespace XCEngine
7.2 AudioEventSystem
namespace XCEngine {
namespace Audio {
class AudioEventSystem {
public:
static AudioEventSystem& Get();
void Initialize();
void Shutdown();
// 事件创建
AudioEvent* CreateEvent(const String& name);
AudioEvent* GetEvent(const String& name);
AudioEvent* GetEvent(uint64_t id);
void DestroyEvent(const String& name);
void DestroyEvent(uint64_t id);
// 触发事件
void TriggerEvent(const String& name);
void TriggerEvent(uint64_t id);
void TriggerEvent(const String& name, float param);
void TriggerEvent(uint64_t id, float param);
// 订阅
uint64_t Subscribe(const String& eventName, AudioEvent::Callback callback);
uint64_t Subscribe(const String& eventName, AudioEvent::FloatCallback callback, float param);
// 状态
bool HasEvent(const String& name) const;
bool HasEvent(uint64_t id) const;
size_t GetEventCount() const { return m_events.size(); }
private:
AudioEventSystem() = default;
~AudioEventSystem() = default;
std::map<String, std::unique_ptr<AudioEvent>> m_events;
std::map<uint64_t, AudioEvent*> m_idToEvent;
uint64_t m_nextEventId = 0;
};
} // namespace Audio
} // namespace XCEngine
第八章 资源管理集成
8.1 AudioClipLoader
namespace XCEngine {
namespace Resources {
class AudioClipLoader : public IResourceLoader {
public:
AudioClipLoader();
~AudioClipLoader() override;
bool CanLoad(const String& extension) const override;
IResource* Load(const String& filePath) override;
bool LoadAsync(const String& filePath, std::function<void(IResource*)> callback) override;
void Unload(IResource* resource) override;
// 获取支持的文件格式
static const std::vector<String>& GetSupportedExtensions();
private:
static std::vector<String> s_supportedExtensions;
};
} // namespace Resources
} // namespace XCEngine
8.2 ResourceManager 集成
namespace XCEngine {
namespace Resources {
// 在 ResourceManager 中添加音频相关接口
template<>
class ResourceHandle<Audio::AudioClip> {
public:
ResourceHandle() = default;
explicit ResourceHandle(Audio::AudioClip* resource);
Audio::AudioClip* Get() const { return m_resource; }
Audio::AudioClip* operator->() const { return m_resource; }
explicit operator bool() const { return m_resource != nullptr; }
private:
Audio::AudioClip* m_resource = nullptr;
};
} // namespace Resources
} // namespace XCEngine
第九章 目录结构
XCEngine/
├── engine/ # 引擎核心库
│ ├── include/XCEngine/
│ │ ├── Audio/ # 音频模块
│ │ │ ├── AudioSystem.h # 音频系统入口
│ │ │ ├── AudioConfig.h # 配置结构
│ │ │ ├── AudioTypes.h # 基础类型定义
│ │ │ ├── IAudioBackend.h # 后端抽象接口
│ │ │ ├── AudioBackendFactory.h # 后端工厂
│ │ │ │
│ │ │ ├── AudioClip.h # 音频剪辑资源
│ │ │ ├── AudioMixer.h # 混音器
│ │ │ ├── AudioBank.h # 音频银行
│ │ │ │
│ │ │ ├── IAudioEffect.h # 效果器接口
│ │ │ ├── FFTFilter.h # FFT频谱分析
│ │ │ ├── Reverbation.h # 混响效果
│ │ │ ├── Equalizer.h # 均衡器
│ │ │ ├── Compressor.h # 压缩器
│ │ │ ├── Limiter.h # 限制器
│ │ │ ├── DopplerEffect.h # 多普勒效应
│ │ │ ├── OcclusionSystem.h # 遮蔽系统
│ │ │ │
│ │ │ ├── Spatializer.h # 空间化处理
│ │ │ ├── HRTF.h # HRTF实现
│ │ │ │
│ │ │ ├── AudioEvent.h # 音频事件
│ │ │ ├── AudioEventSystem.h # 事件系统
│ │ │ │
│ │ │ ├── WASAPI/
│ │ │ │ └── WASAPIBackend.h # WASAPI后端
│ │ │ └── OpenAL/
│ │ │ └── OpenALBackend.h # OpenAL后端
│ │ │ │
│ │ │ └── XCEngineAudio.h # 主头文件
│ │ │
│ │ └── Components/
│ │ ├── AudioSourceComponent.h # 声源组件
│ │ └── AudioListenerComponent.h # 监听器组件
│ │
│ └── src/Audio/
│ ├── AudioSystem.cpp
│ ├── AudioClip.cpp
│ ├── AudioMixer.cpp
│ ├── FFTFilter.cpp
│ ├── Reverbation.cpp
│ ├── Equalizer.cpp
│ ├── HRTF.cpp
│ ├── DopplerEffect.cpp
│ ├── OcclusionSystem.cpp
│ ├── AudioEventSystem.cpp
│ ├── WASAPI/
│ │ └── WASAPIBackend.cpp
│ └── OpenAL/
│ └── OpenALBackend.cpp
│
├── mvs/ # 示例应用
│ └── Music fluctuations/ # 音频示例(参考)
│ ├── source/
│ │ ├── audio/ # 基础音频
│ │ ├── audio3d/ # 3D音频
│ │ ├── kissfft/ # FFT库
│ │ └── libsamplerate/ # 重采样库
│ └── res/ # 音频资源
│
└── tests/Audio/ # 音频模块测试
├── AudioSystemTest.cpp
├── AudioClipTest.cpp
├── SpatializerTest.cpp
└── HRTFTest.cpp
附录:实现优先级
第一阶段 - 基础音频
- AudioSystem 核心框架
- AudioClip 资源加载(WAV格式)
- AudioSourceComponent 播放控制
- AudioListenerComponent 监听器
- WASAPI 后端实现
第二阶段 - 3D 空间音频
- HRTF 空间化
- DopplerEffect 多普勒效应
- OcclusionSystem 遮蔽系统
- 距离衰减
第三阶段 - 效果系统
- FFTFilter 频谱分析
- Reverbation 混响
- Equalizer 均衡器
- Compressor/Limiter 动态效果
- 效果链系统
第四阶段 - 混音与事件
- AudioMixer 混音器
- AudioEvent 事件系统
- AudioBank 分段加载
- OpenAL 后端实现
第五阶段 - 优化与扩展
- 资源异步加载
- 性能优化
- profiler 集成
- 更多音频格式支持