将X3Daudio与XAudio2集成



我目前正在努力用XAudio2库实现3D定位声音。当监听器和源的位置在所有轴上正好是0.0f时,我设法让它工作起来。当我稍微移动听众或音源时,声音就不再被听到,但仍在播放。我在这里错过了什么?谢谢:(

uint32_t sourceInputChannels = 2;
uint32_t masterInputChannels = 8;
float* outputMatrix = new float[masterInputChannels * sourceInputChannels];
// Listener
X3DAUDIO_LISTENER listener{};
listener.Position = { 0.0f, 0.0f, 0.0f };
listener.Velocity = { 0.0f, 0.0f, 0.0f };
listener.OrientFront = { 1.0f, 0.0f, 0.0f };
listener.OrientTop = { 0.0f, 0.0f, 1.0f };
// Emitter
X3DAUDIO_EMITTER sourceEmitter{};
sourceEmitter.ChannelCount = 1;
sourceEmitter.CurveDistanceScaler = FLT_MIN;
sourceEmitter.Position = { 0.0f, 0.0f, 0.0f };
sourceEmitter.Velocity = { 0.0f, 0.0f, 0.0f };
sourceEmitter.OrientFront = { 1.0f, 0.0f, 0.0f };
sourceEmitter.OrientTop = { 0.0f, 0.0f, 1.0f };
sourceEmitter.ChannelRadius = 2.0f;
sourceEmitter.InnerRadius = 2.0f;
sourceEmitter.InnerRadiusAngle = X3DAUDIO_PI / 4.0f;
X3DAUDIO_DSP_SETTINGS dspSettings{};
dspSettings.SrcChannelCount = sourceEmitter.ChannelCount; // 1
// 8 * 2, OUTPUT_CHANNELS is also present in CreateMasteringVoice
dspSettings.DstChannelCount = OUTPUT_CHANNELS * sourceVoiceDetails.InputChannels; 
dspSettings.pMatrixCoefficients = outputMatrix;
// Calculating
X3DAudioCalculate(g_CealContext->X3DInstance, &listener, &sourceEmitter, X3DAUDIO_CALCULATE_MATRIX | 
X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_LPF_DIRECT | X3DAUDIO_CALCULATE_REVERB, &dspSettings);
sourceVoice->SetOutputMatrix(g_CealContext->XMasterVoice, sourceInputChannels, masterInputChannels, outputMatrix);
delete[] outputMatrix;

X3DAudio有很多参数,但我猜问题是您有立体声(2声道(源语音,并且试图使用1声道DSP设置。您还传递了许多X3DAUDIO_CALCULATE_标志,这些标志需要比您提供的更多的数据。

您应该看看托管在GitHub上的原始遗留DirectX SDK XAudio2示例。特别请参见XAudio2Sound3D。

您还应该看看DirectX音频工具包。

此外,sourceEmitter.CurveDistanceScalersourceEmitter.DopplerScaler通常应为1.0。

更新 :如果SrcChannelCount大于1,则必须提供发射器方位角。我在DirectX音频工具包AudioEmitter::EnableDefaultMultiChannel中有一个助手方法,它基于简单的扬声器几何结构来设置这些功能——这就是传统XACT处理它们的方式。

// **Note these constants came from xact3d3.h in the legacy DirectX SDK**
//
// Supported speaker positions, represented as azimuth angles.
//
// Here's a picture of the azimuth angles for the 8 cardinal points,
// seen from above.  The emitter's base position is at the origin 0.
//
//           FRONT
//             | 0  <-- azimuth
//             |
//    7pi/4   |  / pi/4
//            | /
// LEFT       |/      RIGHT
// 3pi/2-------0-------pi/2
//            /|
//           / | 
//    5pi/4 /  |   3pi/4
//             |
//             | pi
//           BACK
//
constexpr float LEFT_AZIMUTH = 3 * X3DAUDIO_PI / 2;
constexpr float RIGHT_AZIMUTH = X3DAUDIO_PI / 2;
constexpr float FRONT_LEFT_AZIMUTH = 7 * X3DAUDIO_PI / 4;
constexpr float FRONT_RIGHT_AZIMUTH = X3DAUDIO_PI / 4;
constexpr float FRONT_CENTER_AZIMUTH = 0.0f;
constexpr float LOW_FREQUENCY_AZIMUTH = X3DAUDIO_2PI;
constexpr float BACK_LEFT_AZIMUTH = 5 * X3DAUDIO_PI / 4;
constexpr float BACK_RIGHT_AZIMUTH = 3 * X3DAUDIO_PI / 4;
constexpr float BACK_CENTER_AZIMUTH = X3DAUDIO_PI;
constexpr float c_channelAzimuths[9][8] =
{
/* 0 */   { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f },
/* 1 */   { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f },
/* 2 */   { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f },
/* 2.1 */ { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, LOW_FREQUENCY_AZIMUTH, 0.f, 0.f, 0.f, 0.f, 0.f },
/* 4.0 */ { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH, 0.f, 0.f, 0.f, 0.f },
/* 4.1 */ { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, LOW_FREQUENCY_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH, 0.f, 0.f, 0.f },
/* 5.1 */ { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, FRONT_CENTER_AZIMUTH, LOW_FREQUENCY_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH, 0.f, 0.f },
/* 6.1 */ { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, FRONT_CENTER_AZIMUTH, LOW_FREQUENCY_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH, BACK_CENTER_AZIMUTH, 0.f },
/* 7.1 */ { FRONT_LEFT_AZIMUTH, FRONT_RIGHT_AZIMUTH, FRONT_CENTER_AZIMUTH, LOW_FREQUENCY_AZIMUTH, BACK_LEFT_AZIMUTH, BACK_RIGHT_AZIMUTH, LEFT_AZIMUTH, RIGHT_AZIMUTH }
};
...
emitter.ChannelCount = channels;
emitter.ChannelRadius = 1.f;
emitter.pChannelAzimuths = (channels <= 8)
? &c_channelAzimuths[channels] : nullptr;

好吧,多亏了@chuck walbourn,我成功地让它工作了
问题是X3DAUDIO_EMITTER的成员CurveDistanceScaler被设置为FLT_MIN,而不是某个不太小的值
奇怪的是,我正在关注微软的官方文档《如何将X3DAudio与XAudio2集成》,示例代码使用FLT_MIN,所以我真的不明白发生了什么。

最新更新