如何:将 X3DAudio 与 XAudio2 集成

本主题演示如何将 X3DAudio 与 XAudio2 集成。 可以使用 X3DAudio 为 XAudio2 语音提供音量和音调值,以及 XAudio2 内置混响效果的参数。 本主题假定已按照 如何:生成基本音频处理图中所述创建了音频图。 如果尚未创建音频图, X3DAudioInitialize 将失败。

初始化 X3DAudio

  1. 通过调用 X3DAudioInitialize 初始化 X3DAudio

    X3DAudioInitialize 函数采用指示扬声器设置的标志、以用户定义的世界单位/秒为单位的声速以及返回 X3DAudio 引擎实例的句柄。 调用 IXAudio2MasteringVoice::GetChannelMask 以获取输出格式的通道掩码。

    DWORD dwChannelMask;       
    pMasteringVoice->GetChannelMask( &dwChannelMask );       
    
    X3DAUDIO_HANDLE X3DInstance;
    X3DAudioInitialize( dwChannelMask, X3DAUDIO_SPEED_OF_SOUND, X3DInstance );
    
  2. 创建 X3DAUDIO_LISTENERX3DAUDIO_EMITTER 结构的实例。

    X3DAUDIO_LISTENER结构表示听到声音的任何内容的位置。 通常,这是相机的位置或靠近它的位置。 X3DAUDIO_EMITTER结构表示发出声音的物体的位置。 跟踪的每个声音都有一个 X3DAUDIO_EMITTER 结构。

    应在此处初始化不会在游戏循环中更新的结构的成员。 结构的大多数成员都可以简单地初始化为零。 但是, 需要将X3DAUDIO_EMITTER 的某些成员设置为非零值。 X3DAUDIO_EMITTER的 ChannelCount 成员需要初始化为发射器表示的语音中的通道数。 此外, X3DAUDIO_EMITTER 的 CurveDistanceScaler 成员必须位于FLT_MAX FLT_MIN范围内。

    X3DAUDIO_LISTENER Listener = {};
    
    X3DAUDIO_EMITTER Emitter = {};
    Emitter.ChannelCount = 1;
    Emitter.CurveDistanceScaler = Emitter.DopplerScaler = 1.0f;
    

此处的 ChannelCount 假定我们播放的是最容易设置的单声道声音。 对于具有 1 个以上声道的声源,还必须设置发射器 ChannelRadiuspChannelAzimuths 值。

  1. 创建 X3DAUDIO_DSP_SETTINGS 结构的实例。

    X3DAUDIO_DSP_SETTINGS 结构用于返回由 X3DAudioCalculate 计算的结果。 X3DAudioCalculate 函数不为其任何参数分配内存。 这意味着,如果要使用 X3DAUDIO_DSP_SETTINGS结构的 pMatrixCoefficients 和 pDelayTimes 成员,则需要为它们分配数组。 此外,需要将 SrcChannelCount 和 DstChannelCount 成员设置为发射器的源语音和目标语音中的通道数。

    X3DAUDIO_DSP_SETTINGS DSPSettings = {};
    FLOAT32 * matrix = new FLOAT32[deviceDetails.OutputFormat.Format.nChannels];
    DSPSettings.SrcChannelCount = 1;
    DSPSettings.DstChannelCount = deviceDetails.OutputFormat.Format.nChannels;
    DSPSettings.pMatrixCoefficients = matrix;
    

    注意

    在主语音上使用 IXAudio2Voice::GetVoiceDetails 获取 nChannels 的 InputChannels 数。 对于 Windows 8 之前的 DirectX SDK XAUDIO2 版本,请使用 IXAudio2::GetDeviceDetails。

     

每两到三帧执行一次这些步骤,以计算新设置并应用它们。 在此示例中,源语音将直接发送到主语音和子混合语音,并应用了混响效果。

使用 X3DAudio 计算和应用新的 3D 音频设置

  1. 使用当前位置、速度和方向更新 X3DAUDIO_LISTENERX3DAUDIO_EMITTER 结构。

    Emitter.OrientFront = EmitterOrientFront;
    Emitter.OrientTop = EmitterOrientTop;
    Emitter.Position = EmitterPosition;
    Emitter.Velocity = EmitterVelocity;
    Listener.OrientFront = ListenerOrientFront;
    Listener.OrientTop = ListenerOrientTop;
    Listener.Position = ListenerPosition;
    Listener.Velocity = ListenerVelocity;
    
  2. 调用 X3DAudioCalculate 以计算语音的新设置。

    X3DAudioCalculate 的参数将是更新X3DAUDIO_LISTENERX3DAUDIO_EMITTER结构。 标志将指示 X3DAudioCalculate 应计算哪些值,以及哪些 X3DAUDIO_DSP_SETTINGS 结构将保存所执行计算的结果。

    X3DAudioCalculate(X3DInstance, &Listener, &Emitter,
        X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_LPF_DIRECT | X3DAUDIO_CALCULATE_REVERB,
        &DSPSettings );
    
  3. 使用 IXAudio2Voice::SetOutputMatrixIXAudio2SourceVoice::SetFrequencyRatio 将音量和音调值应用于源语音。

    pSFXSourceVoice->SetOutputMatrix( pMasterVoice, 1, deviceDetails.OutputFormat.Format.nChannels, DSPSettings.pMatrixCoefficients ) ;
    pSFXSourceVoice->SetFrequencyRatio(DSPSettings.DopplerFactor);
    
  4. 使用 IXAudio2Voice::SetOutputMatrix 将计算的混响级别应用于子混合语音。

    pSFXSourceVoice->SetOutputMatrix(pSubmixVoice, 1, 1, &DSPSettings.ReverbLevel);
    
  5. 使用 IXAudio2Voice::SetFilterParameters 将计算的低通筛选器直接系数应用于源语音。

    XAUDIO2_FILTER_PARAMETERS FilterParameters = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * DSPSettings.LPFDirectCoefficient), 1.0f };
    pSFXSourceVoice->SetFilterParameters(&FilterParameters);
    

X3DAudio

X3DAudio 概述

XAudio2 编程指南

XAudio2 音量和音调控制