Skip to content
Browse files

[AE/Pulseaudio] add CAEUtil::PercentToPulseVolume to convert hardware…

… volume [0,1] to pulseaudio volume [0,PA_VOLUME_NORM]. This fixes volume range mismatch between AE [-60,0]dB and pulseaudio (-inf,0]dB. This should work with any version of Puleaudio as long as PA_VOLUME_NORM is correctly defined.
  • Loading branch information...
1 parent 275ec26 commit e9346f23d4df60648e581d23292d1528e586e1b3 @s7mx1 committed Nov 30, 2012
View
3 xbmc/cores/AudioEngine/Engines/PulseAE/PulseAESound.cpp
@@ -23,6 +23,7 @@
#include "PulseAESound.h"
#include "AEFactory.h"
+#include "Utils/AEUtil.h"
#include "utils/log.h"
#include "MathUtils.h"
#include "StringUtils.h"
@@ -81,7 +82,7 @@ bool CPulseAESound::Initialize()
m_maxVolume = CAEFactory::GetEngine()->GetVolume();
m_volume = 1.0f;
- pa_volume_t paVolume = pa_sw_volume_from_linear((double)(m_volume * m_maxVolume));
+ pa_volume_t paVolume = CAEUtil::PercentToPulseVolume((double)(m_volume * m_maxVolume));
pa_cvolume_set(&m_chVolume, m_sampleSpec.channels, paVolume);
pa_threaded_mainloop_lock(m_mainLoop);
View
5 xbmc/cores/AudioEngine/Engines/PulseAE/PulseAEStream.cpp
@@ -24,6 +24,7 @@
#include "PulseAEStream.h"
#include "AEFactory.h"
#include "Utils/AEUtil.h"
+#include "Utils/AEUtil.h"
#include "utils/log.h"
#include "utils/MathUtils.h"
#include "threads/SingleLock.h"
@@ -138,7 +139,7 @@ CPulseAEStream::CPulseAEStream(pa_context *context, pa_threaded_mainloop *mainLo
m_MaxVolume = CAEFactory::GetEngine()->GetVolume();
m_Volume = 1.0f;
- pa_volume_t paVolume = pa_sw_volume_from_linear((double)(m_Volume * m_MaxVolume));
+ pa_volume_t paVolume = CAEUtil::PercentToPulseVolume((double)(m_Volume * m_MaxVolume));
pa_cvolume_set(&m_ChVolume, m_SampleSpec.channels, paVolume);
#if PA_CHECK_VERSION(1,0,0)
@@ -419,7 +420,7 @@ void CPulseAEStream::SetVolume(float volume)
if (volume > 0.f)
{
m_Volume = volume;
- pa_volume_t paVolume = pa_sw_volume_from_linear((double)(m_Volume * m_MaxVolume));
+ pa_volume_t paVolume = CAEUtil::PercentToPulseVolume((double)(m_Volume * m_MaxVolume));
pa_cvolume_set(&m_ChVolume, m_SampleSpec.channels, paVolume);
}
View
24 xbmc/cores/AudioEngine/Utils/AEUtil.h
@@ -24,6 +24,10 @@
#include "PlatformDefs.h"
#include <math.h>
+#if defined(HAS_PULSEAUDIO)
+#include <pulse/pulseaudio.h>
+#endif
+
#ifdef TARGET_WINDOWS
#if _M_IX86_FP>0 && !defined(__SSE__)
#define __SSE__
@@ -81,6 +85,26 @@ class CAEUtil
{
return pow(10.0f, dB/20);
}
+
+ #if defined(HAS_PULSEAUDIO)
+ /*
+ Hardware volume [0,1] will be converted to dB using PercentToGain() and then converted to scale by
+ GainToScale() before reaching PulseAudio. However the underlying math assumes 60dB volume range which
+ contradicts (-inf,0] volume range used by pulseaudio 2.0 and above. To fix this we will reverse the
+ process of GainToScale() and PercentToGain() to get hardware volume then using our own linear converter to
+ get valid pulseaudio volume [0,PA_VOLUME_NORM].
+ */
+ static inline const int PercentToPulseVolume(const float value)
+ {
+ float hardware_volume = 0.f;
+ // This is to reverse "pow(10.0f, dB/20)" in GainToScale() and "(value - 1)*db_range" in PercentToGain()
+ if ( value > 0.f )
+ hardware_volume = (double)( (20 * log10(value)) / 60 + 1 );
+ // This is to simulate pa_sw_volume_from_linear() which convert a linear hardware volume rage [0,1]
+ // to pulseaudio volume rage [0, PA_VOLUME_NORM]
+ return (int)( hardware_volume * PA_VOLUME_NORM );
+ }
+ #endif
#ifdef __SSE__
static void SSEMulArray (float *data, const float mul, uint32_t count);

0 comments on commit e9346f2

Please sign in to comment.
Something went wrong with that request. Please try again.