1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-08 15:16:34 +02:00

Fixed AudioEngine state machine.

This commit is contained in:
Christian Muehlhaeuser
2015-04-18 08:41:44 +02:00
parent 1e900f87a0
commit dfc07598a1
2 changed files with 25 additions and 44 deletions

View File

@@ -56,13 +56,14 @@ void
AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutput::AudioState oldState ) AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutput::AudioState oldState )
{ {
tDebug() << Q_FUNC_INFO << oldState << newState << q_ptr->state(); tDebug() << Q_FUNC_INFO << oldState << newState << q_ptr->state();
AudioEngine::AudioState previousState = q_ptr->state();
if ( newState == AudioOutput::Loading ) if ( newState == AudioOutput::Loading )
{ {
// We don't emit this state to listeners - yet. // We don't emit this state to listeners - yet.
state = AudioEngine::Loading; state = AudioEngine::Loading;
} }
if ( newState == AudioOutput::Buffering ) else if ( newState == AudioOutput::Buffering )
{ {
if ( underrunCount > UNDERRUNTHRESHOLD && !underrunNotified ) if ( underrunCount > UNDERRUNTHRESHOLD && !underrunNotified )
{ {
@@ -72,14 +73,14 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu
else else
underrunCount++; underrunCount++;
} }
if ( newState == AudioOutput::Error ) else if ( newState == AudioOutput::Error )
{ {
q_ptr->stop( AudioEngine::UnknownError ); q_ptr->setState( AudioEngine::Stopped );
tDebug() << "AudioOutput Error"; tDebug() << Q_FUNC_INFO << "AudioOutput Error";
emit q_ptr->error( AudioEngine::UnknownError ); emit q_ptr->error( AudioEngine::UnknownError );
q_ptr->setState( AudioEngine::Error ); q_ptr->setState( AudioEngine::Error );
} }
if ( newState == AudioOutput::Playing ) else if ( newState == AudioOutput::Playing )
{ {
bool emitSignal = false; bool emitSignal = false;
if ( q_ptr->state() != AudioEngine::Paused && q_ptr->state() != AudioEngine::Playing ) if ( q_ptr->state() != AudioEngine::Paused && q_ptr->state() != AudioEngine::Playing )
@@ -89,47 +90,38 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu
emitSignal = true; emitSignal = true;
} }
q_ptr->setState( AudioEngine::Playing ); q_ptr->setState( AudioEngine::Playing );
audioRetryCounter = 0;
if ( emitSignal ) if ( emitSignal )
emit q_ptr->started( currentTrack ); emit q_ptr->started( currentTrack );
} }
if ( newState == AudioOutput::Stopped && oldState == AudioOutput::Paused ) else if ( newState == AudioOutput::Paused )
{
q_ptr->setState( AudioEngine::Paused );
}
else if ( newState == AudioOutput::Stopped )
{ {
q_ptr->setState( AudioEngine::Stopped ); q_ptr->setState( AudioEngine::Stopped );
} }
if ( oldState == AudioOutput::Playing ) if ( previousState != AudioEngine::Stopped &&
( oldState == AudioOutput::Playing || oldState == AudioOutput::Loading ) )
{ {
bool stopped = false; bool retry = false;
switch ( newState ) if ( newState == AudioOutput::Error )
{ {
case AudioOutput::Paused: retry = ( audioRetryCounter < 2 );
{ audioRetryCounter++;
if ( audioOutput && currentTrack )
{
qint64 duration = audioOutput->totalTime() > 0 ? audioOutput->totalTime() : currentTrack->track()->duration() * 1000;
stopped = ( duration - 1000 < audioOutput->currentTime() );
}
else
stopped = true;
if ( !stopped ) if ( !retry )
q_ptr->setState( AudioEngine::Paused );
break;
}
case AudioOutput::Stopped:
{ {
stopped = true; q_ptr->stop( AudioEngine::UnknownError );
break;
} }
default:
break;
} }
if ( stopped ) if ( newState == AudioOutput::Stopped || retry )
{ {
tDebug() << "Finding next track."; tDebug() << Q_FUNC_INFO << "Finding next track." << oldState << newState;
if ( q_ptr->canGoNext() ) if ( q_ptr->canGoNext() )
{ {
q_ptr->loadNextTrack(); q_ptr->loadNextTrack();
@@ -142,16 +134,6 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu
q_ptr->stop(); q_ptr->stop();
} }
} }
/* This is obsolete, we always expect stop
else if ( stopped )
{
// We did not expect a Stop here, so do not go to the next track
// but change the AudioEngine state
//
// A possible scenario where we can reach this is point if we pause
// an stream that cannot be paused.
q_ptr->setState( AudioEngine::Stopped );
}*/
} }
} }
@@ -212,7 +194,6 @@ AudioEngine::playPause()
return; return;
} }
if ( isPlaying() ) if ( isPlaying() )
pause(); pause();
else else
@@ -285,9 +266,6 @@ AudioEngine::stop( AudioErrorCode errorCode )
tDebug() << Q_FUNC_INFO << errorCode << isStopped(); tDebug() << Q_FUNC_INFO << errorCode << isStopped();
if ( isStopped() )
return;
if ( errorCode == NoError ) if ( errorCode == NoError )
setState( Stopped ); setState( Stopped );
else else
@@ -605,6 +583,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
void void
AudioEngine::onPositionChanged( float new_position ) AudioEngine::onPositionChanged( float new_position )
{ {
// tDebug() << Q_FUNC_INFO << new_position << state();
emit trackPosition( new_position ); emit trackPosition( new_position );
} }

View File

@@ -14,6 +14,7 @@ Q_OBJECT
public: public:
AudioEnginePrivate( AudioEngine* q ) AudioEnginePrivate( AudioEngine* q )
: q_ptr ( q ) : q_ptr ( q )
, audioRetryCounter( 0 )
, underrunCount( 0 ) , underrunCount( 0 )
, underrunNotified( false ) , underrunNotified( false )
{ {
@@ -43,6 +44,7 @@ private:
QQueue< AudioState > stateQueue; QQueue< AudioState > stateQueue;
QTimer stateQueueTimer; QTimer stateQueueTimer;
int audioRetryCounter;
quint8 underrunCount; quint8 underrunCount;
bool underrunNotified; bool underrunNotified;