微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 X3DAudio 时的单声道输出

如何解决使用 X3DAudio 时的单声道输出

我正在制作一个简单的音频引擎,音频在 2D 中运行良好,现在我想使用 X3DAudio 来获得定位在 3D 空间中的声音。我已经按照文档进行操作,现在可以使用 X3DAudio 播放声音,但由于某种原因,它输出的是单声道声音,尽管我的主人有 2 个声道,并且声音也有 2 个声道。
我做错了什么?

首先,我初始化 X3DAudio

DWORD dwChannelMask;
pMasteringVoice->GetChannelMask(&dwChannelMask);

X3DAudioInitialize(dwChannelMask,X3DAUdio_SPEED_OF_SOUND,hX3dAudio);

然后,我初始化侦听器内容(并将向量从我的坐标系转换为 X3DAudio 使用的坐标系):

x3dAudioListener.pCone = NULL;

listenerProps.position = X3DAUdio_VECTOR(-listenerProps.position.x,listenerProps.position.z,listenerProps.position.y);
listenerProps.veLocity = X3DAUdio_VECTOR(-listenerProps.veLocity.x,listenerProps.veLocity.z,listenerProps.veLocity.y);
listenerProps.topVector = X3DAUdio_VECTOR(-listenerProps.topVector.x,listenerProps.topVector.z,listenerProps.topVector.y);
listenerProps.forwardVector = X3DAUdio_VECTOR(-listenerProps.forwardVector.x,listenerProps.forwardVector.z,listenerProps.forwardVector.y);

x3dAudioListener.OrientFront = listenerProps.forwardVector;
x3dAudioListener.OrientTop = listenerProps.topVector;
x3dAudioListener.Position = listenerProps.position;
x3dAudioListener.VeLocity = listenerProps.veLocity;

然后,我初始化 DSP 设置:

xaudio2_VOICE_DETAILS masterVoiceDetails;
pAudioEngine->pMasteringVoice->GetVoiceDetails(&masterVoiceDetails);

xaudio2_VOICE_DETAILS sourceVoiceDetails;
pSourceVoice->GetVoiceDetails(&sourceVoiceDetails);

p3dAudioMatrix = new float[sourceVoiceDetails.InputChannels * masterVoiceDetails.InputChannels];
memset(p3dAudioMatrix,sizeof(float) * sourceVoiceDetails.InputChannels * masterVoiceDetails.InputChannels);

x3dAudioDSPSettings.SrcChannelCount = sourceVoiceDetails.InputChannels;
x3dAudioDSPSettings.DstChannelCount = masterVoiceDetails.InputChannels;
x3dAudioDSPSettings.pMatrixCoefficients = p3dAudioMatrix;
x3dAudioDSPSettings.pDelayTimes = NULL;

然后应用声音位置:

emitterProps.position = X3DAUdio_VECTOR(-emitterProps.position.x,emitterProps.position.z,emitterProps.position.y);
emitterProps.veLocity = X3DAUdio_VECTOR(-emitterProps.veLocity.x,emitterProps.veLocity.z,emitterProps.veLocity.y);
emitterProps.topVector = X3DAUdio_VECTOR(-emitterProps.topVector.x,emitterProps.topVector.z,emitterProps.topVector.y);
emitterProps.forwardVector = X3DAUdio_VECTOR(-emitterProps.forwardVector.x,emitterProps.forwardVector.z,emitterProps.forwardVector.y);

x3dAudioEmitter = {0};
x3dAudioEmitter.pCone = NULL;
x3dAudioEmitter.pLFECurve = NULL;
x3dAudioEmitter.pLPFDirectCurve = NULL;
x3dAudioEmitter.pLPFReverbCurve = NULL;
x3dAudioEmitter.pVolumeCurve = NULL;
x3dAudioEmitter.pReverbCurve = NULL;
x3dAudioEmitter.OrientFront = emitterProps.forwardVector;
x3dAudioEmitter.OrientTop = emitterProps.topVector;
x3dAudioEmitter.Position = emitterProps.position;
x3dAudioEmitter.VeLocity = emitterProps.veLocity;
x3dAudioEmitter.InnerRadius = 2.0f;
x3dAudioEmitter.InnerRadiusAngle = X3DAUdio_PI/4.0f;
x3dAudioEmitter.ChannelCount = soundInfo.iChannels;
x3dAudioEmitter.ChannelRadius = 10.0f;
x3dAudioEmitter.CurvedistanceScaler = 1.0f;
x3dAudioEmitter.DopplerScaler = 1.0f;
float* pEmitterazimuths = new float[x3dAudioEmitter.ChannelCount];
memset(pEmitterazimuths,x3dAudioEmitter.ChannelCount * sizeof(float));
x3dAudioEmitter.pChannelAzimuths = pEmitterazimuths;


UINT32 iFlags = X3DAUdio_CALculaTE_MATRIX;
if (bCalcDopplerEffect) iFlags |= X3DAUdio_CALculaTE_DOPPLER;


X3DAudioCalculate(pAudioEngine->hX3dAudio,&pAudioEngine->x3dAudioListener,&x3dAudioEmitter,iFlags,&x3dAudioDSPSettings);

xaudio2_VOICE_DETAILS masterVoiceDetails;
pAudioEngine->pMasteringVoice->GetVoiceDetails(&masterVoiceDetails);

delete[] pEmitterazimuths;

HRESULT hr = pSourceVoice->SetoutputMatrix(pAudioEngine->pMasteringVoice,soundInfo.iChannels,masterVoiceDetails.InputChannels,x3dAudioDSPSettings.pMatrixCoefficients);
if (Failed(hr))
{
    // error handling
}

if (bCalcDopplerEffect)
{
    hr = pSourceVoice->SetFrequencyRatio(x3dAudioDSPSettings.DopplerFactor);
    if (Failed(hr))
    {
        // error handling
    }
}

调试层已启用,我看不到任何错误。我检查过 soundInfo.iChannels 是 == 2 并且主通道数也是 2。 我应用这样的侦听器/发射器属性

listenerProps.position = X3DAUdio_VECTOR(0.0f,0.0f,0.0f);
listenerProps.veLocity = X3DAUdio_VECTOR(0.0f,0.0f);
listenerProps.forwardVector = X3DAUdio_VECTOR(0.0f,1.0f,0.0f);
listenerProps.topVector = X3DAUdio_VECTOR(0.0f,1.0f);

SEmitterProps props;
props.position = X3DAUdio_VECTOR(-5.0f,0.0f);
props.veLocity = X3DAUdio_VECTOR(fSoundSpeed,0.0f);
props.forwardVector = X3DAUdio_VECTOR(-1.0f,0.0f);
props.topVector = X3DAUdio_VECTOR(0.0f,1.0f);

在我的坐标系中,x 是从右到左,上是 z,y 是由近到远。

解决方法

正确使用 X3DAudio 有很多参数和步骤,我无法从上面的代码中判断出您是否已正确归零并设置 X3DAUDIO_LISTENER、{{1} 中的所有值},和 X3DAUDIO_EMITTER 所以先检查一下。任何未初始化的值都会导致问题。

最初在旧版 DirectX SDK 中提供的 XAudio2 示例的最新版本可以在 GitHub 上找到。特别是,请查看 XAudio2Sound3D。您应该尝试将所有发射器/侦听器值硬编码为一些简单的东西以进行测试,并确保在将其连接到您的坐标系之前可以正常工作。

除了来自旧版 DirectX SDK 的 XAudio2 示例之外,您还应该查看 DirectX Tool Kit for Audio,它是 DirectX Tool Kit 的一部分,用于{ {3}} / DX11

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。