XAudio2提供了两种内置音频特效,这两种音频特效以及它们的创建方式如下:
Effect | Creation Method |
---|---|
Reverb | XAudio2CreateReverb |
Volume Meter | XAudio2CreateVolumeMeter |
1.创建XAPO对象;
2.创建XAPO对象描述结构体对象,用于对XAPO信息进行描述;
3.创建效果链结构体对象,用于持有描述结构体对象:包括两个成员变量:一个是持有的对象个数,一个是所有对象的数组;
4.将效果链传递给XAudio2;
5.释放XAPO对象;
6.创建音效参数结构体对象,并设置需要的值;
7.将参数结构体对象传递给XAudio2对象;
8.启用或者禁用效果。
对于参数结构体各个成员变量,上一篇文章也有说明,如果觉得我表达的不准确,可以去查看MSDN或者DirectX 手册。对于每个结构体成员变量的取值,都是有范围的,XAduio2也提供了缺省值,具体如下:
// XAUDIO2FX_REVERB_PARAMETERS: Native parameter set for the reverb effect typedef struct XAUDIO2FX_REVERB_PARAMETERS { // ratio of wet (processed) signal to dry (original) signal float WetDryMix; // [0, 100] (percentage) // Delay times UINT32 ReflectionsDelay; // [0, 300] in ms BYTE ReverbDelay; // [0, 85] in ms BYTE RearDelay; // [0, 5] in ms // Indexed parameters BYTE PositionLeft; // [0, 30] no units BYTE PositionRight; // [0, 30] no units, ignored when configured to mono BYTE PositionMatrixLeft; // [0, 30] no units BYTE PositionMatrixRight; // [0, 30] no units, ignored when configured to mono BYTE EarlyDiffusion; // [0, 15] no units BYTE LateDiffusion; // [0, 15] no units BYTE LowEQGain; // [0, 12] no units BYTE LowEQCutoff; // [0, 9] no units BYTE HighEQGain; // [0, 8] no units BYTE HighEQCutoff; // [0, 14] no units // Direct parameters float RoomFilterFreq; // [20, 20000] in Hz float RoomFilterMain; // [-100, 0] in dB float RoomFilterHF; // [-100, 0] in dB float ReflectionsGain; // [-100, 20] in dB float ReverbGain; // [-100, 20] in dB float DecayTime; // [0.1, inf] in seconds float Density; // [0, 100] (percentage) float RoomSize; // [1, 100] in feet // component control BOOL DisableLateField; // TRUE to disable late field reflections } XAUDIO2FX_REVERB_PARAMETERS; // Maximum, minimum and default values for the parameters above #define XAUDIO2FX_REVERB_MIN_WET_DRY_MIX 0.0f #define XAUDIO2FX_REVERB_MIN_REFLECTIONS_DELAY 0 #define XAUDIO2FX_REVERB_MIN_REVERB_DELAY 0 #define XAUDIO2FX_REVERB_MIN_REAR_DELAY 0 #define XAUDIO2FX_REVERB_MIN_POSITION 0 #define XAUDIO2FX_REVERB_MIN_DIFFUSION 0 #define XAUDIO2FX_REVERB_MIN_LOW_EQ_GAIN 0 #define XAUDIO2FX_REVERB_MIN_LOW_EQ_CUTOFF 0 #define XAUDIO2FX_REVERB_MIN_HIGH_EQ_GAIN 0 #define XAUDIO2FX_REVERB_MIN_HIGH_EQ_CUTOFF 0 #define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_FREQ 20.0f #define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_MAIN -100.0f #define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_HF -100.0f #define XAUDIO2FX_REVERB_MIN_REFLECTIONS_GAIN -100.0f #define XAUDIO2FX_REVERB_MIN_REVERB_GAIN -100.0f #define XAUDIO2FX_REVERB_MIN_DECAY_TIME 0.1f #define XAUDIO2FX_REVERB_MIN_DENSITY 0.0f #define XAUDIO2FX_REVERB_MIN_ROOM_SIZE 0.0f #define XAUDIO2FX_REVERB_MAX_WET_DRY_MIX 100.0f #define XAUDIO2FX_REVERB_MAX_REFLECTIONS_DELAY 300 #define XAUDIO2FX_REVERB_MAX_REVERB_DELAY 85 #define XAUDIO2FX_REVERB_MAX_REAR_DELAY 5 #define XAUDIO2FX_REVERB_MAX_POSITION 30 #define XAUDIO2FX_REVERB_MAX_DIFFUSION 15 #define XAUDIO2FX_REVERB_MAX_LOW_EQ_GAIN 12 #define XAUDIO2FX_REVERB_MAX_LOW_EQ_CUTOFF 9 #define XAUDIO2FX_REVERB_MAX_HIGH_EQ_GAIN 8 #define XAUDIO2FX_REVERB_MAX_HIGH_EQ_CUTOFF 14 #define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_FREQ 20000.0f #define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_MAIN 0.0f #define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_HF 0.0f #define XAUDIO2FX_REVERB_MAX_REFLECTIONS_GAIN 20.0f #define XAUDIO2FX_REVERB_MAX_REVERB_GAIN 20.0f #define XAUDIO2FX_REVERB_MAX_DENSITY 100.0f #define XAUDIO2FX_REVERB_MAX_ROOM_SIZE 100.0f #define XAUDIO2FX_REVERB_DEFAULT_WET_DRY_MIX 100.0f #define XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_DELAY 5 #define XAUDIO2FX_REVERB_DEFAULT_REVERB_DELAY 5 #define XAUDIO2FX_REVERB_DEFAULT_REAR_DELAY 5 #define XAUDIO2FX_REVERB_DEFAULT_POSITION 6 #define XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX 27 #define XAUDIO2FX_REVERB_DEFAULT_EARLY_DIFFUSION 8 #define XAUDIO2FX_REVERB_DEFAULT_LATE_DIFFUSION 8 #define XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_GAIN 8 #define XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_CUTOFF 4 #define XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_GAIN 8 #define XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_CUTOFF 4 #define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_FREQ 5000.0f #define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_MAIN 0.0f #define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_HF 0.0f #define XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_GAIN 0.0f #define XAUDIO2FX_REVERB_DEFAULT_REVERB_GAIN 0.0f #define XAUDIO2FX_REVERB_DEFAULT_DECAY_TIME 1.0f #define XAUDIO2FX_REVERB_DEFAULT_DENSITY 100.0f #define XAUDIO2FX_REVERB_DEFAULT_ROOM_SIZE 100.0f #define XAUDIO2FX_REVERB_DEFAULT_DISABLE_LATE_FIELD FALSE
本篇主要是展示如何使用内置混响音频特效,具体实现代码如下:
#pragma once #include "WaveFile.h" #include "XAudio2.h" #include <XAudio2fx.h> class VoiceCallBack : public IXAudio2VoiceCallback { public: HANDLE hBufferEndEvent; VoiceCallBack() : hBufferEndEvent(CreateEvent(NULL, FALSE, FALSE, NULL)){} ~VoiceCallBack(){ CloseHandle(hBufferEndEvent); } void OnStreamEnd() { /*SetEvent(hBufferEndEvent);*/ } void OnVoiceProcessingPassEnd() { } void OnVoiceProcessingPassStart(UINT32 SamplesRequired) { } //Called when the voice has just finished playing an audio buffer. void OnBufferEnd(void * pBufferContext) { SetEvent(hBufferEndEvent); } void OnBufferStart(void * pBufferContext) { } void OnLoopEnd(void * pBufferContext) { /*SetEvent(hBufferEndEvent);*/ } void OnVoiceError(void * pBufferContext, HRESULT Error) { } }; int main(int argc, char *argv[]) { HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);;//com初始化 if (FAILED(hr)) return 0; IXAudio2 *pEngine = NULL; hr = XAudio2Create(&pEngine);//创建引擎 if (FAILED(hr)) return 0; IXAudio2MasteringVoice *pMasterVoice = NULL; hr = pEngine->CreateMasteringVoice(&pMasterVoice);//创建主声音,默认是输出当前扬声器 if (FAILED(hr)) return 0; CWaveFile waveFile; hr = waveFile.Open(L"F:\\桌面\\24bit-48khz.wav", NULL, WAVEFILE_READ);//加载文件 if (FAILED(hr)) return 0; WAVEFORMATEX *waveFormat = waveFile.GetFormat();//获取文件格式 VoiceCallBack callBack; IXAudio2SourceVoice *pSourceVoice = NULL; hr = pEngine->CreateSourceVoice(&pSourceVoice, waveFormat, 0, 1.0f, &callBack);//创建源声音,用来提交数据 if (FAILED(hr)) return 0; IUnknown *pXAPO = NULL; hr = XAudio2CreateReverb(&pXAPO);//创建混响对象 if (FAILED(hr)) return 0; XAUDIO2_EFFECT_DESCRIPTOR descriptor;//效果描述,包含了一个XAPO的信息 descriptor.InitialState = true; descriptor.OutputChannels = 2; descriptor.pEffect = pXAPO; XAUDIO2_EFFECT_CHAIN eChain;//效果链,包含了含有几个效果对象 eChain.EffectCount = 1; eChain.pEffectDescriptors = &descriptor; hr = pSourceVoice->SetEffectChain(&eChain);//将效果链传递给voice if (FAILED(hr)) return 0; pXAPO->Release();//传给voice后,voice接管此对象。防止外部对此对象修改,释放 XAUDIO2FX_REVERB_PARAMETERS reverbParameters;//创建参数结构体对象 reverbParameters.ReflectionsDelay = XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_DELAY; reverbParameters.ReverbDelay = XAUDIO2FX_REVERB_DEFAULT_REVERB_DELAY; reverbParameters.RearDelay = XAUDIO2FX_REVERB_DEFAULT_REAR_DELAY; reverbParameters.PositionLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION; reverbParameters.PositionRight = XAUDIO2FX_REVERB_DEFAULT_POSITION; reverbParameters.PositionMatrixLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX; reverbParameters.PositionMatrixRight = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX; reverbParameters.EarlyDiffusion = XAUDIO2FX_REVERB_DEFAULT_EARLY_DIFFUSION; reverbParameters.LateDiffusion = XAUDIO2FX_REVERB_DEFAULT_LATE_DIFFUSION; reverbParameters.LowEQGain = XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_GAIN; reverbParameters.LowEQCutoff = XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_CUTOFF; reverbParameters.HighEQGain = XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_GAIN; reverbParameters.HighEQCutoff = XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_CUTOFF; reverbParameters.RoomFilterFreq = XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_FREQ; reverbParameters.RoomFilterMain = XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_MAIN; reverbParameters.RoomFilterHF = XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_HF; reverbParameters.ReflectionsGain = XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_GAIN; reverbParameters.ReverbGain = XAUDIO2FX_REVERB_DEFAULT_REVERB_GAIN; reverbParameters.DecayTime = XAUDIO2FX_REVERB_DEFAULT_DECAY_TIME; reverbParameters.Density = XAUDIO2FX_REVERB_DEFAULT_DENSITY; reverbParameters.RoomSize = XAUDIO2FX_REVERB_DEFAULT_ROOM_SIZE; reverbParameters.WetDryMix = XAUDIO2FX_REVERB_DEFAULT_WET_DRY_MIX; int effectIndex = 0; hr = pSourceVoice->SetEffectParameters(effectIndex, &reverbParameters, sizeof(reverbParameters));//将设置传递给voice if (FAILED(hr)) return 0; hr = pSourceVoice->EnableEffect(effectIndex);//启动音效。禁止音效是DisableEffect(effectIndex); if (FAILED(hr)) return 0; DWORD size = waveFile.GetSize();//获取文件的大小 BYTE *pData = new BYTE[size];//申请内存空间,用于保存数据 hr = waveFile.Read(pData, size, &size);//读取文件内容 if (FAILED(hr)) return 0; XAUDIO2_BUFFER buffer = {0};//将读取的文件数据,赋值XAUDIO2_BUFFER buffer.AudioBytes = size; buffer.pAudioData = pData; //buffer.Flags = XAUDIO2_END_OF_STREAM; hr = pSourceVoice->SubmitSourceBuffer(&buffer);//提交内存数据 if (FAILED(hr)) return 0; hr = pSourceVoice->Start(0);//启动源声音 if (FAILED(hr)) return 0; XAUDIO2_VOICE_STATE state; while (pSourceVoice->GetState(&state), state.BuffersQueued > 0)//等待队列中的数据播放完成,退出线程 { WaitForSingleObject(callBack.hBufferEndEvent, INFINITE); } pMasterVoice->DestroyVoice();//释放资源 pSourceVoice->DestroyVoice();//释放资源 pEngine->Release();//释放资源 CoUninitialize();//释放资源 delete []pData;//释放资源 pData = NULL; return 0; }需要注意的是,需要包含头文件:
#include <XAudio2fx.h>才可以使用内置音效混响。
交流QQ:1245178753
本文地址:http://blog.csdn.net/u011417605/article/details/51178625