mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 03:10:12 +02:00
* Initial work on phonon-powered AudioEngine.
This commit is contained in:
@@ -7,6 +7,8 @@ ENDIF()
|
|||||||
SET( QT_USE_QTSQL TRUE )
|
SET( QT_USE_QTSQL TRUE )
|
||||||
SET( QT_USE_QTNETWORK TRUE )
|
SET( QT_USE_QTNETWORK TRUE )
|
||||||
SET( QT_USE_QTXML TRUE )
|
SET( QT_USE_QTXML TRUE )
|
||||||
|
SET( QT_USE_PHONON TRUE )
|
||||||
|
|
||||||
INCLUDE( ${QT_USE_FILE} )
|
INCLUDE( ${QT_USE_FILE} )
|
||||||
|
|
||||||
INCLUDE( ${CMAKE_MODULE_PATH}/AddAppIconMacro.cmake )
|
INCLUDE( ${CMAKE_MODULE_PATH}/AddAppIconMacro.cmake )
|
||||||
@@ -27,9 +29,6 @@ SET( TOMAHAWK_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../include/" )
|
|||||||
#ENDFOREACH( moddir )
|
#ENDFOREACH( moddir )
|
||||||
|
|
||||||
SET( tomahawkSources ${tomahawkSources}
|
SET( tomahawkSources ${tomahawkSources}
|
||||||
audio/madtranscode.cpp
|
|
||||||
audio/vorbistranscode.cpp
|
|
||||||
audio/flactranscode.cpp
|
|
||||||
audio/audioengine.cpp
|
audio/audioengine.cpp
|
||||||
|
|
||||||
utils/tomahawkutils.cpp
|
utils/tomahawkutils.cpp
|
||||||
@@ -113,9 +112,6 @@ SET( tomahawkHeaders ${tomahawkHeaders}
|
|||||||
"${TOMAHAWK_INC_DIR}/tomahawk/infosystem.h"
|
"${TOMAHAWK_INC_DIR}/tomahawk/infosystem.h"
|
||||||
|
|
||||||
audio/transcodeinterface.h
|
audio/transcodeinterface.h
|
||||||
audio/madtranscode.h
|
|
||||||
audio/vorbistranscode.h
|
|
||||||
audio/flactranscode.h
|
|
||||||
audio/audioengine.h
|
audio/audioengine.h
|
||||||
|
|
||||||
sip/SipHandler.h
|
sip/SipHandler.h
|
||||||
@@ -215,7 +211,6 @@ INCLUDE_DIRECTORIES(
|
|||||||
utils
|
utils
|
||||||
libtomahawk
|
libtomahawk
|
||||||
|
|
||||||
../rtaudio
|
|
||||||
../alsa-playback
|
../alsa-playback
|
||||||
../qxt/qxtweb-standalone/qxtweb
|
../qxt/qxtweb-standalone/qxtweb
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#include "audioengine.h"
|
#include "audioengine.h"
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QMutexLocker>
|
|
||||||
|
|
||||||
#include "playlistinterface.h"
|
#include "playlistinterface.h"
|
||||||
|
|
||||||
@@ -9,47 +8,36 @@
|
|||||||
#include "database/databasecommand_logplayback.h"
|
#include "database/databasecommand_logplayback.h"
|
||||||
#include "network/servent.h"
|
#include "network/servent.h"
|
||||||
|
|
||||||
#include "madtranscode.h"
|
|
||||||
#ifndef NO_OGG
|
|
||||||
#include "vorbistranscode.h"
|
|
||||||
#endif
|
|
||||||
#ifndef NO_FLAC
|
|
||||||
#include "flactranscode.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
AudioEngine::AudioEngine()
|
AudioEngine::AudioEngine()
|
||||||
: QThread()
|
: QObject()
|
||||||
, m_playlist( 0 )
|
, m_playlist( 0 )
|
||||||
, m_currentTrackPlaylist( 0 )
|
, m_currentTrackPlaylist( 0 )
|
||||||
, m_queue( 0 )
|
, m_queue( 0 )
|
||||||
, m_timeElapsed( 0 )
|
, m_timeElapsed( 0 )
|
||||||
, m_i( 0 )
|
|
||||||
{
|
{
|
||||||
qDebug() << "Init AudioEngine";
|
qDebug() << "Init AudioEngine";
|
||||||
|
|
||||||
moveToThread( this );
|
|
||||||
qRegisterMetaType< AudioErrorCode >("AudioErrorCode");
|
qRegisterMetaType< AudioErrorCode >("AudioErrorCode");
|
||||||
|
|
||||||
#ifdef Q_WS_X11
|
m_mediaObject = new Phonon::MediaObject( this );
|
||||||
m_audio = new AlsaPlayback();
|
m_audioOutput = new Phonon::AudioOutput( Phonon::MusicCategory, this );
|
||||||
#else
|
Phonon::createPath( m_mediaObject, m_audioOutput );
|
||||||
m_audio = new RTAudioOutput();
|
|
||||||
#endif
|
|
||||||
connect( m_audio, SIGNAL( timeElapsed( unsigned int ) ), SLOT( timerTriggered( unsigned int ) ), Qt::DirectConnection );
|
|
||||||
|
|
||||||
start();
|
// connect( m_audio, SIGNAL( timeElapsed( unsigned int ) ), SLOT( timerTriggered( unsigned int ) ), Qt::DirectConnection );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AudioEngine::~AudioEngine()
|
AudioEngine::~AudioEngine()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO << "waiting for event loop to finish...";
|
qDebug() << Q_FUNC_INFO << "waiting for event loop to finish...";
|
||||||
quit();
|
|
||||||
wait( 1000 );
|
m_mediaObject->stop();
|
||||||
|
|
||||||
|
delete m_audioOutput;
|
||||||
|
delete m_mediaObject;
|
||||||
|
|
||||||
m_input.clear();
|
m_input.clear();
|
||||||
delete m_audio;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,10 +46,9 @@ AudioEngine::play()
|
|||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
if ( m_audio->isPaused() )
|
if ( isPaused() )
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &m_mutex );
|
m_mediaObject->play();
|
||||||
m_audio->resume();
|
|
||||||
emit resumed();
|
emit resumed();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -73,9 +60,8 @@ void
|
|||||||
AudioEngine::pause()
|
AudioEngine::pause()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QMutexLocker lock( &m_mutex );
|
|
||||||
|
|
||||||
m_audio->pause();
|
m_mediaObject->pause();
|
||||||
emit paused();
|
emit paused();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +70,8 @@ void
|
|||||||
AudioEngine::stop()
|
AudioEngine::stop()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QMutexLocker lock( &m_mutex );
|
|
||||||
|
m_mediaObject->stop();
|
||||||
|
|
||||||
if ( !m_input.isNull() )
|
if ( !m_input.isNull() )
|
||||||
{
|
{
|
||||||
@@ -92,11 +79,6 @@ AudioEngine::stop()
|
|||||||
m_input.clear();
|
m_input.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !m_transcode.isNull() )
|
|
||||||
m_transcode->clearBuffers();
|
|
||||||
|
|
||||||
m_audio->stopPlayback();
|
|
||||||
|
|
||||||
setCurrentTrack( Tomahawk::result_ptr() );
|
setCurrentTrack( Tomahawk::result_ptr() );
|
||||||
emit stopped();
|
emit stopped();
|
||||||
}
|
}
|
||||||
@@ -106,7 +88,6 @@ void
|
|||||||
AudioEngine::previous()
|
AudioEngine::previous()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
clearBuffers();
|
|
||||||
loadPreviousTrack();
|
loadPreviousTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +96,6 @@ void
|
|||||||
AudioEngine::next()
|
AudioEngine::next()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
clearBuffers();
|
|
||||||
loadNextTrack();
|
loadNextTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +107,7 @@ AudioEngine::setVolume( int percentage )
|
|||||||
|
|
||||||
percentage = qBound( 0, percentage, 100 );
|
percentage = qBound( 0, percentage, 100 );
|
||||||
|
|
||||||
m_audio->setVolume( percentage );
|
m_audioOutput->setVolume( (qreal)percentage / 100.0 );
|
||||||
emit volumeChanged( percentage );
|
emit volumeChanged( percentage );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,9 +129,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
|||||||
qDebug() << Q_FUNC_INFO << thread() << result;
|
qDebug() << Q_FUNC_INFO << thread() << result;
|
||||||
bool err = false;
|
bool err = false;
|
||||||
|
|
||||||
// in a separate scope due to the QMutexLocker!
|
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &m_mutex );
|
|
||||||
QSharedPointer<QIODevice> io;
|
QSharedPointer<QIODevice> io;
|
||||||
|
|
||||||
if ( result.isNull() )
|
if ( result.isNull() )
|
||||||
@@ -181,44 +159,15 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
|||||||
m_input.clear();
|
m_input.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_lastTrack.isNull() || ( m_currentTrack->mimetype() != m_lastTrack->mimetype() ) )
|
m_input = io;
|
||||||
{
|
|
||||||
if ( !m_transcode.isNull() )
|
|
||||||
{
|
|
||||||
m_transcode.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_currentTrack->mimetype() == "audio/mpeg" )
|
m_mediaObject->setCurrentSource( io.data() ) ;
|
||||||
{
|
m_mediaObject->play();
|
||||||
m_transcode = QSharedPointer<TranscodeInterface>(new MADTranscode());
|
|
||||||
}
|
|
||||||
#ifndef NO_OGG
|
|
||||||
else if ( m_currentTrack->mimetype() == "application/ogg" )
|
|
||||||
{
|
|
||||||
m_transcode = QSharedPointer<TranscodeInterface>(new VorbisTranscode());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef NO_FLAC
|
|
||||||
else if ( m_currentTrack->mimetype() == "audio/flac" )
|
|
||||||
{
|
|
||||||
m_transcode = QSharedPointer<TranscodeInterface>(new FLACTranscode());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
qDebug() << "Could NOT find suitable transcoder! Stopping audio.";
|
|
||||||
|
|
||||||
if ( !m_transcode.isNull() )
|
emit started( m_currentTrack );
|
||||||
connect( m_transcode.data(), SIGNAL( streamInitialized( long, int ) ), SLOT( setStreamData( long, int ) ), Qt::DirectConnection );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !m_transcode.isNull() )
|
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started );
|
||||||
{
|
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||||
m_transcode->clearBuffers();
|
|
||||||
m_input = io;
|
|
||||||
|
|
||||||
if ( m_audio->isPaused() )
|
|
||||||
m_audio->resume();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,14 +177,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// needs to be out of the mutexlocker scope
|
return true;
|
||||||
if ( m_transcode.isNull() )
|
|
||||||
{
|
|
||||||
stop();
|
|
||||||
emit error( AudioEngine::DecodeError );
|
|
||||||
}
|
|
||||||
|
|
||||||
return !m_transcode.isNull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -287,8 +229,6 @@ AudioEngine::playItem( PlaylistInterface* playlist, const Tomahawk::result_ptr&
|
|||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
clearBuffers();
|
|
||||||
|
|
||||||
m_playlist = playlist;
|
m_playlist = playlist;
|
||||||
m_currentTrackPlaylist = playlist;
|
m_currentTrackPlaylist = playlist;
|
||||||
|
|
||||||
@@ -296,33 +236,6 @@ AudioEngine::playItem( PlaylistInterface* playlist, const Tomahawk::result_ptr&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AudioEngine::setStreamData( long sampleRate, int channels )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << sampleRate << channels << thread();
|
|
||||||
|
|
||||||
if ( sampleRate < 44100 )
|
|
||||||
sampleRate = 44100;
|
|
||||||
|
|
||||||
m_audio->initAudio( sampleRate, channels );
|
|
||||||
if ( m_audio->startPlayback() )
|
|
||||||
{
|
|
||||||
emit started( m_currentTrack );
|
|
||||||
|
|
||||||
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started );
|
|
||||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << "Can't open device for audio output!";
|
|
||||||
stop();
|
|
||||||
emit error( AudioEngine::AudioDeviceError );
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << sampleRate << channels << "done";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::timerTriggered( unsigned int seconds )
|
AudioEngine::timerTriggered( unsigned int seconds )
|
||||||
{
|
{
|
||||||
@@ -340,14 +253,6 @@ AudioEngine::timerTriggered( unsigned int seconds )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AudioEngine::clearBuffers()
|
|
||||||
{
|
|
||||||
QMutexLocker lock( &m_mutex );
|
|
||||||
m_audio->clearBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
||||||
{
|
{
|
||||||
@@ -362,88 +267,3 @@ AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
|||||||
|
|
||||||
m_currentTrack = result;
|
m_currentTrack = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AudioEngine::run()
|
|
||||||
{
|
|
||||||
QTimer::singleShot( 0, this, SLOT( engineLoop() ) );
|
|
||||||
exec();
|
|
||||||
qDebug() << "AudioEngine event loop stopped";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AudioEngine::engineLoop()
|
|
||||||
{
|
|
||||||
qDebug() << "AudioEngine thread:" << this->thread();
|
|
||||||
loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AudioEngine::loop()
|
|
||||||
{
|
|
||||||
m_i++;
|
|
||||||
//if( m_i % 500 == 0 ) qDebug() << Q_FUNC_INFO << thread();
|
|
||||||
|
|
||||||
{
|
|
||||||
QMutexLocker lock( &m_mutex );
|
|
||||||
|
|
||||||
/* if ( m_i % 200 == 0 )
|
|
||||||
{
|
|
||||||
if ( !m_input.isNull() )
|
|
||||||
qDebug() << "Outer audio loop" << m_input->bytesAvailable() << m_audio->needData();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if ( m_i % 10 == 0 && m_audio->isPlaying() )
|
|
||||||
m_audio->triggerTimers();
|
|
||||||
|
|
||||||
if( !m_transcode.isNull() &&
|
|
||||||
!m_input.isNull() &&
|
|
||||||
m_input->bytesAvailable() &&
|
|
||||||
m_audio->needData() &&
|
|
||||||
!m_audio->isPaused() )
|
|
||||||
{
|
|
||||||
//if ( m_i % 50 == 0 )
|
|
||||||
// qDebug() << "Inner audio loop";
|
|
||||||
|
|
||||||
if ( m_transcode->needData() > 0 )
|
|
||||||
{
|
|
||||||
QByteArray encdata = m_input->read( m_transcode->preferredDataSize() );
|
|
||||||
m_transcode->processData( encdata, m_input->atEnd() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_transcode->haveData() )
|
|
||||||
{
|
|
||||||
QByteArray rawdata = m_transcode->data();
|
|
||||||
m_audio->processData( rawdata );
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer::singleShot( 0, this, SLOT( loop() ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int nextdelay = 50;
|
|
||||||
// are we cleanly at the end of a track, and ready for the next one?
|
|
||||||
if ( !m_input.isNull() &&
|
|
||||||
m_input->atEnd() &&
|
|
||||||
!m_input->bytesAvailable() &&
|
|
||||||
!m_audio->haveData() &&
|
|
||||||
!m_audio->isPaused() )
|
|
||||||
{
|
|
||||||
qDebug() << "Starting next track then";
|
|
||||||
loadNextTrack();
|
|
||||||
// will need data immediately:
|
|
||||||
nextdelay = 0;
|
|
||||||
}
|
|
||||||
else if ( !m_input.isNull() && !m_input->isOpen() )
|
|
||||||
{
|
|
||||||
qDebug() << "AudioEngine IODev closed. errorString:" << m_input->errorString();
|
|
||||||
loadNextTrack();
|
|
||||||
nextdelay = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer::singleShot( nextdelay, this, SLOT( loop() ) );
|
|
||||||
}
|
|
||||||
|
@@ -1,22 +1,21 @@
|
|||||||
#ifndef AUDIOENGINE_H
|
#ifndef AUDIOENGINE_H
|
||||||
#define AUDIOENGINE_H
|
#define AUDIOENGINE_H
|
||||||
|
|
||||||
#include <QThread>
|
#include <QObject>
|
||||||
#include <QMutex>
|
|
||||||
#include <QBuffer>
|
#include <Phonon/MediaObject>
|
||||||
|
#include <Phonon/AudioOutput>
|
||||||
|
|
||||||
#include "result.h"
|
#include "result.h"
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
#include "rtaudiooutput.h"
|
|
||||||
#include "alsaplayback.h"
|
|
||||||
#include "transcodeinterface.h"
|
#include "transcodeinterface.h"
|
||||||
|
|
||||||
#define AUDIO_VOLUME_STEP 5
|
#define AUDIO_VOLUME_STEP 5
|
||||||
|
|
||||||
class PlaylistInterface;
|
class PlaylistInterface;
|
||||||
|
|
||||||
class AudioEngine : public QThread
|
class AudioEngine : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -26,8 +25,8 @@ public:
|
|||||||
explicit AudioEngine();
|
explicit AudioEngine();
|
||||||
~AudioEngine();
|
~AudioEngine();
|
||||||
|
|
||||||
unsigned int volume() const { if ( m_audio ) return m_audio->volume() * 100.0; else return 0; }; // in percent
|
unsigned int volume() const { return m_audioOutput->volume() * 100.0; } // in percent
|
||||||
bool isPaused() const { return m_audio->isPaused(); }
|
bool isPaused() const { return m_mediaObject->state() == Phonon::PausedState; }
|
||||||
|
|
||||||
/* Returns the PlaylistInterface of the currently playing track. Note: This might be different to the current playlist! */
|
/* Returns the PlaylistInterface of the currently playing track. Note: This might be different to the current playlist! */
|
||||||
PlaylistInterface* currentTrackPlaylist() const { return m_currentTrackPlaylist; }
|
PlaylistInterface* currentTrackPlaylist() const { return m_currentTrackPlaylist; }
|
||||||
@@ -74,36 +73,23 @@ private slots:
|
|||||||
void loadPreviousTrack();
|
void loadPreviousTrack();
|
||||||
void loadNextTrack();
|
void loadNextTrack();
|
||||||
|
|
||||||
void setStreamData( long sampleRate, int channels );
|
|
||||||
void timerTriggered( unsigned int seconds );
|
void timerTriggered( unsigned int seconds );
|
||||||
|
|
||||||
void engineLoop();
|
|
||||||
void loop();
|
|
||||||
|
|
||||||
void setCurrentTrack( const Tomahawk::result_ptr& result );
|
void setCurrentTrack( const Tomahawk::result_ptr& result );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run();
|
|
||||||
void clearBuffers();
|
|
||||||
|
|
||||||
QSharedPointer<QIODevice> m_input;
|
QSharedPointer<QIODevice> m_input;
|
||||||
QSharedPointer<TranscodeInterface> m_transcode;
|
|
||||||
|
|
||||||
#ifdef Q_WS_X11
|
|
||||||
AlsaPlayback* m_audio;
|
|
||||||
#else
|
|
||||||
RTAudioOutput* m_audio;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Tomahawk::result_ptr m_currentTrack;
|
Tomahawk::result_ptr m_currentTrack;
|
||||||
Tomahawk::result_ptr m_lastTrack;
|
Tomahawk::result_ptr m_lastTrack;
|
||||||
PlaylistInterface* m_playlist;
|
PlaylistInterface* m_playlist;
|
||||||
PlaylistInterface* m_currentTrackPlaylist;
|
PlaylistInterface* m_currentTrackPlaylist;
|
||||||
PlaylistInterface* m_queue;
|
PlaylistInterface* m_queue;
|
||||||
QMutex m_mutex;
|
|
||||||
|
Phonon::MediaObject* m_mediaObject;
|
||||||
|
Phonon::AudioOutput* m_audioOutput;
|
||||||
|
|
||||||
unsigned int m_timeElapsed;
|
unsigned int m_timeElapsed;
|
||||||
int m_i;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AUDIOENGINE_H
|
#endif // AUDIOENGINE_H
|
||||||
|
Reference in New Issue
Block a user