标签:
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
标签:
原文地址:http://blog.csdn.net/u011417605/article/details/51178625