您的位置:首页 > 其它

XAudio2学习之采样率转换

2016-03-27 09:45 363 查看
使用IXAduio2SubmixVoice可以对wave文件进行采样率转换,以满足设备对波形音频采样率的要求。在XAudio2学习三之获取音频输出设备信息可以看到音频播放设备是有自己支持播放的wave文件的格式的。

以将2通道/44.1k采样率的wave转为2通道/48k的wave为例:

首先,初始化COM组件;

HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);;//com初始化
if (FAILED(hr))
return 0;

然后,然后创建IXAudio2引擎;

IXAudio2 *pEngine = NULL;
hr = XAudio2Create(&pEngine);//创建引擎
if (FAILED(hr))
return 0;


然后,创建主声音,并指定通道数为2,采样率为48K;

WAVEFORMATEX waveFormatex;//设置主声音的格式
waveFormatex.nChannels = 2;
waveFormatex.nSamplesPerSec = 48000;
waveFormatex.wBitsPerSample = 32;
waveFormatex.nAvgBytesPerSec = 384000;
waveFormatex.nBlockAlign = 8;
waveFormatex.wFormatTag = WAVE_FORMAT_PCM;

IXAudio2MasteringVoice *pMasterVoice = NULL;
hr = pEngine->CreateMasteringVoice(&pMasterVoice,waveFormatex.nChannels,waveFormatex.nSamplesPerSec);//创建主声音,默认是输出当前扬声器
if (FAILED(hr))
return 0;
然后,读取wave文件,并获取文件格式信息;

CWaveFile waveFile;
hr = waveFile.Open(L"C:\\Users\\xdd\\Desktop\\时间都去哪儿了.wav", NULL, WAVEFILE_READ);//加载文件
if (FAILED(hr))
return 0;

WAVEFORMATEX *waveFormat = waveFile.GetFormat();//获取文件格式
然后,创建IXAudio2SubmixVoice对象,创建时指定通道数为获取文件格式的通道数,采样率为文件的采样率,并指定对象的输出voice为mastering voice:

XAUDIO2_SEND_DESCRIPTOR pSend;
pSend.pOutputVoice = pMasterVoice;//指定输出为mastering voice
pSend.Flags = XAUDIO2_SEND_USEFILTER;

XAUDIO2_VOICE_SENDS pSendList;
pSendList.pSends = &pSend;
pSendList.SendCount = 1;

IXAudio2SubmixVoice *pSubmixVoice = NULL;
hr = pEngine->CreateSubmixVoice(&pSubmixVoice, waveFormat->nChannels, waveFormat->nSamplesPerSec, 0, 0, &pSendList);//指定输出为mastering voice
if (FAILED(hr))
return 0;
除了上面在创建时直接指定输出voice外,还可以使用下面的方法:

pSubmixVoice->SetOutputVoices(&pSendList);
然后,创建IXAudio2SourceVoice对象,创建时使用获取的文件的格式信息,并指定输出voice为上面创建的IXAduio2SubmixVoice对象,同时使用IXAudio2VoiceCallback回调,方便播放:
pSend.pOutputVoice = pSubmixVoice;//指定输出为SubmixVoice
pSend.Flags = XAUDIO2_SEND_USEFILTER;

pSendList.pSends = &pSend;
pSendList.SendCount = 1;

VoiceCallback voiceCallBack;
IXAudio2SourceVoice *pSourceVoice = NULL;
hr = pEngine->CreateSourceVoice(&pSourceVoice, waveFormat, 0, 1.0f, &voiceCallBack,&pSendList);//创建源声音,用来提交数据.指定输出为SubmixVoice
if (FAILED(hr))


然后,读取wave音频数据,并使用IXAudio2SourceVoice对象提交数据,启动播放:

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;
pSourceVoice->GetState(&state);//获取状态
while (state.BuffersQueued)
{
WaitForSingleObject(voiceCallBack.hBufferEndEvent, INFINITE);
pSourceVoice->GetState(&state);
}
最后,释放资源。
pMasterVoice->DestroyVoice();//释放资源
pSubmixVoice->DestroyVoice();//
pSourceVoice->DestroyVoice();//释放资源
pEngine->Release();//释放资源
CoUninitialize();//释放资源

delete []pData;//释放资源
pData = NULL;
编译,运行。可以听到很清晰的声音。



源码下载:http://download.csdn.net/detail/u011417605/9473537

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

交流QQ:1245178753
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: