| @@ -59,19 +59,13 @@ struct MidiDeviceListEntry : ReferenceCountedObject | |||||
| using Ptr = ReferenceCountedObjectPtr<MidiDeviceListEntry>; | using Ptr = ReferenceCountedObjectPtr<MidiDeviceListEntry>; | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| struct MidiCallbackMessage : public Message | |||||
| { | |||||
| MidiCallbackMessage (const MidiMessage& msg) : message (msg) {} | |||||
| MidiMessage message; | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| class MidiDemo : public Component, | class MidiDemo : public Component, | ||||
| private Timer, | private Timer, | ||||
| private MidiKeyboardStateListener, | private MidiKeyboardStateListener, | ||||
| private MidiInputCallback, | private MidiInputCallback, | ||||
| private MessageListener | |||||
| private AsyncUpdater | |||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -152,14 +146,6 @@ public: | |||||
| sendToOutputs (m); | sendToOutputs (m); | ||||
| } | } | ||||
| void handleMessage (const Message& msg) override | |||||
| { | |||||
| // This is called on the message loop | |||||
| auto& mm = dynamic_cast<const MidiCallbackMessage&> (msg).message; | |||||
| midiMonitor.insertTextAtCaret (mm.getDescription() + "\n"); | |||||
| } | |||||
| void paint (Graphics&) override {} | void paint (Graphics&) override {} | ||||
| void resized() override | void resized() override | ||||
| @@ -253,11 +239,9 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| class MidiDeviceListBox : public ListBox, | |||||
| private ListBoxModel | |||||
| struct MidiDeviceListBox : public ListBox, | |||||
| private ListBoxModel | |||||
| { | { | ||||
| public: | |||||
| //============================================================================== | |||||
| MidiDeviceListBox (const String& name, | MidiDeviceListBox (const String& name, | ||||
| MidiDemo& contentComponent, | MidiDemo& contentComponent, | ||||
| bool isInputDeviceList) | bool isInputDeviceList) | ||||
| @@ -277,7 +261,6 @@ private: | |||||
| : parent.getNumMidiOutputs(); | : parent.getNumMidiOutputs(); | ||||
| } | } | ||||
| //============================================================================== | |||||
| void paintListBoxItem (int rowNumber, Graphics& g, | void paintListBoxItem (int rowNumber, Graphics& g, | ||||
| int width, int height, bool rowIsSelected) override | int width, int height, bool rowIsSelected) override | ||||
| { | { | ||||
| @@ -352,12 +335,30 @@ private: | |||||
| void handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage& message) override | void handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage& message) override | ||||
| { | { | ||||
| // This is called on the MIDI thread | // This is called on the MIDI thread | ||||
| const ScopedLock sl (midiMonitorLock); | |||||
| incomingMessages.add (message); | |||||
| triggerAsyncUpdate(); | |||||
| } | |||||
| void handleAsyncUpdate() override | |||||
| { | |||||
| // This is called on the message loop | |||||
| Array<MidiMessage> messages; | |||||
| { | |||||
| const ScopedLock sl (midiMonitorLock); | |||||
| messages.swapWith (incomingMessages); | |||||
| } | |||||
| String messageText; | |||||
| for (auto& m : messages) | |||||
| messageText << m.getDescription() << "\n"; | |||||
| if (message.isNoteOnOrOff()) | |||||
| postMessage (new MidiCallbackMessage (message)); | |||||
| midiMonitor.insertTextAtCaret (messageText); | |||||
| } | } | ||||
| void sendToOutputs(const MidiMessage& msg) | |||||
| void sendToOutputs (const MidiMessage& msg) | |||||
| { | { | ||||
| for (auto midiOutput : midiOutputs) | for (auto midiOutput : midiOutputs) | ||||
| if (midiOutput->outDevice.get() != nullptr) | if (midiOutput->outDevice.get() != nullptr) | ||||
| @@ -469,11 +470,11 @@ private: | |||||
| TextEditor midiMonitor { "MIDI Monitor" }; | TextEditor midiMonitor { "MIDI Monitor" }; | ||||
| TextButton pairButton { "MIDI Bluetooth devices..." }; | TextButton pairButton { "MIDI Bluetooth devices..." }; | ||||
| std::unique_ptr<MidiDeviceListBox> midiInputSelector; | |||||
| std::unique_ptr<MidiDeviceListBox> midiOutputSelector; | |||||
| std::unique_ptr<MidiDeviceListBox> midiInputSelector, midiOutputSelector; | |||||
| ReferenceCountedArray<MidiDeviceListEntry> midiInputs, midiOutputs; | |||||
| ReferenceCountedArray<MidiDeviceListEntry> midiInputs; | |||||
| ReferenceCountedArray<MidiDeviceListEntry> midiOutputs; | |||||
| CriticalSection midiMonitorLock; | |||||
| Array<MidiMessage> incomingMessages; | |||||
| //============================================================================== | //============================================================================== | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiDemo) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiDemo) | ||||