Qt: Runtime configurable audio driver

This commit is contained in:
Jeffrey Pfau 2015-02-21 01:54:50 -08:00
parent 7cad9ab33a
commit 7f592f78e8
12 changed files with 98 additions and 25 deletions

View File

@ -24,6 +24,7 @@ Features:
- Drag and drop game loading
- Cheat code support
- Debugger: Add CLI functions for examining memory regions
- Runtime configurable audio driver
Bugfixes:
- ARM7: Extend prefetch by one stage
- GBA Audio: Support 16-bit writes to FIFO audio

View File

@ -7,7 +7,9 @@
#ifdef BUILD_SDL
#include "AudioProcessorSDL.h"
#else
#endif
#ifdef BUILD_QT_MULTIMEDIA
#include "AudioProcessorQt.h"
#endif
@ -17,12 +19,31 @@ extern "C" {
using namespace QGBA;
AudioProcessor* AudioProcessor::create() {
#ifdef BUILD_SDL
return new AudioProcessorSDL();
#ifdef BUILD_QT_MULTIMEDIA
AudioProcessor::Driver AudioProcessor::s_driver = AudioProcessor::Driver::QT_MULTIMEDIA;
#else
return new AudioProcessorQt();
#endif
AudioProcessor::Driver AudioProcessor::s_driver = AudioProcessor::Driver::SDL;
#endif
AudioProcessor* AudioProcessor::create() {
switch (s_driver) {
#ifdef BUILD_SDL
case Driver::SDL:
return new AudioProcessorSDL();
#endif
#ifdef BUILD_QT_MULTIMEDIA
case Driver::QT_MULTIMEDIA:
return new AudioProcessorQt();
#endif
default:
#ifdef BUILD_QT_MULTIMEDIA
return new AudioProcessorQt();
#else
return new AudioProcessorSDL();
#endif
}
}
AudioProcessor::AudioProcessor(QObject* parent)

View File

@ -15,7 +15,18 @@ class AudioProcessor : public QObject {
Q_OBJECT
public:
enum class Driver {
#ifdef BUILD_QT_MULTIMEDIA
QT_MULTIMEDIA = 0,
#endif
#ifdef BUILD_SDL
SDL = 1,
#endif
};
static AudioProcessor* create();
static void setDriver(Driver driver) { s_driver = driver; }
AudioProcessor(QObject* parent = nullptr);
virtual void setInput(GBAThread* input);
@ -34,6 +45,7 @@ protected:
private:
GBAThread* m_context;
int m_samples;
static Driver s_driver;
};
}

View File

@ -7,7 +7,7 @@
#define QGBA_AUDIO_PROCESSOR_QT
#include "AudioProcessor.h"
class QAudioOutput;
class QAudioOutput;
namespace QGBA {

View File

@ -74,15 +74,22 @@ qt5_wrap_ui(UI_FILES
set(QT_LIBRARIES)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5widgets5,libqt5opengl5" PARENT_SCOPE)
set(AUDIO_SRC)
if(BUILD_SDL)
list(APPEND SOURCE_FILES AudioProcessorSDL.cpp)
elseif(Qt5Multimedia_FOUND)
list(APPEND SOURCE_FILES
list(APPEND AUDIO_SRC AudioProcessorSDL.cpp)
endif()
if(Qt5Multimedia_FOUND)
list(APPEND AUDIO_SRC
AudioProcessorQt.cpp
AudioDevice.cpp)
list(APPEND QT_LIBRARIES Qt5::Multimedia)
add_definitions(-DBUILD_QT_MULTIMEDIA)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5multimedia5" PARENT_SCOPE)
else()
endif()
if(NOT AUDIO_SRC)
message(WARNING "No supported audio modules found")
set(BUILD_QT OFF PARENT_SCOPE)
return()
@ -101,7 +108,7 @@ qt5_add_resources(RESOURCES resources.qrc)
if(WIN32)
list(APPEND RESOURCES ${CMAKE_SOURCE_DIR}/res/mgba.rc)
endif()
add_executable(${BINARY_NAME}-qt WIN32 MACOSX_BUNDLE main.cpp ${CMAKE_SOURCE_DIR}/res/mgba.icns ${SOURCE_FILES} ${PLATFORM_SRC} ${UI_FILES} ${RESOURCES})
add_executable(${BINARY_NAME}-qt WIN32 MACOSX_BUNDLE main.cpp ${CMAKE_SOURCE_DIR}/res/mgba.icns ${SOURCE_FILES} ${PLATFORM_SRC} ${UI_FILES} ${AUDIO_SRC} ${RESOURCES})
set_target_properties(${BINARY_NAME}-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/res/info.plist.in)
list(APPEND QT_LIBRARIES Qt5::Widgets Qt5::OpenGL)

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GBAApp.h"
#include "AudioProcessor.h"
#include "GameController.h"
#include <QFileOpenEvent>
@ -38,6 +39,9 @@ GBAApp::GBAApp(int& argc, char* argv[])
}
freeArguments(&args);
AudioProcessor::setDriver(static_cast<AudioProcessor::Driver>(m_configController.getQtOption("audioDriver").toInt()));
m_window.controller()->reloadAudioDriver();
#ifdef Q_OS_MAC
m_window.show();
#endif

View File

@ -460,6 +460,21 @@ void GameController::clearAVStream() {
threadContinue();
}
void GameController::reloadAudioDriver() {
m_audioProcessor->pause();
delete m_audioProcessor;
m_audioProcessor = AudioProcessor::create();
m_audioProcessor->moveToThread(m_audioThread);
connect(this, SIGNAL(gameStarted(GBAThread*)), m_audioProcessor, SLOT(start()));
connect(this, SIGNAL(gameStopped(GBAThread*)), m_audioProcessor, SLOT(pause()));
connect(this, SIGNAL(gamePaused(GBAThread*)), m_audioProcessor, SLOT(pause()));
connect(this, SIGNAL(gameUnpaused(GBAThread*)), m_audioProcessor, SLOT(start()));
if (isLoaded()) {
m_audioProcessor->setInput(&m_threadContext);
QMetaObject::invokeMethod(m_audioProcessor, "start");
}
}
void GameController::setLuminanceValue(uint8_t value) {
m_luxValue = value;
value = std::max<int>(value - 0x16, 0);

View File

@ -106,6 +106,7 @@ public slots:
void setTurbo(bool, bool forced = true);
void setAVStream(GBAAVStream*);
void clearAVStream();
void reloadAudioDriver();
void setLuminanceValue(uint8_t value);
void setLuminanceLevel(int level);

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SettingsView.h"
#include "AudioProcessor.h"
#include "ConfigController.h"
#include <QFileDialog>
@ -39,6 +40,21 @@ SettingsView::SettingsView(ConfigController* controller, QWidget* parent)
m_ui.idleOptimization->setCurrentIndex(2);
}
int audioDriver = m_controller->getQtOption("audioDriver").toInt();
#ifdef BUILD_QT_MULTIMEDIA
m_ui.audioDriver->addItem(tr("Qt Multimedia"), static_cast<int>(AudioProcessor::Driver::QT_MULTIMEDIA));
if (audioDriver == static_cast<int>(AudioProcessor::Driver::QT_MULTIMEDIA)) {
m_ui.audioDriver->setCurrentIndex(m_ui.audioDriver->count() - 1);
}
#endif
#ifdef BUILD_SDL
m_ui.audioDriver->addItem(tr("SDL"), static_cast<int>(AudioProcessor::Driver::SDL));
if (audioDriver == static_cast<int>(AudioProcessor::Driver::SDL)) {
m_ui.audioDriver->setCurrentIndex(m_ui.audioDriver->count() - 1);
}
#endif
connect(m_ui.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios()));
connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig()));
}
@ -76,6 +92,13 @@ void SettingsView::updateConfig() {
break;
}
QVariant audioDriver = m_ui.audioDriver->itemData(m_ui.audioDriver->currentIndex());
if (audioDriver != m_controller->getQtOption("audioDriver")) {
m_controller->setQtOption("audioDriver", audioDriver);
AudioProcessor::setDriver(static_cast<AudioProcessor::Driver>(audioDriver.toInt()));
emit audioDriverChanged();
}
m_controller->write();
emit biosLoaded(m_ui.bios->text());

View File

@ -22,6 +22,7 @@ public:
signals:
void biosLoaded(const QString&);
void audioDriverChanged();
private slots:
void selectBios();

View File

@ -89,25 +89,12 @@
</item>
<item row="4" column="1">
<widget class="QComboBox" name="audioDriver">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>SDL</string>
</property>
</item>
<item>
<property name="text">
<string>Qt Multimedia</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">

View File

@ -219,6 +219,7 @@ void Window::openSettingsWindow() {
SettingsView* settingsWindow = new SettingsView(m_config);
connect(this, SIGNAL(shutdown()), settingsWindow, SLOT(close()));
connect(settingsWindow, SIGNAL(biosLoaded(const QString&)), m_controller, SLOT(loadBIOS(const QString&)));
connect(settingsWindow, SIGNAL(audioDriverChanged()), m_controller, SLOT(reloadAudioDriver()));
settingsWindow->setAttribute(Qt::WA_DeleteOnClose);
settingsWindow->show();
}