mirror of https://github.com/mgba-emu/mgba.git
Qt: Runtime configurable audio driver
This commit is contained in:
parent
7cad9ab33a
commit
7f592f78e8
1
CHANGES
1
CHANGES
|
@ -24,6 +24,7 @@ Features:
|
||||||
- Drag and drop game loading
|
- Drag and drop game loading
|
||||||
- Cheat code support
|
- Cheat code support
|
||||||
- Debugger: Add CLI functions for examining memory regions
|
- Debugger: Add CLI functions for examining memory regions
|
||||||
|
- Runtime configurable audio driver
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- ARM7: Extend prefetch by one stage
|
- ARM7: Extend prefetch by one stage
|
||||||
- GBA Audio: Support 16-bit writes to FIFO audio
|
- GBA Audio: Support 16-bit writes to FIFO audio
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
#include "AudioProcessorSDL.h"
|
#include "AudioProcessorSDL.h"
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUILD_QT_MULTIMEDIA
|
||||||
#include "AudioProcessorQt.h"
|
#include "AudioProcessorQt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -17,12 +19,31 @@ extern "C" {
|
||||||
|
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
|
|
||||||
AudioProcessor* AudioProcessor::create() {
|
#ifdef BUILD_QT_MULTIMEDIA
|
||||||
#ifdef BUILD_SDL
|
AudioProcessor::Driver AudioProcessor::s_driver = AudioProcessor::Driver::QT_MULTIMEDIA;
|
||||||
return new AudioProcessorSDL();
|
|
||||||
#else
|
#else
|
||||||
|
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();
|
return new AudioProcessorQt();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
#ifdef BUILD_QT_MULTIMEDIA
|
||||||
|
return new AudioProcessorQt();
|
||||||
|
#else
|
||||||
|
return new AudioProcessorSDL();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioProcessor::AudioProcessor(QObject* parent)
|
AudioProcessor::AudioProcessor(QObject* parent)
|
||||||
|
|
|
@ -15,7 +15,18 @@ class AudioProcessor : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class Driver {
|
||||||
|
#ifdef BUILD_QT_MULTIMEDIA
|
||||||
|
QT_MULTIMEDIA = 0,
|
||||||
|
#endif
|
||||||
|
#ifdef BUILD_SDL
|
||||||
|
SDL = 1,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static AudioProcessor* create();
|
static AudioProcessor* create();
|
||||||
|
static void setDriver(Driver driver) { s_driver = driver; }
|
||||||
|
|
||||||
AudioProcessor(QObject* parent = nullptr);
|
AudioProcessor(QObject* parent = nullptr);
|
||||||
|
|
||||||
virtual void setInput(GBAThread* input);
|
virtual void setInput(GBAThread* input);
|
||||||
|
@ -34,6 +45,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
GBAThread* m_context;
|
GBAThread* m_context;
|
||||||
int m_samples;
|
int m_samples;
|
||||||
|
static Driver s_driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,15 +74,22 @@ qt5_wrap_ui(UI_FILES
|
||||||
|
|
||||||
set(QT_LIBRARIES)
|
set(QT_LIBRARIES)
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5widgets5,libqt5opengl5" PARENT_SCOPE)
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5widgets5,libqt5opengl5" PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(AUDIO_SRC)
|
||||||
if(BUILD_SDL)
|
if(BUILD_SDL)
|
||||||
list(APPEND SOURCE_FILES AudioProcessorSDL.cpp)
|
list(APPEND AUDIO_SRC AudioProcessorSDL.cpp)
|
||||||
elseif(Qt5Multimedia_FOUND)
|
endif()
|
||||||
list(APPEND SOURCE_FILES
|
|
||||||
|
if(Qt5Multimedia_FOUND)
|
||||||
|
list(APPEND AUDIO_SRC
|
||||||
AudioProcessorQt.cpp
|
AudioProcessorQt.cpp
|
||||||
AudioDevice.cpp)
|
AudioDevice.cpp)
|
||||||
list(APPEND QT_LIBRARIES Qt5::Multimedia)
|
list(APPEND QT_LIBRARIES Qt5::Multimedia)
|
||||||
|
add_definitions(-DBUILD_QT_MULTIMEDIA)
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5multimedia5" PARENT_SCOPE)
|
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")
|
message(WARNING "No supported audio modules found")
|
||||||
set(BUILD_QT OFF PARENT_SCOPE)
|
set(BUILD_QT OFF PARENT_SCOPE)
|
||||||
return()
|
return()
|
||||||
|
@ -101,7 +108,7 @@ qt5_add_resources(RESOURCES resources.qrc)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
list(APPEND RESOURCES ${CMAKE_SOURCE_DIR}/res/mgba.rc)
|
list(APPEND RESOURCES ${CMAKE_SOURCE_DIR}/res/mgba.rc)
|
||||||
endif()
|
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)
|
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)
|
list(APPEND QT_LIBRARIES Qt5::Widgets Qt5::OpenGL)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include "GBAApp.h"
|
#include "GBAApp.h"
|
||||||
|
|
||||||
|
#include "AudioProcessor.h"
|
||||||
#include "GameController.h"
|
#include "GameController.h"
|
||||||
|
|
||||||
#include <QFileOpenEvent>
|
#include <QFileOpenEvent>
|
||||||
|
@ -38,6 +39,9 @@ GBAApp::GBAApp(int& argc, char* argv[])
|
||||||
}
|
}
|
||||||
freeArguments(&args);
|
freeArguments(&args);
|
||||||
|
|
||||||
|
AudioProcessor::setDriver(static_cast<AudioProcessor::Driver>(m_configController.getQtOption("audioDriver").toInt()));
|
||||||
|
m_window.controller()->reloadAudioDriver();
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
m_window.show();
|
m_window.show();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -460,6 +460,21 @@ void GameController::clearAVStream() {
|
||||||
threadContinue();
|
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) {
|
void GameController::setLuminanceValue(uint8_t value) {
|
||||||
m_luxValue = value;
|
m_luxValue = value;
|
||||||
value = std::max<int>(value - 0x16, 0);
|
value = std::max<int>(value - 0x16, 0);
|
||||||
|
|
|
@ -106,6 +106,7 @@ public slots:
|
||||||
void setTurbo(bool, bool forced = true);
|
void setTurbo(bool, bool forced = true);
|
||||||
void setAVStream(GBAAVStream*);
|
void setAVStream(GBAAVStream*);
|
||||||
void clearAVStream();
|
void clearAVStream();
|
||||||
|
void reloadAudioDriver();
|
||||||
|
|
||||||
void setLuminanceValue(uint8_t value);
|
void setLuminanceValue(uint8_t value);
|
||||||
void setLuminanceLevel(int level);
|
void setLuminanceLevel(int level);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include "SettingsView.h"
|
#include "SettingsView.h"
|
||||||
|
|
||||||
|
#include "AudioProcessor.h"
|
||||||
#include "ConfigController.h"
|
#include "ConfigController.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
@ -39,6 +40,21 @@ SettingsView::SettingsView(ConfigController* controller, QWidget* parent)
|
||||||
m_ui.idleOptimization->setCurrentIndex(2);
|
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.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios()));
|
||||||
connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig()));
|
connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig()));
|
||||||
}
|
}
|
||||||
|
@ -76,6 +92,13 @@ void SettingsView::updateConfig() {
|
||||||
break;
|
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();
|
m_controller->write();
|
||||||
|
|
||||||
emit biosLoaded(m_ui.bios->text());
|
emit biosLoaded(m_ui.bios->text());
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void biosLoaded(const QString&);
|
void biosLoaded(const QString&);
|
||||||
|
void audioDriverChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void selectBios();
|
void selectBios();
|
||||||
|
|
|
@ -89,25 +89,12 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QComboBox" name="audioDriver">
|
<widget class="QComboBox" name="audioDriver">
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>SDL</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Qt Multimedia</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
|
|
|
@ -219,6 +219,7 @@ void Window::openSettingsWindow() {
|
||||||
SettingsView* settingsWindow = new SettingsView(m_config);
|
SettingsView* settingsWindow = new SettingsView(m_config);
|
||||||
connect(this, SIGNAL(shutdown()), settingsWindow, SLOT(close()));
|
connect(this, SIGNAL(shutdown()), settingsWindow, SLOT(close()));
|
||||||
connect(settingsWindow, SIGNAL(biosLoaded(const QString&)), m_controller, SLOT(loadBIOS(const QString&)));
|
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->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
settingsWindow->show();
|
settingsWindow->show();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue