mirror of https://github.com/mgba-emu/mgba.git
Run audio on separate thread
This commit is contained in:
parent
baeaf8729f
commit
0ca3afa3e6
|
@ -31,3 +31,19 @@ qint64 AudioDevice::readData(char* data, qint64 maxSize) {
|
||||||
qint64 AudioDevice::writeData(const char*, qint64) {
|
qint64 AudioDevice::writeData(const char*, qint64) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioDevice::Thread::Thread(AudioDevice* device, QObject* parent)
|
||||||
|
: QThread(parent)
|
||||||
|
, m_device(device)
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevice::Thread::setOutput(QAudioOutput* output) {
|
||||||
|
m_audio = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevice::Thread::run() {
|
||||||
|
m_audio->start(m_device);
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
#define QGBA_AUDIO_DEVICE
|
#define QGBA_AUDIO_DEVICE
|
||||||
|
|
||||||
#include <QAudioFormat>
|
#include <QAudioFormat>
|
||||||
|
#include <QAudioOutput>
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
struct GBAAudio;
|
struct GBAAudio;
|
||||||
|
|
||||||
|
@ -16,6 +18,20 @@ public:
|
||||||
|
|
||||||
void setFormat(const QAudioFormat& format);
|
void setFormat(const QAudioFormat& format);
|
||||||
|
|
||||||
|
class Thread : public QThread {
|
||||||
|
public:
|
||||||
|
Thread(AudioDevice* device, QObject* parent = 0);
|
||||||
|
|
||||||
|
void setOutput(QAudioOutput* output);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QAudioOutput* m_audio;
|
||||||
|
AudioDevice* m_device;
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual qint64 readData(char* data, qint64 maxSize);
|
virtual qint64 readData(char* data, qint64 maxSize);
|
||||||
virtual qint64 writeData(const char* data, qint64 maxSize);
|
virtual qint64 writeData(const char* data, qint64 maxSize);
|
||||||
|
|
|
@ -24,7 +24,7 @@ GameController::GameController(QObject* parent)
|
||||||
m_threadContext.sync.audioWait = 1;
|
m_threadContext.sync.audioWait = 1;
|
||||||
m_threadContext.startCallback = [] (GBAThread* context) {
|
m_threadContext.startCallback = [] (GBAThread* context) {
|
||||||
GameController* controller = static_cast<GameController*>(context->userData);
|
GameController* controller = static_cast<GameController*>(context->userData);
|
||||||
controller->setupAudio(&context->gba->audio);
|
controller->audioDeviceAvailable(&context->gba->audio);
|
||||||
};
|
};
|
||||||
m_threadContext.cleanCallback = 0;
|
m_threadContext.cleanCallback = 0;
|
||||||
m_threadContext.frameCallback = [] (GBAThread* context) {
|
m_threadContext.frameCallback = [] (GBAThread* context) {
|
||||||
|
@ -53,12 +53,3 @@ bool GameController::loadGame(const QString& path) {
|
||||||
GBAThreadStart(&m_threadContext);
|
GBAThreadStart(&m_threadContext);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameController::setupAudio(GBAAudio* audio) {
|
|
||||||
if (m_audioContext) {
|
|
||||||
delete m_audioContext;
|
|
||||||
}
|
|
||||||
m_audioContext = new AudioDevice(audio);
|
|
||||||
|
|
||||||
emit audioDeviceAvailable(m_audioContext);
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void frameAvailable(const QImage&);
|
void frameAvailable(const QImage&);
|
||||||
void audioDeviceAvailable(AudioDevice*);
|
void audioDeviceAvailable(GBAAudio*);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool loadGame(const QString& path);
|
bool loadGame(const QString& path);
|
||||||
|
|
|
@ -11,7 +11,7 @@ Window::Window(QWidget* parent) : QMainWindow(parent) {
|
||||||
m_display = new Display(this);
|
m_display = new Display(this);
|
||||||
setCentralWidget(m_display);
|
setCentralWidget(m_display);
|
||||||
connect(m_controller, SIGNAL(frameAvailable(const QImage&)), m_display, SLOT(draw(const QImage&)));
|
connect(m_controller, SIGNAL(frameAvailable(const QImage&)), m_display, SLOT(draw(const QImage&)));
|
||||||
connect(m_controller, SIGNAL(audioDeviceAvailable(AudioDevice*)), this, SLOT(setupAudio(AudioDevice*)));
|
connect(m_controller, SIGNAL(audioDeviceAvailable(GBAAudio*)), this, SLOT(setupAudio(GBAAudio*)));
|
||||||
|
|
||||||
connect(actionOpen, SIGNAL(triggered()), this, SLOT(selectROM()));
|
connect(actionOpen, SIGNAL(triggered()), this, SLOT(selectROM()));
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,9 @@ void Window::selectROM() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setupAudio(AudioDevice* device) {
|
void Window::setupAudio(GBAAudio* audio) {
|
||||||
|
AudioDevice* device = new AudioDevice(audio, this);
|
||||||
|
AudioDevice::Thread* thread = new AudioDevice::Thread(device, this);
|
||||||
if (!m_audio) {
|
if (!m_audio) {
|
||||||
QAudioFormat format;
|
QAudioFormat format;
|
||||||
format.setSampleRate(44100);
|
format.setSampleRate(44100);
|
||||||
|
@ -37,5 +39,6 @@ void Window::setupAudio(AudioDevice* device) {
|
||||||
m_audio->setBufferSize(1024);
|
m_audio->setBufferSize(1024);
|
||||||
}
|
}
|
||||||
device->setFormat(m_audio->format());
|
device->setFormat(m_audio->format());
|
||||||
m_audio->start(device);
|
thread->setOutput(m_audio);
|
||||||
|
thread->start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public slots:
|
||||||
void selectROM();
|
void selectROM();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void setupAudio(AudioDevice*);
|
void setupAudio(GBAAudio*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAudioOutput* m_audio;
|
QAudioOutput* m_audio;
|
||||||
|
|
Loading…
Reference in New Issue