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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue