diff --git a/src/MIDI_Interfaces/DebugMIDI_Interface.hpp b/src/MIDI_Interfaces/DebugMIDI_Interface.hpp index 951aafd049..b84a9088cc 100644 --- a/src/MIDI_Interfaces/DebugMIDI_Interface.hpp +++ b/src/MIDI_Interfaces/DebugMIDI_Interface.hpp @@ -224,6 +224,9 @@ class StreamDebugMIDI_Interface : public PrintDebugMIDI_Base, private: #if !DISABLE_PIPES void handleStall() override { MIDI_Interface::handleStall(this); } +#ifdef DEBUG_OUT + const char *getName() const override { return "dbg"; } +#endif #endif private: diff --git a/src/MIDI_Interfaces/GenericBLEMIDI_Interface.hpp b/src/MIDI_Interfaces/GenericBLEMIDI_Interface.hpp index e981e8af73..31ea604a9e 100644 --- a/src/MIDI_Interfaces/GenericBLEMIDI_Interface.hpp +++ b/src/MIDI_Interfaces/GenericBLEMIDI_Interface.hpp @@ -32,6 +32,9 @@ class GenericBLEMIDI_Interface : public MIDI_Interface { private: #if !DISABLE_PIPES void handleStall() override { MIDI_Interface::handleStall(this); } +#ifdef DEBUG_OUT + const char *getName() const override { return "ble"; } +#endif #endif public: diff --git a/src/MIDI_Interfaces/MIDI_Interface.hpp b/src/MIDI_Interfaces/MIDI_Interface.hpp index 9e6b65b9d7..a02b864343 100644 --- a/src/MIDI_Interfaces/MIDI_Interface.hpp +++ b/src/MIDI_Interfaces/MIDI_Interface.hpp @@ -117,10 +117,10 @@ class MIDI_Interface : public TrueMIDI_SinkSource, template static void dispatchIncoming(MIDIInterface_t *iface, MIDIReadEvent event); /// Un-stall the given MIDI interface. Assumes the interface has been - /// stalled because of a chunked SysEx messages. Waits untill that message + /// stalled because of a chunked SysEx messages. Waits until that message /// is finished. template - static void handleStall(MIDIInterface_t *iface); + static void handleStall(MIDIInterface_t *self); private: MIDI_Callbacks *callbacks = nullptr; @@ -130,28 +130,30 @@ class MIDI_Interface : public TrueMIDI_SinkSource, }; template -void MIDI_Interface::updateIncoming(MIDIInterface_t *iface) { +void MIDI_Interface::updateIncoming(MIDIInterface_t *self) { #if DISABLE_PIPES - MIDIReadEvent event = iface->read(); + MIDIReadEvent event = self->read(); while (event != MIDIReadEvent::NO_MESSAGE) { - dispatchIncoming(iface, event); - event = iface->read(); + dispatchIncoming(self, event); + event = self->read(); } #else - if (iface->getStaller() == iface) - iface->unstall(iface); + MIDIReadEvent event = self->read(); + if (event == MIDIReadEvent::NO_MESSAGE) + return; + if (self->getStaller() == self) + self->unstall(self); bool chunked = false; - MIDIReadEvent event = iface->read(); while (event != MIDIReadEvent::NO_MESSAGE) { - dispatchIncoming(iface, event); + dispatchIncoming(self, event); if (event == MIDIReadEvent::SYSEX_CHUNK) chunked = true; if (event == MIDIReadEvent::SYSEX_MESSAGE) chunked = false; - event = iface->read(); + event = self->read(); } if (chunked) - iface->stall(iface); + self->stall(self); #endif // TODO: add logic to detect MIDI messages such as (N)RPN that span over // multiple channel voice messages and that shouldn't be interrupted. @@ -159,21 +161,21 @@ void MIDI_Interface::updateIncoming(MIDIInterface_t *iface) { } template -void MIDI_Interface::dispatchIncoming(MIDIInterface_t *iface, +void MIDI_Interface::dispatchIncoming(MIDIInterface_t *self, MIDIReadEvent event) { switch (event) { case MIDIReadEvent::CHANNEL_MESSAGE: - iface->onChannelMessage(iface->getChannelMessage()); + self->onChannelMessage(self->getChannelMessage()); break; case MIDIReadEvent::SYSEX_CHUNK: // fallthrough case MIDIReadEvent::SYSEX_MESSAGE: - iface->onSysExMessage(iface->getSysExMessage()); + self->onSysExMessage(self->getSysExMessage()); break; case MIDIReadEvent::SYSCOMMON_MESSAGE: - iface->onSysCommonMessage(iface->getSysCommonMessage()); + self->onSysCommonMessage(self->getSysCommonMessage()); break; case MIDIReadEvent::REALTIME_MESSAGE: - iface->onRealTimeMessage(iface->getRealTimeMessage()); + self->onRealTimeMessage(self->getRealTimeMessage()); break; case MIDIReadEvent::NO_MESSAGE: break; // LCOV_EXCL_LINE default: break; // LCOV_EXCL_LINE @@ -182,20 +184,22 @@ void MIDI_Interface::dispatchIncoming(MIDIInterface_t *iface, #if !DISABLE_PIPES template -void MIDI_Interface::handleStall(MIDIInterface_t *iface) { - iface->unstall(iface); +void MIDI_Interface::handleStall(MIDIInterface_t *self) { + const char *staller_name = self->getStallerName(); + DEBUGFN(F("Handling stall. Cause: ") << staller_name); + self->unstall(self); unsigned long startTime = millis(); while (millis() - startTime < SYSEX_CHUNK_TIMEOUT) { - MIDIReadEvent event = iface->read(); - dispatchIncoming(iface, event); + MIDIReadEvent event = self->read(); + dispatchIncoming(self, event); if (event == MIDIReadEvent::SYSEX_CHUNK) startTime = millis(); // reset timeout else if (event == MIDIReadEvent::SYSEX_MESSAGE) return; } - DEBUGREF(F("Warning: Unable to un-stall pipes: ") - << iface->getStallerName()); + DEBUGFN(F("Warning: Unable to un-stall pipes. Cause: ") << staller_name); + static_cast(staller_name); } #endif diff --git a/src/MIDI_Interfaces/MIDI_Pipes.cpp b/src/MIDI_Interfaces/MIDI_Pipes.cpp index 9bfed0b0ae..dda9cd3e37 100644 --- a/src/MIDI_Interfaces/MIDI_Pipes.cpp +++ b/src/MIDI_Interfaces/MIDI_Pipes.cpp @@ -160,9 +160,11 @@ void MIDI_Source::sourceMIDItoPipe(RealTimeMessage msg) { void MIDI_Source::stall(MIDIStaller *cause) { if (hasSinkPipe()) sinkPipe->stallDownstream(cause, this); + DEBUGFN(F("Stalled MIDI source. Cause: ") << getStallerName()); } void MIDI_Source::unstall(MIDIStaller *cause) { + DEBUGFN(F("Un-stalling MIDI source. Cause: ") << getStallerName()); if (hasSinkPipe()) sinkPipe->unstallDownstream(cause, this); } diff --git a/src/MIDI_Interfaces/MIDI_Staller.hpp b/src/MIDI_Interfaces/MIDI_Staller.hpp index 76ec93f7aa..883684376e 100644 --- a/src/MIDI_Interfaces/MIDI_Staller.hpp +++ b/src/MIDI_Interfaces/MIDI_Staller.hpp @@ -15,7 +15,7 @@ BEGIN_CS_NAMESPACE struct MIDIStaller { virtual ~MIDIStaller() = default; /// Get the staller's name for debugging purposes. - virtual const char *getName() const { return ""; }; + virtual const char *getName() const { return ""; } /// Call back that should finish any MIDI messages that are in progress, and /// un-stall the pipe or MIDI source as quickly as possible. virtual void handleStall() = 0; diff --git a/src/MIDI_Interfaces/SerialMIDI_Interface.hpp b/src/MIDI_Interfaces/SerialMIDI_Interface.hpp index dbb620808d..a71c4cb666 100644 --- a/src/MIDI_Interfaces/SerialMIDI_Interface.hpp +++ b/src/MIDI_Interfaces/SerialMIDI_Interface.hpp @@ -49,6 +49,9 @@ class StreamMIDI_Interface : public MIDI_Interface { protected: #if !DISABLE_PIPES void handleStall() override { MIDI_Interface::handleStall(this); } +#ifdef DEBUG_OUT + const char *getName() const override { return "ser"; } +#endif #endif protected: diff --git a/src/MIDI_Interfaces/USBMIDI_Interface.hpp b/src/MIDI_Interfaces/USBMIDI_Interface.hpp index 5908e6500c..783b5c295f 100644 --- a/src/MIDI_Interfaces/USBMIDI_Interface.hpp +++ b/src/MIDI_Interfaces/USBMIDI_Interface.hpp @@ -37,6 +37,9 @@ class GenericUSBMIDI_Interface : public MIDI_Interface { private: #if !DISABLE_PIPES void handleStall() override { MIDI_Interface::handleStall(this); } +#ifdef DEBUG_OUT + const char *getName() const override { return "usb"; } +#endif #endif public: diff --git a/src/MIDI_Interfaces/Wrappers/FortySevenEffects.hpp b/src/MIDI_Interfaces/Wrappers/FortySevenEffects.hpp index e13d5eb257..da65d94119 100644 --- a/src/MIDI_Interfaces/Wrappers/FortySevenEffects.hpp +++ b/src/MIDI_Interfaces/Wrappers/FortySevenEffects.hpp @@ -187,6 +187,9 @@ class FortySevenEffectsMIDI_Interface : public MIDI_Interface { ERROR(F("Not implemented (stalled by ") << stallername << ')', 0x1349); (void)stallername; } +#ifdef DEBUG_OUT + const char *getName() const override { return "47fx"; } +#endif #endif private: