From cd5b89e4a00326e83a2dd2c84e527eb39bae466e Mon Sep 17 00:00:00 2001 From: Martchus Date: Sat, 14 Oct 2023 21:32:52 +0200 Subject: [PATCH] Avoid crash on startup when MIDI input/output cannot be created * Use RtMidi's error callback * Keep printing warnings/errors to stderr for now (showing the error somewhere in the UI would make much more sense) --- src/MidiDeviceRt.cpp | 39 ++++++++++++++++++++------------------- src/MidiDeviceRt.h | 2 ++ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/MidiDeviceRt.cpp b/src/MidiDeviceRt.cpp index e1a8ccd..796a163 100644 --- a/src/MidiDeviceRt.cpp +++ b/src/MidiDeviceRt.cpp @@ -53,12 +53,14 @@ void CMidiDeviceRt::init() m_rawDataIndex = 0; try { m_midiout = std::make_unique(); - } catch (RtMidiError &error) { + m_midiout->setErrorCallback(handleRtMidiError); + } catch (const RtMidiError &error) { error.printMessage(); } try { m_midiin = std::make_unique(); - } catch (RtMidiError &error) { + m_midiin->setErrorCallback(handleRtMidiError); + } catch (const RtMidiError &error) { error.printMessage(); } } @@ -208,14 +210,7 @@ void CMidiDeviceRt::playMidiEvent(const CMidiEvent & event) return; } - try { - m_midiout->sendMessage( &message ); - } - catch(RtMidiError &error){ - error.printMessage(); - m_validConnection = false; - } - + m_midiout->sendMessage(&message); //event.printDetails(); // useful for debugging } @@ -224,16 +219,9 @@ int CMidiDeviceRt::checkMidiInput() { if (m_midiPorts[0] < 0) return 0; - - try { - m_stamp = m_midiin->getMessage( &m_inputMessage ); - } - catch(RtMidiError &error){ - error.printMessage(); - m_validConnection = false; + m_stamp = m_midiin->getMessage( &m_inputMessage ); + if (!m_validConnection) return 0; - } - return m_inputMessage.size() > std::numeric_limits::max() ? std::numeric_limits::max() : static_cast(m_inputMessage.size()); } @@ -328,3 +316,16 @@ int CMidiDeviceRt::midiSettingsGetInt(const QString &name) Q_UNUSED(name) return 0; } + +void CMidiDeviceRt::handleRtMidiError(RtMidiError::Type type, const std::string &errorText, void *userData) +{ + static_cast(userData)->handleRtMidiError(type, errorText); +} + +void CMidiDeviceRt::handleRtMidiError(RtMidiError::Type type, const std::string &errorText) +{ + std::cerr + << (type == RtMidiError::WARNING || type == RtMidiError::DEBUG_WARNING ? "MIDI warning: " : "MIDI error: ") + << errorText << '\n'; + m_validConnection = false; +} diff --git a/src/MidiDeviceRt.h b/src/MidiDeviceRt.h index e0984cf..9c2864a 100644 --- a/src/MidiDeviceRt.h +++ b/src/MidiDeviceRt.h @@ -34,6 +34,8 @@ class CMidiDeviceRt : public CMidiDeviceBase { virtual void init(); + static void handleRtMidiError(RtMidiError::Type type, const std::string &errorText, void *userData); + void handleRtMidiError(RtMidiError::Type type, const std::string &errorText); //! add a midi event to be played immediately virtual void playMidiEvent(const CMidiEvent &event); virtual int checkMidiInput();