Fix playing mono audio sounds with panning
Tested on OpenAL and XAudio backkend on Windows. #3206
This commit is contained in:
@@ -161,7 +161,10 @@ public:
|
||||
case 2:
|
||||
default: // TODO: implement multi-channel support (eg. 5.1, 7.1)
|
||||
outputMatrix[0] = channels[FrontLeft];
|
||||
outputMatrix[sourceChannels + 1] = channels[FrontRight];
|
||||
if (sourceChannels == 1)
|
||||
outputMatrix[1] = channels[FrontRight];
|
||||
else
|
||||
outputMatrix[sourceChannels + 1] = channels[FrontRight];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,11 +40,17 @@
|
||||
|
||||
namespace ALC
|
||||
{
|
||||
struct SourceData
|
||||
{
|
||||
AudioDataInfo Format;
|
||||
bool Spatial;
|
||||
};
|
||||
|
||||
ALCdevice* Device = nullptr;
|
||||
ALCcontext* Context = nullptr;
|
||||
AudioBackend::FeatureFlags Features = AudioBackend::FeatureFlags::None;
|
||||
CriticalSection Locker;
|
||||
Dictionary<uint32, AudioDataInfo> SourceIDtoFormat;
|
||||
Dictionary<uint32, SourceData> SourcesData;
|
||||
|
||||
bool IsExtensionSupported(const char* extension)
|
||||
{
|
||||
@@ -88,32 +94,32 @@ namespace ALC
|
||||
alSourcef(sourceID, AL_PITCH, pitch);
|
||||
alSourcef(sourceID, AL_SEC_OFFSET, 0.0f);
|
||||
alSourcei(sourceID, AL_LOOPING, loop);
|
||||
alSourcei(sourceID, AL_SOURCE_RELATIVE, !spatial);
|
||||
alSourcei(sourceID, AL_SOURCE_RELATIVE, AL_TRUE); // Non-spatial sounds use AL_POSITION for panning
|
||||
alSourcei(sourceID, AL_BUFFER, 0);
|
||||
#ifdef AL_SOFT_source_spatialize
|
||||
alSourcei(sourceID, AL_SOURCE_SPATIALIZE_SOFT, AL_TRUE); // Always spatialize, fixes multi-channel played as spatial
|
||||
#endif
|
||||
if (spatial)
|
||||
{
|
||||
#ifdef AL_SOFT_source_spatialize
|
||||
alSourcei(sourceID, AL_SOURCE_SPATIALIZE_SOFT, AL_TRUE);
|
||||
#endif
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, attenuation);
|
||||
alSourcef(sourceID, AL_DOPPLER_FACTOR, doppler);
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(minDistance));
|
||||
alSource3f(sourceID, AL_POSITION, FLAX_POS_TO_OAL(position));
|
||||
alSource3f(sourceID, AL_VELOCITY, FLAX_VEL_TO_OAL(Vector3::Zero));
|
||||
#ifdef AL_EXT_STEREO_ANGLES
|
||||
const float panAngle = pan * PI_HALF;
|
||||
const ALfloat panAngles[2] = { (ALfloat)(PI / 6.0 - panAngle), (ALfloat)(-PI / 6.0 - panAngle) }; // Angles are specified counter-clockwise in radians
|
||||
alSourcefv(sourceID, AL_STEREO_ANGLES, panAngles);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f);
|
||||
alSourcef(sourceID, AL_DOPPLER_FACTOR, 1.0f);
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 0.0f);
|
||||
alSource3f(sourceID, AL_POSITION, 0.0f, 0.0f, 0.0f);
|
||||
alSource3f(sourceID, AL_POSITION, pan, 0, -sqrtf(1.0f - pan * pan));
|
||||
alSource3f(sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
#ifdef AL_EXT_STEREO_ANGLES
|
||||
const float panAngle = pan * PI_HALF;
|
||||
const ALfloat panAngles[2] = { (ALfloat)(PI / 6.0 - panAngle), (ALfloat)(-PI / 6.0 - panAngle) }; // Angles are specified counter-clockwise in radians
|
||||
alSourcefv(sourceID, AL_STEREO_ANGLES, panAngles);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +309,9 @@ uint32 AudioBackendOAL::Source_Add(const AudioDataInfo& format, const Vector3& p
|
||||
|
||||
// Cache audio data format assigned on source (used in Source_GetCurrentBufferTime)
|
||||
ALC::Locker.Lock();
|
||||
ALC::SourceIDtoFormat[sourceID] = format;
|
||||
auto& data = ALC::SourcesData[sourceID];
|
||||
data.Format = format;
|
||||
data.Spatial = spatial;
|
||||
ALC::Locker.Unlock();
|
||||
|
||||
return sourceID;
|
||||
@@ -317,18 +325,30 @@ void AudioBackendOAL::Source_Remove(uint32 sourceID)
|
||||
ALC_CHECK_ERROR(alDeleteSources);
|
||||
|
||||
ALC::Locker.Lock();
|
||||
ALC::SourceIDtoFormat.Remove(sourceID);
|
||||
ALC::SourcesData.Remove(sourceID);
|
||||
ALC::Locker.Unlock();
|
||||
}
|
||||
|
||||
void AudioBackendOAL::Source_VelocityChanged(uint32 sourceID, const Vector3& velocity)
|
||||
{
|
||||
alSource3f(sourceID, AL_VELOCITY, FLAX_VEL_TO_OAL(velocity));
|
||||
ALC::Locker.Lock();
|
||||
const bool spatial = ALC::SourcesData[sourceID].Spatial;
|
||||
ALC::Locker.Unlock();
|
||||
if (spatial)
|
||||
{
|
||||
alSource3f(sourceID, AL_VELOCITY, FLAX_VEL_TO_OAL(velocity));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioBackendOAL::Source_TransformChanged(uint32 sourceID, const Vector3& position, const Quaternion& orientation)
|
||||
{
|
||||
alSource3f(sourceID, AL_POSITION, FLAX_POS_TO_OAL(position));
|
||||
ALC::Locker.Lock();
|
||||
const bool spatial = ALC::SourcesData[sourceID].Spatial;
|
||||
ALC::Locker.Unlock();
|
||||
if (spatial)
|
||||
{
|
||||
alSource3f(sourceID, AL_POSITION, FLAX_POS_TO_OAL(position));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioBackendOAL::Source_VolumeChanged(uint32 sourceID, float volume)
|
||||
@@ -343,11 +363,21 @@ void AudioBackendOAL::Source_PitchChanged(uint32 sourceID, float pitch)
|
||||
|
||||
void AudioBackendOAL::Source_PanChanged(uint32 sourceID, float pan)
|
||||
{
|
||||
ALC::Locker.Lock();
|
||||
const bool spatial = ALC::SourcesData[sourceID].Spatial;
|
||||
ALC::Locker.Unlock();
|
||||
if (spatial)
|
||||
{
|
||||
#ifdef AL_EXT_STEREO_ANGLES
|
||||
const float panAngle = pan * PI_HALF;
|
||||
const ALfloat panAngles[2] = { (ALfloat)(PI / 6.0 - panAngle), (ALfloat)(-PI / 6.0 - panAngle) }; // Angles are specified counter-clockwise in radians
|
||||
alSourcefv(sourceID, AL_STEREO_ANGLES, panAngles);
|
||||
const float panAngle = pan * PI_HALF;
|
||||
const ALfloat panAngles[2] = { (ALfloat)(PI / 6.0 - panAngle), (ALfloat)(-PI / 6.0 - panAngle) }; // Angles are specified counter-clockwise in radians
|
||||
alSourcefv(sourceID, AL_STEREO_ANGLES, panAngles);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
alSource3f(sourceID, AL_POSITION, pan, 0, -sqrtf(1.0f - pan * pan));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioBackendOAL::Source_IsLoopingChanged(uint32 sourceID, bool loop)
|
||||
@@ -357,12 +387,8 @@ void AudioBackendOAL::Source_IsLoopingChanged(uint32 sourceID, bool loop)
|
||||
|
||||
void AudioBackendOAL::Source_SpatialSetupChanged(uint32 sourceID, bool spatial, float attenuation, float minDistance, float doppler)
|
||||
{
|
||||
alSourcei(sourceID, AL_SOURCE_RELATIVE, !spatial);
|
||||
if (spatial)
|
||||
{
|
||||
#ifdef AL_SOFT_source_spatialize
|
||||
alSourcei(sourceID, AL_SOURCE_SPATIALIZE_SOFT, AL_TRUE);
|
||||
#endif
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, attenuation);
|
||||
alSourcef(sourceID, AL_DOPPLER_FACTOR, doppler);
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(minDistance));
|
||||
@@ -411,7 +437,7 @@ float AudioBackendOAL::Source_GetCurrentBufferTime(uint32 sourceID)
|
||||
alGetSourcef(sourceID, AL_SEC_OFFSET, &time);
|
||||
#else
|
||||
ALC::Locker.Lock();
|
||||
AudioDataInfo clipInfo = ALC::SourceIDtoFormat[sourceID];
|
||||
AudioDataInfo clipInfo = ALC::SourcesData[sourceID].Format;
|
||||
ALC::Locker.Unlock();
|
||||
ALint samplesPlayed;
|
||||
alGetSourcei(sourceID, AL_SAMPLE_OFFSET, &samplesPlayed);
|
||||
|
||||
Reference in New Issue
Block a user