diff --git a/src/framework/audio/driver/platform/win/asio/asioaudiodriver.cpp b/src/framework/audio/driver/platform/win/asio/asioaudiodriver.cpp index 64b18c84ecb2b..ec1620b3f18a2 100644 --- a/src/framework/audio/driver/platform/win/asio/asioaudiodriver.cpp +++ b/src/framework/audio/driver/platform/win/asio/asioaudiodriver.cpp @@ -427,7 +427,12 @@ bool AsioAudioDriver::open(const Spec& spec, Spec* activeSpec) return false; } - const char* name = spec.deviceId.c_str(); + AudioDeviceID deviceId = spec.deviceId; + if (deviceId == DEFAULT_DEVICE_ID) { + deviceId = defaultDevice(); + } + + const char* name = deviceId.c_str(); bool ok = s_adata.drivers->loadDriver(const_cast(name)); if (!ok) { LOGE() << "failed load driver: " << name; diff --git a/src/framework/audio/main/internal/audiodrivercontroller.cpp b/src/framework/audio/main/internal/audiodrivercontroller.cpp index acf4e355cb0c1..a5b052728ce71 100644 --- a/src/framework/audio/main/internal/audiodrivercontroller.cpp +++ b/src/framework/audio/main/internal/audiodrivercontroller.cpp @@ -218,16 +218,17 @@ void AudioDriverController::changeCurrentAudioApi(const std::string& name) IAudioDriverPtr driver = createDriver(name); setNewDriver(driver); m_audioDriver->init(); - LOGI() << "Used " << m_audioDriver->name() << " audio driver"; + LOGI() << "Used audio driver: " << m_audioDriver->name(); // reset to default IAudioDriver::Spec spec = defaultSpec(); spec.callback = m_callback; if (!spec.deviceId.empty()) { + spec.deviceId = DEFAULT_DEVICE_ID; m_audioDriver->open(spec, nullptr); } else { - LOGW() << "no devices for " << name; + LOGW() << "No devices for " << name; } configuration()->setCurrentAudioApi(name); diff --git a/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.cpp b/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.cpp index 8f1e002cc5743..a049711b75ac8 100644 --- a/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.cpp +++ b/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.cpp @@ -22,6 +22,7 @@ #include "audiomidipreferencesmodel.h" +#include "translation.h" #include "log.h" using namespace mu::preferences; @@ -50,6 +51,28 @@ void AudioMidiPreferencesModel::setCurrentAudioApiIndex(int index) return; } + std::string fallbackApi = audioDriverController()->currentAudioApi(); + + audioDriverController()->availableOutputDevicesChanged().onNotify(this, [this, fallbackApi]() { + audioDriverController()->availableOutputDevicesChanged().disconnect(this); + + if (!audioDriverController()->availableOutputDevices().empty()) { + return; + } + + auto promise = interactive()->warning( + muse::trc("preferences", "No audio devices available"), + muse::qtrc("preferences", "The selected audio driver does not have any available audio devices. " + "MuseScore Studio will use the default audio driver instead. " + "To use %1, please check your hardware settings and try again.") + .arg(QString::fromStdString(audioDriverController()->currentAudioApi())).toStdString()); + + promise.onResolve(this, [this, fallbackApi](const muse::IInteractive::Result&) { + audioDriverController()->changeCurrentAudioApi(fallbackApi); + emit currentAudioApiIndexChanged(currentAudioApiIndex()); + }); + }, Asyncable::Mode::SetReplace); + audioDriverController()->changeCurrentAudioApi(apiList.at(index)); emit currentAudioApiIndexChanged(index); } @@ -147,9 +170,11 @@ bool AudioMidiPreferencesModel::onlineSoundsSectionVisible() const QVariantList AudioMidiPreferencesModel::midiInputDevices() const { + std::vector devices = midiInPort()->availableDevices(); + QVariantList result; + result.reserve(devices.size()); - std::vector devices = midiInPort()->availableDevices(); for (const MidiDevice& device : devices) { QVariantMap obj; obj["value"] = QString::fromStdString(device.id); @@ -163,9 +188,11 @@ QVariantList AudioMidiPreferencesModel::midiInputDevices() const QVariantList AudioMidiPreferencesModel::midiOutputDevices() const { + std::vector devices = midiOutPort()->availableDevices(); + QVariantList result; + result.reserve(devices.size()); - std::vector devices = midiOutPort()->availableDevices(); for (const MidiDevice& device : devices) { QVariantMap obj; obj["value"] = QString::fromStdString(device.id); diff --git a/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.h b/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.h index a23123124ea57..b767b917e870d 100644 --- a/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.h +++ b/src/preferences/qml/MuseScore/Preferences/audiomidipreferencesmodel.h @@ -27,12 +27,14 @@ #include "modularity/ioc.h" #include "async/asyncable.h" + #include "audio/main/iaudioconfiguration.h" #include "audio/iaudiodrivercontroller.h" #include "midi/imidiconfiguration.h" #include "midi/imidioutport.h" #include "midi/imidiinport.h" #include "playback/iplaybackconfiguration.h" +#include "global/iinteractive.h" namespace mu::preferences { class AudioMidiPreferencesModel : public QObject, public muse::Contextable, public muse::async::Asyncable @@ -66,6 +68,7 @@ class AudioMidiPreferencesModel : public QObject, public muse::Contextable, publ muse::ContextInject audioDriverController = { this }; muse::ContextInject midiOutPort = { this }; muse::ContextInject midiInPort = { this }; + muse::ContextInject interactive = { this }; public: explicit AudioMidiPreferencesModel(QObject* parent = nullptr); diff --git a/src/preferences/qml/MuseScore/Preferences/internal/AudioApiSection.qml b/src/preferences/qml/MuseScore/Preferences/internal/AudioApiSection.qml index fa4d55483bb02..73cb3d027285e 100644 --- a/src/preferences/qml/MuseScore/Preferences/internal/AudioApiSection.qml +++ b/src/preferences/qml/MuseScore/Preferences/internal/AudioApiSection.qml @@ -39,7 +39,7 @@ BaseSection { ComboBoxWithTitle { id: apiComboBox - title: qsTrc("preferences", "Audio API") + title: qsTrc("preferences", "Audio driver") columnWidth: root.columnWidth visible: root.audioApiList.length > 1