diff --git a/kaffeine/src/player-parts/xine-part/kxinewidget.cpp b/kaffeine/src/player-parts/xine-part/kxinewidget.cpp index 742d55a..80804b2 100644 --- a/kaffeine/src/player-parts/xine-part/kxinewidget.cpp +++ b/kaffeine/src/player-parts/xine-part/kxinewidget.cpp @@ -61,6 +61,8 @@ #define TIMER_EVENT_RESIZE_PARENT 300 +bool KXineWidget::s_logarithmicVolume = false; + KXineWidget::KXineWidget(TQWidget* parent, const char* name, const TQString& pathToConfigFile, const TQString& pathToLogoFile, const TQString& audioDriver, const TQString& videoDriver, @@ -117,6 +119,13 @@ KXineWidget::KXineWidget(TQWidget* parent, const char* name, setUpdatesEnabled(false); setMouseTracking(true); + + // Detect xine version, this is used for volume adjustment. + // Xine versions prior to 1.2.13 use linear volume, so the engine uses logarithmic volume. + // Xine versions starting from 1.2.13 use logarithmic volume, so the engine uses linear volume. + int xinemajor = 0, xineminor = 0, xinemaint = 0; + xine_get_version(&xinemajor, &xineminor, &xinemaint); + s_logarithmicVolume = (xinemajor * 1000000 + xineminor * 1000 + xinemaint < 1002013); } @@ -2667,16 +2676,28 @@ bool KXineWidget::getAutoplayPluginURLS(const TQString& plugin, TQStringList& li } } +int KXineWidget::makeVolumeLogarithmic(int volume) +{ + // We're using a logarithmic function to make the volume ramp more natural. + return static_cast( 100 - 100.0 * std::log10( ( 100 - volume ) * 0.09 + 1.0 ) ); +} + void KXineWidget::slotSetVolume(int vol) { if (!isXineReady()) return; + if (m_softwareMixer) { + int xine_vol = vol; + if (s_logarithmicVolume) + { + xine_vol = makeVolumeLogarithmic(vol); + } //debugOut(TQString("Set software amplification level: %1").arg(vol)); if (m_volumeGain) - xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL, vol*2); + xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL, xine_vol*2); else - xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL, vol); + xine_set_param(m_xineStream, XINE_PARAM_AUDIO_AMP_LEVEL, xine_vol); } else { @@ -2696,8 +2717,8 @@ uint KXineWidget::getVolume() const if (vol > 200) { // when amp is high > 100, xine_get_param sometimes returns incorrect amp level - errorOut("Amp level returned weird results, set Amp to 100"); - vol = 100; + errorOut("Amp level returned weird results, set Amp to 200"); + vol = 200; } if (m_volumeGain) vol = vol/2; } diff --git a/kaffeine/src/player-parts/xine-part/kxinewidget.h b/kaffeine/src/player-parts/xine-part/kxinewidget.h index 4b4a581..811df93 100644 --- a/kaffeine/src/player-parts/xine-part/kxinewidget.h +++ b/kaffeine/src/player-parts/xine-part/kxinewidget.h @@ -316,6 +316,10 @@ protected: void initOSD(); virtual void run(); + static int makeVolumeLogarithmic(int volume); + + static bool s_logarithmicVolume; + private: #ifndef HAVE_XCB bool x11Event(XEvent *);