Initialize rtmidi async

On my system this opening the settings takes 10 seconds on a cold boot.
Letting it initialize async during boot reduces this delay drastically.
This commit is contained in:
Megamouse
2026-06-04 23:17:08 +02:00
committed by Ani
parent bf85a3fdd9
commit 8112c7cc19
9 changed files with 82 additions and 25 deletions
+4 -1
View File
@@ -412,7 +412,10 @@ usb_device_rb3_midi_drums::usb_device_rb3_midi_drums(const std::array<u8, 7>& lo
usb_device_rb3_midi_drums::~usb_device_rb3_midi_drums()
{
rtmidi_in_free(midi_in);
if (midi_in)
{
rtmidi_in_free(midi_in);
}
}
static const std::array<u8, 40> disabled_response = {
+4 -1
View File
@@ -100,7 +100,10 @@ usb_device_rb3_midi_guitar::usb_device_rb3_midi_guitar(const std::array<u8, 7>&
usb_device_rb3_midi_guitar::~usb_device_rb3_midi_guitar()
{
rtmidi_in_free(midi_in);
if (midi_in)
{
rtmidi_in_free(midi_in);
}
}
static const std::array<u8, 40> disabled_response = {
+4 -1
View File
@@ -86,7 +86,10 @@ usb_device_rb3_midi_keyboard::usb_device_rb3_midi_keyboard(const std::array<u8,
usb_device_rb3_midi_keyboard::~usb_device_rb3_midi_keyboard()
{
rtmidi_in_free(midi_in);
if (midi_in)
{
rtmidi_in_free(midi_in);
}
}
static const std::array<u8, 40> disabled_response = {
+2 -2
View File
@@ -302,7 +302,7 @@ bool config_checker::check_config(cfg_mode mode, QString content_or_serial, QStr
const std::array<midi_device, max_midi_devices> def_devices = mc.get_selection_list();
mc.parse_devices(val);
const std::array<midi_device, max_midi_devices> devices = mc.get_selection_list();
const std::array<midi_device, max_midi_devices>& devices = mc.get_selection_list();
for (usz i = 0; i < devices.size(); i++)
{
@@ -327,7 +327,7 @@ bool config_checker::check_config(cfg_mode mode, QString content_or_serial, QStr
const std::array<std::string, 4> def_devices = mc.get_selection_list();
mc.parse_devices(val);
const std::array<std::string, 4> devices = mc.get_selection_list();
const std::array<std::string, 4>& devices = mc.get_selection_list();
for (usz i = 0; i < devices.size(); i++)
{
+3 -3
View File
@@ -14,7 +14,7 @@ microphone_creator::microphone_creator()
}
// We need to recreate the localized string because the microphone creator is currently only created once.
QString microphone_creator::get_none()
QString microphone_creator::get_none() const
{
return tr("None", "Microphone device");
}
@@ -49,12 +49,12 @@ void microphone_creator::refresh_list()
}
}
QStringList microphone_creator::get_microphone_list() const
const QStringList& microphone_creator::get_microphone_list() const
{
return m_microphone_list;
}
std::array<std::string, 4> microphone_creator::get_selection_list() const
const std::array<std::string, 4>& microphone_creator::get_selection_list() const
{
return m_sel_list;
}
+3 -3
View File
@@ -15,12 +15,12 @@ class microphone_creator : public QObject
public:
microphone_creator();
QString get_none();
QString get_none() const;
std::string set_device(u32 num, const QString& text);
void parse_devices(std::string_view list);
void refresh_list();
QStringList get_microphone_list() const;
std::array<std::string, 4> get_selection_list() const;
const QStringList& get_microphone_list() const;
const std::array<std::string, 4>& get_selection_list() const;
private:
QStringList m_microphone_list;
+38 -5
View File
@@ -8,24 +8,57 @@
LOG_CHANNEL(cfg_log, "CFG");
const auto midi_deleter = [](RtMidiWrapper* ptr) { if (ptr) rtmidi_in_free(ptr); };
using midi_ptr = std::unique_ptr<RtMidiWrapper, decltype(midi_deleter)>;
std::mutex midi_creator::m_midi_init_mutex = {};
std::unique_ptr<std::thread> midi_creator::m_midi_init_thread = {};
midi_creator::midi_creator()
{
setObjectName("midi_creator");
// Initialize rtmidi async. This can take 10+ seconds on a cold start.
std::lock_guard lock(m_midi_init_mutex);
if (!m_midi_init_thread)
{
m_midi_init_thread = std::make_unique<std::thread>([]
{
[[maybe_unused]] midi_ptr midi_in(rtmidi_in_create_default());
});
}
}
midi_creator::~midi_creator()
{
std::lock_guard lock(m_midi_init_mutex);
if (m_midi_init_thread && m_midi_init_thread->joinable())
{
m_midi_init_thread->join();
}
}
// We need to recreate the localized string because the midi creator is currently only created once.
QString midi_creator::get_none()
QString midi_creator::get_none() const
{
return tr("None", "MIDI device");
}
void midi_creator::refresh_list()
{
// Wait for initial initialization
{
std::lock_guard lock(m_midi_init_mutex);
if (m_midi_init_thread && m_midi_init_thread->joinable())
{
m_midi_init_thread->join();
}
}
m_midi_list.clear();
m_midi_list.append(get_none());
const auto deleter = [](RtMidiWrapper* ptr) { if (ptr) rtmidi_in_free(ptr); };
std::unique_ptr<RtMidiWrapper, decltype(deleter)> midi_in(rtmidi_in_create_default());
midi_ptr midi_in(rtmidi_in_create_default());
ensure(midi_in);
if (!midi_in->ok)
@@ -74,12 +107,12 @@ void midi_creator::refresh_list()
}
}
QStringList midi_creator::get_midi_list() const
const QStringList& midi_creator::get_midi_list() const
{
return m_midi_list;
}
std::array<midi_device, max_midi_devices> midi_creator::get_selection_list() const
const std::array<midi_device, max_midi_devices>& midi_creator::get_selection_list() const
{
return m_sel_list;
}
+10 -3
View File
@@ -3,6 +3,9 @@
#include "util/types.hpp"
#include "Emu/Io/midi_config_types.h"
#include <mutex>
#include <thread>
#include <QObject>
#include <QStringList>
@@ -12,14 +15,18 @@ class midi_creator : public QObject
public:
midi_creator();
QString get_none();
virtual ~midi_creator();
QString get_none() const;
std::string set_device(u32 num, const midi_device& device);
void parse_devices(std::string_view list);
void refresh_list();
QStringList get_midi_list() const;
std::array<midi_device, max_midi_devices> get_selection_list() const;
const QStringList& get_midi_list() const;
const std::array<midi_device, max_midi_devices>& get_selection_list() const;
private:
static std::mutex m_midi_init_mutex;
static std::unique_ptr<std::thread> m_midi_init_thread;
QStringList m_midi_list;
std::array<midi_device, max_midi_devices> m_sel_list;
};
+14 -6
View File
@@ -933,8 +933,11 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
QStringList cur_list = m_emu_settings->m_microphone_creator.get_microphone_list();
for (u32 subindex = 0; subindex < m_mics_combo.size(); subindex++)
{
if (subindex != index && m_mics_combo[subindex]->currentText() != mic_none)
cur_list.removeOne(m_mics_combo[subindex]->currentText());
if (subindex == index) continue;
if (const QString text = m_mics_combo[subindex]->currentText(); text != mic_none)
{
cur_list.removeOne(text);
}
}
m_mics_combo[index]->blockSignals(true);
m_mics_combo[index]->clear();
@@ -949,7 +952,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
{
m_emu_settings->SetSetting(emu_settings_type::MicrophoneDevices, m_emu_settings->m_microphone_creator.set_device(index, text));
if (const u32 next_index = index + 1; next_index < m_mics_combo.size() && text == mic_none)
{
m_mics_combo[next_index]->setCurrentText(mic_none);
}
propagate_used_devices();
};
@@ -1102,7 +1107,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
m_emu_settings->m_microphone_creator.parse_devices(m_emu_settings->GetSetting(emu_settings_type::MicrophoneDevices));
const std::array<std::string, 4> mic_sel_list = m_emu_settings->m_microphone_creator.get_selection_list();
const std::array<std::string, 4>& mic_sel_list = m_emu_settings->m_microphone_creator.get_selection_list();
for (s32 index = static_cast<int>(mic_sel_list.size()) - 1; index >= 0; index--)
{
@@ -1276,8 +1281,11 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
QStringList cur_list = m_emu_settings->m_midi_creator.get_midi_list();
for (u32 subindex = 0; subindex < m_midi_device_combo.size(); subindex++)
{
if (subindex != index && m_midi_device_combo[subindex]->currentText() != midi_none)
cur_list.removeOne(m_midi_device_combo[subindex]->currentText());
if (subindex == index) continue;
if (const QString text = m_midi_device_combo[subindex]->currentText(); text != midi_none)
{
cur_list.removeOne(text);
}
}
m_midi_device_combo[index]->blockSignals(true);
m_midi_device_combo[index]->clear();
@@ -1326,7 +1334,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
m_emu_settings->m_midi_creator.parse_devices(m_emu_settings->GetSetting(emu_settings_type::MidiDevices));
const std::array<midi_device, max_midi_devices> midi_sel_list = m_emu_settings->m_midi_creator.get_selection_list();
const std::array<midi_device, max_midi_devices>& midi_sel_list = m_emu_settings->m_midi_creator.get_selection_list();
for (s32 index = static_cast<int>(midi_sel_list.size()) - 1; index >= 0; index--)
{