@ -26,6 +26,7 @@ namespace Codeine {
VideoWindow * VideoWindow : : s_instance = 0 ;
VideoWindow * VideoWindow : : s_instance = 0 ;
bool VideoWindow : : s_logarithmicVolume = false ;
VideoWindow : : VideoWindow ( TQWidget * parent )
VideoWindow : : VideoWindow ( TQWidget * parent )
@ -53,6 +54,13 @@ VideoWindow::VideoWindow( TQWidget *parent )
//TODO sucks
//TODO sucks
//TODO namespace this?
//TODO namespace this?
myList - > next = myList ; //init the buffer list
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 ( )
VideoWindow : : ~ VideoWindow ( )
@ -65,7 +73,12 @@ VideoWindow::~VideoWindow()
if ( m_stream & & xine_get_status ( m_stream ) = = XINE_STATUS_PLAY ) {
if ( m_stream & & xine_get_status ( m_stream ) = = XINE_STATUS_PLAY ) {
int cum = 0 ;
int cum = 0 ;
for ( int v = 99 ; v > = 0 ; v - - ) {
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 ) ) ;
int sleep = int ( 32000 * ( - std : : log10 ( double ( v + 1 ) ) + 2 ) ) ;
: : usleep ( sleep ) ;
: : usleep ( sleep ) ;
@ -255,6 +268,7 @@ VideoWindow::load( const KURL &url )
setParameter ( XINE_PARAM_SPU_CHANNEL , - 1 ) ;
setParameter ( XINE_PARAM_SPU_CHANNEL , - 1 ) ;
setParameter ( XINE_PARAM_AUDIO_CHANNEL_LOGICAL , - 1 ) ;
setParameter ( XINE_PARAM_AUDIO_CHANNEL_LOGICAL , - 1 ) ;
setParameter ( XINE_PARAM_VO_ASPECT_RATIO , 0 ) ;
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 ) ;
setParameter ( XINE_PARAM_AUDIO_AMP_LEVEL , 100 ) ;
# undef setParameter
# undef setParameter
@ -445,8 +459,20 @@ VideoWindow::posTimeLength( PosTimeLength type ) const
uint
uint
VideoWindow : : volume ( ) const
VideoWindow : : volume ( ) const
{
{
//TODO I don't like the design
int vol = xine_get_param ( m_stream , XINE_PARAM_AUDIO_AMP_LEVEL ) ;
return 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
void
@ -532,6 +558,13 @@ VideoWindow::seek( uint pos )
xine_set_param ( m_stream , XINE_PARAM_AUDIO_AMP_MUTE , 0 ) ;
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
void
VideoWindow : : setStreamParameter ( int value )
VideoWindow : : setStreamParameter ( int value )
{
{
@ -558,6 +591,10 @@ VideoWindow::setStreamParameter( int value )
{
{
parameter = XINE_PARAM_AUDIO_AMP_LEVEL ;
parameter = XINE_PARAM_AUDIO_AMP_LEVEL ;
value = 100 - value ; // TQt sliders are wrong way round when vertical
value = 100 - value ; // TQt sliders are wrong way round when vertical
if ( s_logarithmicVolume )
{
value = makeVolumeLogarithmic ( value ) ;
}
}
}
else
else
return ;
return ;