XAudio2学习之内置音效:混响

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

时间: 2024-10-07 01:29:19

XAudio2学习之内置音效:混响的相关文章

perl学习之内置变量

Perl内置特殊变量 一.正则表达式特殊变量:1.$n  :包含上次模式匹配的第n个子串2.$& :前一次成功模式匹配的字符串3.$`  :前次匹配成功的子串之前的内容4.$’ :前次匹配成功的子串之后的内容5.$+ :前一次使用括号的模式匹配的字符串. 二.文件句柄特殊变量:1.$| :如果设置为零,在每次调用函数write或print后,自动调用函数fflush,将所写内容写回文件2.$% :当前输出页号3.$= :当前每页长度4.$- :当前页剩余的行数5.$~ :当前报表输出格式的名称.

python3学习之内置函数

filter    参数中函数返回True或者False,将元素返回到结果 li = [1,2,3,4,5,6] f = lambda a: a>3    原理:简单函数用lambda:a相当于参数,"a>3"是函数体,有返回值 filter(函数A,可迭代序列B)   原理:把B的值逐个给A,过滤机制在函数A中,返回True时输出当前B的值,否则不输出 filter(lambda a: a>3,li) def  f1(a): if  a>3: return T

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.

17、Cocos2dx 3.0游戏开发找小三之内置的常用层:三剑客LayerColor、LayerGradient、Menu

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30477587 为了方便游戏开发者,Cocos2d-x 内置了 3 种特殊的 Layer: 具体如下所示: LayerColor:一个单纯的实心色块. LayerGradient:一个色块,但可以设置两种颜色的渐变效果. Menu:十分常用的游戏菜单. LayerColor 与 与 LayerGradient 这两个层十分简单,都仅仅包含一个色块. 不同

老李分享:持续集成学好jenkins之内置命令

老李分享:持续集成学好jenkins之内置命令 Jenkins命令调用方式:调用Jenkins命令设置job的描述信息. $JAVA_BIN-jar "$JENKINS_CLI_JAR" -s "$JENKINS_URL"  set-build-description "${JOB_NAME}""${BUILD_NUMBER}" "$tag_name" --username "$SVN_USERN

XAudio2学习之IXAudio2VoiceCallback回调

使用IXAudio2VoiceCallback回调的好处是,在音频数据播放完的时候,可以通知外部程序进行其他操作. 使用IXAudio2VoiceCallback需要继承此接口,然后重新实现,因为内部所有函数都是纯虚函数.所有函数中使用比较多的是OnStreamEnd函数,当音频数据播放完成的时候,OnStreamEnd会触发一个事件. 继承实现IXAudio2VoiceCallback接口: class VoiceCallback : public IXAudio2VoiceCallback

Metasploit 四之内置PostgreSQL数据库

最近工作很不顺心,也在看python,所以没有坚持写笔记,今天就更新一点笔记,metasploit支持的数据库有2种,一种是PostgreSQL,还有一个是大家熟悉的MySQL,其实MySQL我都不熟悉,我只用过orcal MMSQL 还有accsess数据库,至于PostgreSQL,我之前都没听过,好了,这个无所谓,除非是团队做安全,对于个人来说,我想啥数据库都无所谓吧,希望支持SQL语句^_^ kaili_linux 刚下载的metasploit是无法自建数据库的,应该是个BUG,BT的我

XAudio2学习之采样率转换

使用IXAduio2SubmixVoice可以对wave文件进行采样率转换,以满足设备对波形音频采样率的要求.在XAudio2学习三之获取音频输出设备信息可以看到音频播放设备是有自己支持播放的wave文件的格式的. 以将2通道/44.1k采样率的wave转为2通道/48k的wave为例: 首先,初始化COM组件: HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);;//com初始化 if (FAILED(hr)) return 0;

转载FPGA学习之内嵌乘法器调用

补充一点,除法的时候如果直接a/b那么就会调用lpm模块,不管输入是否是常数,乘法的时候输入都是reg型变量会调用硬件乘法器,有一个是常数就会调用lpm模块. 上课的时候一直听老师说真正实践的时候你别想着要自己写一个乘法器,那样子做的孩子是笨蛋. 不管老师说得对不对,总之,既然FPGA内部有硬件乘法器那么为啥不直接使用呢,而且在写verilog使用是非常简单的,只是用个*号就轻易搞定. 只要所使用的FPGA内嵌有乘法器,则综合软件在综合的时候就会自动帮你调用乘法器实现. 下面是一段简单代码: m