summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichele Calgaro <[email protected]>2023-10-06 22:00:01 +0900
committerMichele Calgaro <[email protected]>2023-10-09 13:57:17 +0900
commit58bbed05107c58789755ff70e89f50458a14407b (patch)
tree9a7fb41413b1d32c9364295192c96fd6ad7313c9
parent79a8d17988a72d78635a3757382ed21441a4bc01 (diff)
downloadcodeine-58bbed05107c58789755ff70e89f50458a14407b.tar.gz
codeine-58bbed05107c58789755ff70e89f50458a14407b.zip
xine engine: make volume control logarithmic for versions of xine < 1.2.13. For xine versions >= 1.2.13, libxine already makes the volume logarithmic. This relates to TDE/tdemultimedia#40.
Signed-off-by: Michele Calgaro <[email protected]> (cherry picked from commit b5977d5e67d68ec18fad1d1130f5a306ce4fe598)
-rw-r--r--src/app/mainWindow.cpp2
-rw-r--r--src/app/mainWindow.h2
-rw-r--r--src/app/stateChange.cpp5
-rw-r--r--src/app/volumeAction.cpp2
-rw-r--r--src/app/volumeAction.h4
-rw-r--r--src/app/xineEngine.cpp43
-rw-r--r--src/app/xineEngine.h2
7 files changed, 51 insertions, 9 deletions
diff --git a/src/app/mainWindow.cpp b/src/app/mainWindow.cpp
index 9ca9bc0..b94a2e9 100644
--- a/src/app/mainWindow.cpp
+++ b/src/app/mainWindow.cpp
@@ -265,7 +265,7 @@ MainWindow::setupActions()
(new KWidgetAction( m_positionSlider, i18n("Position Slider"), 0, 0, 0, ac, "position_slider" ))->setAutoSized( true );
- new VolumeAction( toolBar(), ac );
+ m_volumeAction = new VolumeAction( toolBar(), ac );
}
void
diff --git a/src/app/mainWindow.h b/src/app/mainWindow.h
index 2139cd5..6ba9e89 100644
--- a/src/app/mainWindow.h
+++ b/src/app/mainWindow.h
@@ -11,6 +11,7 @@ class KURL;
class TQLabel;
class TQPopupMenu;
class TQSlider;
+class VolumeAction;
namespace Codeine
@@ -65,6 +66,7 @@ namespace Codeine
TQLabel *m_timeLabel;
TQLabel *m_titleLabel;
TQWidget *m_analyzer;
+ VolumeAction *m_volumeAction;
//undefined
MainWindow( const MainWindow& );
diff --git a/src/app/stateChange.cpp b/src/app/stateChange.cpp
index db07231..e0450d3 100644
--- a/src/app/stateChange.cpp
+++ b/src/app/stateChange.cpp
@@ -16,6 +16,7 @@
#include "theStream.h"
#include "videoSettings.h" //FIXME unfortunate
#include "xineEngine.h"
+#include "volumeAction.h"
//TODO do in Sconstruct
@@ -62,9 +63,7 @@ MainWindow::engineStateChanged( Engine::State state )
toggleAction( "play" )->setChecked( state == Playing );
//FIXME bad design to do this way
- TQSlider *volume = (TQSlider*)toolBar()->child( "volume" );
- if (volume)
- volume->setValue( engine()->volume() );
+ m_volumeAction->sliderMoved( engine()->volume() );
}
diff --git a/src/app/volumeAction.cpp b/src/app/volumeAction.cpp
index 1663190..0d8a181 100644
--- a/src/app/volumeAction.cpp
+++ b/src/app/volumeAction.cpp
@@ -77,7 +77,7 @@ VolumeAction::toggled( bool const b )
{
DEBUG_BLOCK
- TQString t = TQString::number(Codeine::engine()->volume()) + "%";
+ TQString t = TQString::number(100 - m_widget->slider->value()) + "%";
setToolTip( i18n( "Volume: %1" ).arg( t ) );
m_widget->label->setText( t );
diff --git a/src/app/volumeAction.h b/src/app/volumeAction.h
index d2a2520..67cfad0 100644
--- a/src/app/volumeAction.h
+++ b/src/app/volumeAction.h
@@ -17,9 +17,11 @@ class VolumeAction : public TDEToggleAction
virtual int plug( TQWidget*, int );
+public slots:
+ void sliderMoved( int );
+
private slots:
void toggled( bool );
- void sliderMoved( int );
void sliderReleased() { setChecked( false ); toggled( false ); }
public:
diff --git a/src/app/xineEngine.cpp b/src/app/xineEngine.cpp
index 74f4f35..3a05862 100644
--- a/src/app/xineEngine.cpp
+++ b/src/app/xineEngine.cpp
@@ -26,6 +26,7 @@ namespace Codeine {
VideoWindow *VideoWindow::s_instance = 0;
+bool VideoWindow::s_logarithmicVolume = false;
VideoWindow::VideoWindow( TQWidget *parent )
@@ -53,6 +54,13 @@ VideoWindow::VideoWindow( TQWidget *parent )
//TODO sucks
//TODO namespace this?
myList->next = myList; //init the buffer list
+
+ // 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);
}
VideoWindow::~VideoWindow()
@@ -65,7 +73,12 @@ VideoWindow::~VideoWindow()
if( m_stream && xine_get_status( m_stream ) == XINE_STATUS_PLAY ) {
int cum = 0;
for( int v = 99; v >= 0; v-- ) {
- xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, v );
+ int vol = v;
+ if (s_logarithmicVolume)
+ {
+ vol = makeVolumeLogarithmic(vol);
+ }
+ xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, vol );
int sleep = int(32000 * (-std::log10( double(v + 1) ) + 2));
::usleep( sleep );
@@ -255,6 +268,7 @@ VideoWindow::load( const KURL &url )
setParameter( XINE_PARAM_SPU_CHANNEL, -1 );
setParameter( XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -1 );
setParameter( XINE_PARAM_VO_ASPECT_RATIO, 0 );
+ // 100 is the same for both linear and logarithmic volume control
setParameter( XINE_PARAM_AUDIO_AMP_LEVEL, 100 );
#undef setParameter
@@ -445,8 +459,20 @@ VideoWindow::posTimeLength( PosTimeLength type ) const
uint
VideoWindow::volume() const
{
- //TODO I don't like the design
- return xine_get_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL );
+ int vol = xine_get_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL );
+ if (s_logarithmicVolume)
+ {
+ vol = 100 - 100.0 * (pow(10, (100.0 - vol) / 100.0) - 1) / 9.0;
+ }
+ if (vol < 0)
+ {
+ vol = 0;
+ }
+ if (vol > 100)
+ {
+ vol = 100;
+ }
+ return (uint)vol;
}
void
@@ -532,6 +558,13 @@ VideoWindow::seek( uint pos )
xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_MUTE, 0 );
}
+int
+VideoWindow::makeVolumeLogarithmic(int volume)
+{
+ // We're using a logarithmic function to make the volume ramp more natural.
+ return static_cast<uint>( 100 - 100.0 * std::log10( ( 100 - volume ) * 0.09 + 1.0 ) );
+}
+
void
VideoWindow::setStreamParameter( int value )
{
@@ -558,6 +591,10 @@ VideoWindow::setStreamParameter( int value )
{
parameter = XINE_PARAM_AUDIO_AMP_LEVEL;
value = 100 - value; // TQt sliders are wrong way round when vertical
+ if (s_logarithmicVolume)
+ {
+ value = makeVolumeLogarithmic(value);
+ }
}
else
return;
diff --git a/src/app/xineEngine.h b/src/app/xineEngine.h
index 70271b9..d152a96 100644
--- a/src/app/xineEngine.h
+++ b/src/app/xineEngine.h
@@ -39,6 +39,7 @@ namespace Codeine
enum PosTimeLength { Pos, Time, Length };
static VideoWindow *s_instance;
+ static bool s_logarithmicVolume;
VideoWindow( const VideoWindow& ); //disable
VideoWindow &operator=( const VideoWindow& ); //disable
@@ -120,6 +121,7 @@ namespace Codeine
private:
static void destSizeCallBack( void*, int, int, double, int*, int*, double* );
static void frameOutputCallBack( void*, int, int, double, int*, int*, int*, int*, double*, int*, int* );
+ static int makeVolumeLogarithmic(int volume);
void initVideo();
void cleanUpVideo();