XAudio2学习之音频特效库XAPOFX

XAPOFX是一个继承自XAPO接口的音频效果集合,用于XAudio2。XAPOFX包含了几种效果以及一个通用的创建音效实例的机制。

XAPOFX中包含的效果如下表:

Effect Description Parameter Structure Parameter Constants Requirements
FXECHO An echo effect. FXECHO_PARAMETERS FXECHO Constants Only supports FLOAT32 audio formats.
FXEQ A four band equalizer. FXEQ_PARAMETERS FXEQ Constants Only supports FLOAT32 audio formats. The sample rate must be between 22,000 Hz and 48,000 Hz.
FXMasteringLimiter A volume limiter. FXMASTERINGLIMITER_PARAMETERS FXMASTERINGLIMIT Constants Only supports FLOAT32 audio formats.
FXReverb

A simple reverb effect.

XAudio2 also provides an effect implementing Princeton Digital Reverb that can be instantiated withXAudio2CreateReverb.

FXREVERB_PARAMETERS FXREVERB Constants Only supports FLOAT32 audio formats. Also, it only supports mono input to mono output, and stereo input to stereo output.

使用CreateFX接口作为通用机制来创建效果实例。此接口需要每个音效对应的CLSID来返回不同的效果实例。

HRESULT CreateFX(
         CLSID clsid,
         IUnknown **pEffect
)
每个XAudio2 voice拥有一条效果链,效果链中包含0或者多个音频效果。输送给voice的音频数据,在输出到目的voice之前,需要通过效果链中的每个效果。voice拥有每个效果的输出,输入给效果链中的下一个效果,直到效果链中没有剩余的效果为止。
使用XAPOFX中的效果,步骤如下:

1.实例化一个效果;

2.填充XAUDIO2_EFFECT_DESCRIPTOR结构体;

3.填充XAUDIO2_EFFECT_CHAIN结构体;

4.将对象传递给XAudio2;

5.释放对象;

6.填充参数结构体;

7.将参数结构体传递给XAudio2.

XAPOFX相关的宏定义以及每个音效的CLSID:

// FX class IDs
class __declspec(uuid("F5E01117-D6C4-485A-A3F5-695196F3DBFA")) FXEQ;
class __declspec(uuid("C4137916-2BE1-46FD-8599-441536F49856")) FXMasteringLimiter;
class __declspec(uuid("7D9ACA56-CB68-4807-B632-B137352E8596")) FXReverb;
class __declspec(uuid("5039D740-F736-449A-84D3-A56202557B87")) FXEcho;

    // EQ parameter bounds (inclusive), used with FXEQ:
    #define FXEQ_MIN_FRAMERATE 22000
    #define FXEQ_MAX_FRAMERATE 48000

    #define FXEQ_MIN_FREQUENCY_CENTER       20.0f
    #define FXEQ_MAX_FREQUENCY_CENTER       20000.0f
    #define FXEQ_DEFAULT_FREQUENCY_CENTER_0 100.0f   // band 0
    #define FXEQ_DEFAULT_FREQUENCY_CENTER_1 800.0f   // band 1
    #define FXEQ_DEFAULT_FREQUENCY_CENTER_2 2000.0f  // band 2
    #define FXEQ_DEFAULT_FREQUENCY_CENTER_3 10000.0f // band 3

    #define FXEQ_MIN_GAIN     0.126f // -18dB
    #define FXEQ_MAX_GAIN     7.94f  // +18dB
    #define FXEQ_DEFAULT_GAIN 1.0f   // 0dB change, all bands

    #define FXEQ_MIN_BANDWIDTH     0.1f
    #define FXEQ_MAX_BANDWIDTH     2.0f
    #define FXEQ_DEFAULT_BANDWIDTH 1.0f // all bands


    // Mastering limiter parameter bounds (inclusive), used with FXMasteringLimiter:
    #define FXMASTERINGLIMITER_MIN_RELEASE     1
    #define FXMASTERINGLIMITER_MAX_RELEASE     20
    #define FXMASTERINGLIMITER_DEFAULT_RELEASE 6

    #define FXMASTERINGLIMITER_MIN_LOUDNESS     1
    #define FXMASTERINGLIMITER_MAX_LOUDNESS     1800
    #define FXMASTERINGLIMITER_DEFAULT_LOUDNESS 1000


    // Reverb parameter bounds (inclusive), used with FXReverb:
    #define FXREVERB_MIN_DIFFUSION     0.0f
    #define FXREVERB_MAX_DIFFUSION     1.0f
    #define FXREVERB_DEFAULT_DIFFUSION 0.9f

    #define FXREVERB_MIN_ROOMSIZE     0.0001f
    #define FXREVERB_MAX_ROOMSIZE     1.0f
    #define FXREVERB_DEFAULT_ROOMSIZE 0.6f


    // Echo initialization data/parameter bounds (inclusive), used with FXEcho:
    #define FXECHO_MIN_WETDRYMIX     0.0f
    #define FXECHO_MAX_WETDRYMIX     1.0f
    #define FXECHO_DEFAULT_WETDRYMIX 0.5f

    #define FXECHO_MIN_FEEDBACK     0.0f
    #define FXECHO_MAX_FEEDBACK     1.0f
    #define FXECHO_DEFAULT_FEEDBACK 0.5f

    #define FXECHO_MIN_DELAY     1.0f
    #define FXECHO_MAX_DELAY     2000.0f
    #define FXECHO_DEFAULT_DELAY 500.0f
