我正在学习微软XAudio2的X3Daudio示例代码,并且对发送源语音并行于submix语音和母带语音感到困惑。
if( FAILED( hr = g_audioState.pXAudio2->CreateMasteringVoice( &g_audioState.pMasteringVoice ) ) )
{
SAFE_RELEASE( g_audioState.pXAudio2 );
return hr;
}
if( FAILED( hr = g_audioState.pXAudio2->CreateSubmixVoice( &g_audioState.pSubmixVoice, 1,
nSampleRate, 0, 0,
nullptr, &effectChain ) ) )
{
SAFE_RELEASE( g_audioState.pXAudio2 );
SAFE_RELEASE( g_audioState.pReverbEffect );
return hr;
}
//上面第二个参数nullptr->没有sendlist指针指向submix voice,我所理解的是,这个submix voice没有输出。
XAUDIO2_SEND_DESCRIPTOR sendDescriptors[2];
sendDescriptors[0].Flags = XAUDIO2_SEND_USEFILTER; // LPF direct-path
sendDescriptors[0].pOutputVoice = g_audioState.pMasteringVoice;
sendDescriptors[1].Flags = XAUDIO2_SEND_USEFILTER; // LPF reverb-path -- omit for better performance at the cost of less realistic occlusion
sendDescriptors[1].pOutputVoice = g_audioState.pSubmixVoice;
const XAUDIO2_VOICE_SENDS sendList = { 2, sendDescriptors };
// create the source voice
V_RETURN( g_audioState.pXAudio2->CreateSourceVoice( &g_audioState.pSourceVoice, pwfx, 0,
2.0f, nullptr, &sendList ) );
源音将声音发送给母带音和副混音。副音会对声音产生混响效果。但是我看不出副混音是如何将后处理和混响效果发送到母带声音以输出到扬声器的。
如果submix voice在创建时没有指定sendlist,则默认将其声音数据发送到母带voice。为什么在这个样本中,我们还需要同时发送源语音到母带语音?演示输出声音总是带有混响效果。我没有看到在示例可执行文件中有禁用混响效果的选项。
我很困惑
如果您不提供发送列表,则语音将自动连接到母带语音。每MSDN:
pSendList [in, optional]
Pointer to a list of XAUDIO2_VOICE_SENDS structures that describe
the set of destination voices for the submix voice. If pSendList is
NULL, the send list will default to a single output to the first
mastering voice created.
如果您提供了一个发送列表,但是,那么语音的输出不会转到母带语音,除非您在发送列表中指定它。这就是为什么源声音会同时发送给母带声音和副混音声音。
混响是在混音上做的原因是一个优化。它允许所有受混响影响的源声音进行处理,包括过滤和源速率转换到子混音,然后通常昂贵的效果(在这种情况下,环境混响)可以运行一次,而不是每个源声音。此外,将副混音制成单声道而不是多声道,因此在效果处理之前,任何立体声或多声道源也被下混音到副混音中。第三,这允许你发送一些声音到母音,而不是从混响中排除的副混音(通常是HUD和界面声音)。
请注意,最新版本的XAudio2示例可以在GitHub上找到。你可能还想看看DirectX Tool Kit for Audio.