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:
|
case 2:
|
||||||
default: // TODO: implement multi-channel support (eg. 5.1, 7.1)
|
default: // TODO: implement multi-channel support (eg. 5.1, 7.1)
|
||||||
outputMatrix[0] = channels[FrontLeft];
|
outputMatrix[0] = channels[FrontLeft];
|
||||||
outputMatrix[sourceChannels + 1] = channels[FrontRight];
|
if (sourceChannels == 1)
|
||||||
|
outputMatrix[1] = channels[FrontRight];
|
||||||
|
else
|
||||||
|
outputMatrix[sourceChannels + 1] = channels[FrontRight];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,11 +40,17 @@
|
|||||||
|
|
||||||
namespace ALC
|
namespace ALC
|
||||||
{
|
{
|
||||||
|
struct SourceData
|
||||||
|
{
|
||||||
|
AudioDataInfo Format;
|
||||||
|
bool Spatial;
|
||||||
|
};
|
||||||
|
|
||||||
ALCdevice* Device = nullptr;
|
ALCdevice* Device = nullptr;
|
||||||
ALCcontext* Context = nullptr;
|
ALCcontext* Context = nullptr;
|
||||||
AudioBackend::FeatureFlags Features = AudioBackend::FeatureFlags::None;
|
AudioBackend::FeatureFlags Features = AudioBackend::FeatureFlags::None;
|
||||||
CriticalSection Locker;
|
CriticalSection Locker;
|
||||||
Dictionary<uint32, AudioDataInfo> SourceIDtoFormat;
|
Dictionary<uint32, SourceData> SourcesData;
|
||||||
|
|
||||||
bool IsExtensionSupported(const char* extension)
|
bool IsExtensionSupported(const char* extension)
|
||||||
{
|
{
|
||||||
@@ -88,32 +94,32 @@ namespace ALC
|
|||||||
alSourcef(sourceID, AL_PITCH, pitch);
|
alSourcef(sourceID, AL_PITCH, pitch);
|
||||||
alSourcef(sourceID, AL_SEC_OFFSET, 0.0f);
|
alSourcef(sourceID, AL_SEC_OFFSET, 0.0f);
|
||||||
alSourcei(sourceID, AL_LOOPING, loop);
|
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);
|
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)
|
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_ROLLOFF_FACTOR, attenuation);
|
||||||
alSourcef(sourceID, AL_DOPPLER_FACTOR, doppler);
|
alSourcef(sourceID, AL_DOPPLER_FACTOR, doppler);
|
||||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(minDistance));
|
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(minDistance));
|
||||||
alSource3f(sourceID, AL_POSITION, FLAX_POS_TO_OAL(position));
|
alSource3f(sourceID, AL_POSITION, FLAX_POS_TO_OAL(position));
|
||||||
alSource3f(sourceID, AL_VELOCITY, FLAX_VEL_TO_OAL(Vector3::Zero));
|
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
|
else
|
||||||
{
|
{
|
||||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f);
|
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f);
|
||||||
alSourcef(sourceID, AL_DOPPLER_FACTOR, 1.0f);
|
alSourcef(sourceID, AL_DOPPLER_FACTOR, 1.0f);
|
||||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 0.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);
|
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)
|
// Cache audio data format assigned on source (used in Source_GetCurrentBufferTime)
|
||||||
ALC::Locker.Lock();
|
ALC::Locker.Lock();
|
||||||
ALC::SourceIDtoFormat[sourceID] = format;
|
auto& data = ALC::SourcesData[sourceID];
|
||||||
|
data.Format = format;
|
||||||
|
data.Spatial = spatial;
|
||||||
ALC::Locker.Unlock();
|
ALC::Locker.Unlock();
|
||||||
|
|
||||||
return sourceID;
|
return sourceID;
|
||||||
@@ -317,18 +325,30 @@ void AudioBackendOAL::Source_Remove(uint32 sourceID)
|
|||||||
ALC_CHECK_ERROR(alDeleteSources);
|
ALC_CHECK_ERROR(alDeleteSources);
|
||||||
|
|
||||||
ALC::Locker.Lock();
|
ALC::Locker.Lock();
|
||||||
ALC::SourceIDtoFormat.Remove(sourceID);
|
ALC::SourcesData.Remove(sourceID);
|
||||||
ALC::Locker.Unlock();
|
ALC::Locker.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioBackendOAL::Source_VelocityChanged(uint32 sourceID, const Vector3& velocity)
|
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)
|
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)
|
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)
|
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
|
#ifdef AL_EXT_STEREO_ANGLES
|
||||||
const float panAngle = pan * PI_HALF;
|
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
|
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);
|
alSourcefv(sourceID, AL_STEREO_ANGLES, panAngles);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alSource3f(sourceID, AL_POSITION, pan, 0, -sqrtf(1.0f - pan * pan));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioBackendOAL::Source_IsLoopingChanged(uint32 sourceID, bool loop)
|
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)
|
void AudioBackendOAL::Source_SpatialSetupChanged(uint32 sourceID, bool spatial, float attenuation, float minDistance, float doppler)
|
||||||
{
|
{
|
||||||
alSourcei(sourceID, AL_SOURCE_RELATIVE, !spatial);
|
|
||||||
if (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_ROLLOFF_FACTOR, attenuation);
|
||||||
alSourcef(sourceID, AL_DOPPLER_FACTOR, doppler);
|
alSourcef(sourceID, AL_DOPPLER_FACTOR, doppler);
|
||||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(minDistance));
|
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);
|
alGetSourcef(sourceID, AL_SEC_OFFSET, &time);
|
||||||
#else
|
#else
|
||||||
ALC::Locker.Lock();
|
ALC::Locker.Lock();
|
||||||
AudioDataInfo clipInfo = ALC::SourceIDtoFormat[sourceID];
|
AudioDataInfo clipInfo = ALC::SourcesData[sourceID].Format;
|
||||||
ALC::Locker.Unlock();
|
ALC::Locker.Unlock();
|
||||||
ALint samplesPlayed;
|
ALint samplesPlayed;
|
||||||
alGetSourcei(sourceID, AL_SAMPLE_OFFSET, &samplesPlayed);
|
alGetSourcei(sourceID, AL_SAMPLE_OFFSET, &samplesPlayed);
|
||||||
|
|||||||
Reference in New Issue
Block a user