每个音效对应的参数结构体如下:

  // EQ parameters (4 bands), used with IXAPOParameters::SetParameters:
    // The EQ supports only FLOAT32 audio foramts.
    // The framerate must be within [22000, 48000] Hz.
    typedef struct FXEQ_PARAMETERS {
        float FrequencyCenter0; // center frequency in Hz, band 0
        float Gain0;            // boost/cut
        float Bandwidth0;       // bandwidth, region of EQ is center frequency +/- bandwidth/2
        float FrequencyCenter1; // band 1
        float Gain1;
        float Bandwidth1;
        float FrequencyCenter2; // band 2
        float Gain2;
        float Bandwidth2;
        float FrequencyCenter3; // band 3
        float Gain3;
        float Bandwidth3;
    } FXEQ_PARAMETERS;


    // Mastering limiter parameters, used with IXAPOParameters::SetParameters:
    // The mastering limiter supports only FLOAT32 audio formats.
    typedef struct FXMASTERINGLIMITER_PARAMETERS {
        UINT32 Release;  // release time (tuning factor with no specific units)
        UINT32 Loudness; // loudness target (threshold)
    } FXMASTERINGLIMITER_PARAMETERS;


    // Reverb parameters, used with IXAPOParameters::SetParameters:
    // The reverb supports only FLOAT32 audio formats with the following
    // channel configurations:
    //     Input: Mono   Output: Mono
    //     Input: Stereo Output: Stereo
    typedef struct FXREVERB_PARAMETERS {
        float Diffusion; // diffusion
        float RoomSize;  // room size
    } FXREVERB_PARAMETERS;


    // Echo initialization data, used with CreateFX:
    // Use of this structure is optional, the default MaxDelay is FXECHO_DEFAULT_DELAY.
    typedef struct FXECHO_INITDATA {
        float MaxDelay;  // maximum delay (all channels) in milliseconds, must be within [FXECHO_MIN_DELAY, FXECHO_MAX_DELAY]
    } FXECHO_INITDATA;

    // Echo parameters, used with IXAPOParameters::SetParameters:
    // The echo supports only FLOAT32 audio formats.
    typedef struct FXECHO_PARAMETERS {
        float WetDryMix; // ratio of wet (processed) signal to dry (original) signal
        float Feedback;  // amount of output fed back into input
        float Delay;     // delay (all channels) in milliseconds, must be within [FXECHO_MIN_DELAY, FXECHO_PARAMETERS.MaxDelay]
    } FXECHO_PARAMETERS;
下面是如何使用XAPOFX库中音频效果的实例,使用方式类似于XAudio2内置音效:

#pragma once
#include "WaveFile.h"
#include "XAudio2.h"
#include <xapofx.h>

#pragma comment(lib,"XAPOFX.lib")

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;
	hr = CreateFX(__uuidof(FXReverb), &pXAPO);//创建FXReverb特效。还有另外三个:FXEQ;FXMasteringLimiter;FXEcho。
	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接管此对象。防止外部对此对象修改,释放

	FXREVERB_PARAMETERS XAPOParameters;
	XAPOParameters.Diffusion = FXREVERB_DEFAULT_DIFFUSION;
	XAPOParameters.RoomSize = FXREVERB_DEFAULT_ROOMSIZE;

	int effectIndex = 0;
	hr = pSourceVoice->SetEffectParameters(effectIndex, &XAPOParameters, sizeof(XAPOParameters));//将设置传递给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 <xapofx.h>

#pragma comment(lib,"XAPOFX.lib")
才可以使用XAPOFX特效。

交流QQ:1245178753

本文地址:http://blog.csdn.net/u011417605/article/details/51187365

你可能感兴趣的:(音效,XAudio2)