Reuse an audio thread instead of shutting it down and making a new one

This commit is contained in:
Jeffrey Pfau 2014-02-03 01:13:52 -08:00
parent 186e0b1ee5
commit 6d12ef81a5
5 changed files with 54 additions and 28 deletions

View File

@ -53,6 +53,14 @@ void AudioThread::shutdown() {
quit(); quit();
} }
void AudioThread::pause() {
m_audioOutput->stop();
}
void AudioThread::resume() {
m_audioOutput->start(m_device);
}
void AudioThread::run() { void AudioThread::run() {
QAudioFormat format; QAudioFormat format;
format.setSampleRate(44100); format.setSampleRate(44100);
@ -62,11 +70,11 @@ void AudioThread::run() {
format.setByteOrder(QAudioFormat::LittleEndian); format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt); format.setSampleType(QAudioFormat::SignedInt);
AudioDevice device(m_input); m_device = new AudioDevice(m_input);
m_audioOutput = new QAudioOutput(format); m_audioOutput = new QAudioOutput(format);
m_audioOutput->setBufferSize(1024); m_audioOutput->setBufferSize(1024);
device.setFormat(m_audioOutput->format()); m_device->setFormat(m_audioOutput->format());
m_audioOutput->start(&device); m_audioOutput->start(m_device);
exec(); exec();
} }

View File

@ -10,25 +10,6 @@ struct GBAThread;
namespace QGBA { 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 { class AudioDevice : public QIODevice {
Q_OBJECT Q_OBJECT
@ -47,6 +28,28 @@ private:
float m_ratio; 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 #endif

View File

@ -18,6 +18,7 @@ GameController::GameController(QObject* parent)
m_renderer->outputBuffer = (color_t*) m_drawContext; m_renderer->outputBuffer = (color_t*) m_drawContext;
m_renderer->outputBufferStride = 256; m_renderer->outputBufferStride = 256;
m_threadContext = { m_threadContext = {
.state = THREAD_INITIALIZED,
.debugger = 0, .debugger = 0,
.frameskip = 0, .frameskip = 0,
.biosFd = -1, .biosFd = -1,
@ -92,7 +93,7 @@ void GameController::loadGame(const QString& path) {
void GameController::closeGame() { void GameController::closeGame() {
// TODO: Make this threadsafe // TODO: Make this threadsafe
if (m_threadContext.state >= THREAD_EXITING) { if (m_threadContext.state >= THREAD_EXITING || m_threadContext.state <= THREAD_INITIALIZED) {
return; return;
} }
GBAThreadEnd(&m_threadContext); GBAThreadEnd(&m_threadContext);

View File

@ -12,6 +12,7 @@ using namespace QGBA;
Window::Window(QWidget* parent) Window::Window(QWidget* parent)
: QMainWindow(parent) : QMainWindow(parent)
, m_audioThread(nullptr)
#ifdef USE_GDB_STUB #ifdef USE_GDB_STUB
, m_gdbController(nullptr) , m_gdbController(nullptr)
#endif #endif
@ -24,6 +25,7 @@ Window::Window(QWidget* parent)
setCentralWidget(m_display); setCentralWidget(m_display);
connect(m_controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*))); 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*)), 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(startDrawing(const uint32_t*, GBAThread*)), m_display, SLOT(startDrawing(const uint32_t*, GBAThread*)), Qt::QueuedConnection);
connect(this, SIGNAL(shutdown()), m_display, SLOT(stopDrawing())); connect(this, SIGNAL(shutdown()), m_display, SLOT(stopDrawing()));
@ -122,11 +124,21 @@ void Window::gameStarted(GBAThread* context) {
foreach (QAction* action, m_gameActions) { foreach (QAction* action, m_gameActions) {
action->setDisabled(false); action->setDisabled(false);
} }
AudioThread* thread = new AudioThread(this); if (!m_audioThread) {
thread->setInput(context); m_audioThread = new AudioThread(this);
thread->start(QThread::HighPriority); connect(this, SIGNAL(shutdown()), m_audioThread, SLOT(shutdown()));
connect(this, SIGNAL(shutdown()), thread, SLOT(shutdown())); m_audioThread->setInput(context);
connect(m_controller, SIGNAL(gameStopped(GBAThread*)), thread, SLOT(shutdown())); 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) { void Window::setupMenu(QMenuBar* menubar) {

View File

@ -40,11 +40,13 @@ protected:
private slots: private slots:
void gameStarted(GBAThread*); void gameStarted(GBAThread*);
void gameStopped();
private: private:
void setupMenu(QMenuBar*); void setupMenu(QMenuBar*);
GameController* m_controller; GameController* m_controller;
Display* m_display; Display* m_display;
AudioThread* m_audioThread;
QList<QAction*> m_gameActions; QList<QAction*> m_gameActions;
#ifdef USE_GDB_STUB #ifdef USE_GDB_STUB