mirror of https://github.com/mgba-emu/mgba.git
Reuse an audio thread instead of shutting it down and making a new one
This commit is contained in:
parent
186e0b1ee5
commit
6d12ef81a5
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue