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();
}
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();
}

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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<QAction*> m_gameActions;
#ifdef USE_GDB_STUB