From 86cd7c1be01f1670255c317fde53e6f50764a9e9 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 22 Feb 2016 00:10:17 +0100 Subject: [PATCH] Fix startup volume for good --- data/sounds/silence.ogg | Bin 0 -> 6122 bytes resources.qrc | 1 + src/libtomahawk/audio/AudioEngine.cpp | 14 +++++- src/libtomahawk/audio/AudioEngine.h | 2 + src/libtomahawk/audio/AudioOutput.cpp | 63 +++++++++++++++++++++++++- src/libtomahawk/audio/AudioOutput.h | 9 ++++ src/libtomahawk/audio/MediaStream.cpp | 8 +++- src/libtomahawk/audio/MediaStream.h | 2 +- 8 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 data/sounds/silence.ogg diff --git a/data/sounds/silence.ogg b/data/sounds/silence.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d7100cc4696a5bc65dff4ead8df11cd9394d1c60 GIT binary patch literal 6122 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 literal 0 HcmV?d00001 diff --git a/resources.qrc b/resources.qrc index 8cc61c536..f839b1952 100644 --- a/resources.qrc +++ b/resources.qrc @@ -170,5 +170,6 @@ data/images/downloadbutton.svg data/images/nav-back.svg data/images/nav-forward.svg + data/sounds/silence.ogg diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index d34d760d8..63fc0a1b0 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -167,6 +167,7 @@ AudioEngine::AudioEngine() d->audioOutput = new AudioOutput( this ); + connect( d->audioOutput, SIGNAL( initialized() ), this, SIGNAL( initialized() ) ); connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d_func(), SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) ); connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) ); connect( d->audioOutput, SIGNAL( positionChanged( float ) ), SLOT( onPositionChanged( float ) ) ); @@ -289,8 +290,11 @@ AudioEngine::stop( AudioErrorCode errorCode ) if ( d->waitingOnNewTrack ) sendWaitingNotification(); - Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag ); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); + if ( d->audioOutput->isInitialized() ) + { + Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData ); + } } @@ -566,6 +570,12 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) Q_D( AudioEngine ); tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); + + if ( !d->audioOutput->isInitialized() ) + { + return; + } + if ( !result ) { stop(); diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index bc129c383..403ccb2a4 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -149,6 +149,8 @@ public slots: void setShuffled( bool enabled ); signals: + void initialized(); + void loading( const Tomahawk::result_ptr track ); void started( const Tomahawk::result_ptr track ); void finished( const Tomahawk::result_ptr track ); diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 48dbd00fd..c431ddbc8 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -25,11 +25,13 @@ #include "audio/MediaStream.h" #include "utils/Logger.h" +#include "utils/TomahawkUtils.h" #include #include #include #include +#include #include #include @@ -58,6 +60,7 @@ AudioOutput::AudioOutput( QObject* parent ) , m_currentTime( 0 ) , m_totalTime( 0 ) , m_justSeeked( false ) + , m_initialized( false ) , dspPluginCallback( nullptr ) , m_vlcInstance( nullptr ) , m_vlcPlayer( nullptr ) @@ -129,7 +132,28 @@ AudioOutput::AudioOutput( QObject* parent ) } m_muted = isMuted(); - tDebug() << Q_FUNC_INFO << "Init OK"; + + // HACK: play silent ogg file and set volume on that to workaround vlc not allowing to set volume before a file is played + libvlc_media_player_set_media( m_vlcPlayer, m_vlcMedia ); + libvlc_media_player_play( m_vlcPlayer ); + + m_silenceFile.setFileName( RESPATH "sounds/silence.ogg" ); + Q_ASSERT( m_silenceFile.exists() ); + Q_ASSERT( m_silenceFile.open( QIODevice::ReadOnly ) ); + + setCurrentSource( new MediaStream( &m_silenceFile, true ) ); + libvlc_media_player_play( m_vlcPlayer ); + + #if QT_VERSION >= QT_VERSION_CHECK(5,4,0) + // if the silence file did not play for 15 secs, we pretend the AudioOutput is initialized, to allow proper error reporting + QTimer::singleShot( 15000, [&]() + { + if ( !m_initialized ) { + m_initialized = true; + emit initialized(); + } + } ); + #endif } @@ -155,6 +179,27 @@ AudioOutput::~AudioOutput() } +void +AudioOutput::onInitVlcEvent( const libvlc_event_t* event ) +{ + switch ( event->type ) + { + case libvlc_MediaPlayerTimeChanged: + setVolume( volume() ); + + m_initialized = true; + m_silenceFile.close(); + + tDebug() << Q_FUNC_INFO << "Init OK"; + emit initialized(); + break; + + default: + break; + } +} + + void AudioOutput::setAutoDelete( bool ad ) { @@ -303,6 +348,13 @@ AudioOutput::setCurrentSource( MediaStream* stream ) } +bool +AudioOutput::isInitialized() const +{ + return m_initialized; +} + + AudioOutput::AudioState AudioOutput::state() const { @@ -555,7 +607,14 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) AudioOutput* that = reinterpret_cast < AudioOutput * > ( opaque ); Q_ASSERT( that ); - that->onVlcEvent( event ); + if ( !that->isInitialized() ) + { + that->onInitVlcEvent( event ); + } + else + { + that->onVlcEvent( event ); + } } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 504cb6cfb..ee03b7d71 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -25,6 +25,8 @@ #include "DllMacro.h" #include "Typedefs.h" +#include + #include struct libvlc_instance_t; @@ -44,6 +46,7 @@ public: explicit AudioOutput( QObject* parent = nullptr ); ~AudioOutput(); + bool isInitialized() const; AudioState state() const; void setCurrentSource( const QUrl& stream ); @@ -72,11 +75,14 @@ public: public slots: signals: + void initialized(); void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ); void tick( qint64 ); void positionChanged( float ); private: + void onInitVlcEvent( const libvlc_event_t* event ); + void setState( AudioState state ); void setCurrentTime( qint64 time ); void setCurrentPosition( float position ); @@ -99,6 +105,9 @@ private: qint64 m_totalTime; bool m_justSeeked; + bool m_initialized; + QFile m_silenceFile; + std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback; libvlc_instance_t* m_vlcInstance; diff --git a/src/libtomahawk/audio/MediaStream.cpp b/src/libtomahawk/audio/MediaStream.cpp index 955c3be9f..97503bcc1 100644 --- a/src/libtomahawk/audio/MediaStream.cpp +++ b/src/libtomahawk/audio/MediaStream.cpp @@ -41,12 +41,16 @@ MediaStream::MediaStream( const QUrl &url ) } -MediaStream::MediaStream( QIODevice* device ) +MediaStream::MediaStream( QIODevice* device, bool bufferingFinished ) : QObject( nullptr ) , m_type( IODevice ) , m_ioDevice ( device ) + , m_bufferingFinished( bufferingFinished ) { - QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) ); + if ( !bufferingFinished ) + { + QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) ); + } } diff --git a/src/libtomahawk/audio/MediaStream.h b/src/libtomahawk/audio/MediaStream.h index 831e70a57..379f7eaa4 100644 --- a/src/libtomahawk/audio/MediaStream.h +++ b/src/libtomahawk/audio/MediaStream.h @@ -42,7 +42,7 @@ public: MediaStream( QObject* parent = nullptr ); explicit MediaStream( const QUrl &url ); - explicit MediaStream( QIODevice* device ); + explicit MediaStream( QIODevice* device, bool bufferingFinished = false ); virtual ~MediaStream(); MediaType type() const;