diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index 17ba9e7e6..720356834 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -53,6 +53,14 @@ void AudioThread::shutdown() { quit(); } +void AudioThread::pause() { + m_audioOutput->stop(); +} + +void AudioThread::resume() { + m_audioOutput->start(m_device); +} + void AudioThread::run() { QAudioFormat format; format.setSampleRate(44100); @@ -62,11 +70,11 @@ void AudioThread::run() { format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); - AudioDevice device(m_input); + m_device = new AudioDevice(m_input); m_audioOutput = new QAudioOutput(format); m_audioOutput->setBufferSize(1024); - device.setFormat(m_audioOutput->format()); - m_audioOutput->start(&device); + m_device->setFormat(m_audioOutput->format()); + m_audioOutput->start(m_device); exec(); } diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index 5665c17f0..a4950299b 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -10,25 +10,6 @@ struct GBAThread; namespace QGBA { -class AudioThread : public QThread { -Q_OBJECT - -public: - AudioThread(QObject* parent = nullptr); - - void setInput(GBAThread* input); - -public slots: - void shutdown(); - -protected: - void run(); - -private: - GBAThread* m_input; - QAudioOutput* m_audioOutput; -}; - class AudioDevice : public QIODevice { Q_OBJECT @@ -47,6 +28,28 @@ private: float m_ratio; }; +class AudioThread : public QThread { +Q_OBJECT + +public: + AudioThread(QObject* parent = nullptr); + + void setInput(GBAThread* input); + +public slots: + void shutdown(); + void pause(); + void resume(); + +protected: + void run(); + +private: + GBAThread* m_input; + QAudioOutput* m_audioOutput; + AudioDevice* m_device; +}; + } #endif diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index f189da04c..d56a02ae2 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -18,6 +18,7 @@ GameController::GameController(QObject* parent) m_renderer->outputBuffer = (color_t*) m_drawContext; m_renderer->outputBufferStride = 256; m_threadContext = { + .state = THREAD_INITIALIZED, .debugger = 0, .frameskip = 0, .biosFd = -1, @@ -92,7 +93,7 @@ void GameController::loadGame(const QString& path) { void GameController::closeGame() { // TODO: Make this threadsafe - if (m_threadContext.state >= THREAD_EXITING) { + if (m_threadContext.state >= THREAD_EXITING || m_threadContext.state <= THREAD_INITIALIZED) { return; } GBAThreadEnd(&m_threadContext); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index e0c5919c3..58b7e9a7b 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -12,6 +12,7 @@ using namespace QGBA; Window::Window(QWidget* parent) : QMainWindow(parent) + , m_audioThread(nullptr) #ifdef USE_GDB_STUB , m_gdbController(nullptr) #endif @@ -24,6 +25,7 @@ Window::Window(QWidget* parent) setCentralWidget(m_display); connect(m_controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*))); connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_display, SLOT(stopDrawing())); + connect(m_controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(gameStopped())); connect(this, SIGNAL(startDrawing(const uint32_t*, GBAThread*)), m_display, SLOT(startDrawing(const uint32_t*, GBAThread*)), Qt::QueuedConnection); connect(this, SIGNAL(shutdown()), m_display, SLOT(stopDrawing())); @@ -122,11 +124,21 @@ void Window::gameStarted(GBAThread* context) { foreach (QAction* action, m_gameActions) { action->setDisabled(false); } - AudioThread* thread = new AudioThread(this); - thread->setInput(context); - thread->start(QThread::HighPriority); - connect(this, SIGNAL(shutdown()), thread, SLOT(shutdown())); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), thread, SLOT(shutdown())); + if (!m_audioThread) { + m_audioThread = new AudioThread(this); + connect(this, SIGNAL(shutdown()), m_audioThread, SLOT(shutdown())); + m_audioThread->setInput(context); + m_audioThread->start(QThread::HighPriority); + } else { + m_audioThread->resume(); + } +} + +void Window::gameStopped() { + foreach (QAction* action, m_gameActions) { + action->setDisabled(true); + } + m_audioThread->pause(); } void Window::setupMenu(QMenuBar* menubar) { diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 8e2b2ec9b..958db7b20 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -40,11 +40,13 @@ protected: private slots: void gameStarted(GBAThread*); + void gameStopped(); private: void setupMenu(QMenuBar*); GameController* m_controller; Display* m_display; + AudioThread* m_audioThread; QList m_gameActions; #ifdef USE_GDB_STUB