diff --git a/modules/juce_audio_basics/midi/ump/juce_UMPConversion.h b/modules/juce_audio_basics/midi/ump/juce_UMPConversion.h index 57f8387e79..56c81e1c7b 100644 --- a/modules/juce_audio_basics/midi/ump/juce_UMPConversion.h +++ b/modules/juce_audio_basics/midi/ump/juce_UMPConversion.h @@ -85,7 +85,7 @@ struct Conversion `callback` is a function which accepts a single View argument. */ template - static void toMidi1 (const BytestreamMidiView& m, PacketCallbackFunction&& callback) + static void toMidi1 (const BytesOnGroup& m, PacketCallbackFunction&& callback) { const auto size = m.bytes.size(); diff --git a/modules/juce_audio_basics/midi/ump/juce_UMPConverters.h b/modules/juce_audio_basics/midi/ump/juce_UMPConverters.h index 6ea9ff8fe3..807d372629 100644 --- a/modules/juce_audio_basics/midi/ump/juce_UMPConverters.h +++ b/modules/juce_audio_basics/midi/ump/juce_UMPConverters.h @@ -44,7 +44,7 @@ namespace juce::universal_midi_packets struct ToUMP1Converter { template - void convert (const BytestreamMidiView& m, Fn&& fn) + void convert (const BytesOnGroup& m, Fn&& fn) { Conversion::toMidi1 (m, std::forward (fn)); } @@ -65,7 +65,7 @@ namespace juce::universal_midi_packets struct ToUMP2Converter { template - void convert (const BytestreamMidiView& m, Fn&& fn) + void convert (const BytesOnGroup& m, Fn&& fn) { Conversion::toMidi1 (m, [&] (const View& v) { @@ -116,7 +116,7 @@ namespace juce::universal_midi_packets } template - static void convertImpl (Converter& converter, const BytestreamMidiView& m, Fn&& fn) + static void convertImpl (Converter& converter, const BytesOnGroup& m, Fn&& fn) { converter.convert (m, std::forward (fn)); } @@ -137,7 +137,7 @@ namespace juce::universal_midi_packets } template - void convert (const BytestreamMidiView& m, Fn&& fn) + void convert (const BytesOnGroup& m, Fn&& fn) { visit (*this, m, std::forward (fn)); } diff --git a/modules/juce_audio_basics/midi/ump/juce_UMPDispatcher.h b/modules/juce_audio_basics/midi/ump/juce_UMPDispatcher.h index a05de2b3f8..1bbaa6701f 100644 --- a/modules/juce_audio_basics/midi/ump/juce_UMPDispatcher.h +++ b/modules/juce_audio_basics/midi/ump/juce_UMPDispatcher.h @@ -123,7 +123,7 @@ public: void handleIncomingMidiMessage (void*, const MidiMessage& msg) const { - Conversion::toMidi1 (BytestreamMidiView (&msg), [&] (const View& view) + Conversion::toMidi1 ({ 0, msg.asSpan() }, [&] (const View& view) { dispatch.converter.convert (view, *callbackPtr); }); diff --git a/modules/juce_audio_basics/midi/ump/juce_UMPMidi1ToBytestreamTranslator.h b/modules/juce_audio_basics/midi/ump/juce_UMPMidi1ToBytestreamTranslator.h index 57afcd05a0..45167ff2e1 100644 --- a/modules/juce_audio_basics/midi/ump/juce_UMPMidi1ToBytestreamTranslator.h +++ b/modules/juce_audio_basics/midi/ump/juce_UMPMidi1ToBytestreamTranslator.h @@ -260,7 +260,7 @@ public: switch (kind) { case SysexExtractorCallbackKind::notSysex: - callback (BytestreamMidiView (bytes, time)); + callback (BytesOnGroup { 0, bytes }, time); return; case SysexExtractorCallbackKind::ongoingSysex: @@ -282,7 +282,7 @@ public: // If this is not true, then the sysex message was truncated somehow and we // probably shouldn't allow it to propagate if (pendingSysExData.back() == std::byte { 0xf7 }) - callback (BytestreamMidiView (Span (pendingSysExData), pendingSysExTime)); + callback (BytesOnGroup { 0, Span (pendingSysExData) }, pendingSysExTime); pendingSysExData.clear(); diff --git a/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp b/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp index 9edfd99acf..c959964e7c 100644 --- a/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp +++ b/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp @@ -42,6 +42,14 @@ constexpr uint64_t operator""_u64 (unsigned long long int i) { return static_cas class UniversalMidiPacketTests final : public UnitTest { + static auto makeMidiMessageAppender (MidiBuffer& b) + { + return [&b] (const BytesOnGroup& x, double time) + { + b.addEvent (makeMidiMessage (x, time), (int) time); + }; + } + public: UniversalMidiPacketTests() : UnitTest ("Universal MIDI Packet", UnitTestCategories::midi) @@ -67,9 +75,9 @@ public: ? Utils::MessageKind::commonRealtime : Utils::MessageKind::channelVoice1)); - translator.dispatch (View { packets.data() }, 0, [&] (const BytestreamMidiView& roundTripped) + translator.dispatch (View { packets.data() }, 0, [&] (const BytesOnGroup& roundTripped, double time) { - expect (equal (m, roundTripped.getMessage())); + expect (equal (m, makeMidiMessage (roundTripped, time))); }); }); } @@ -141,13 +149,10 @@ public: const auto checkRoundTrip = [&] (const MidiBuffer& expected) { for (const auto meta : expected) - Conversion::toMidi1 (ump::BytestreamMidiView (meta), [&] (const auto p) { packets.add (p); }); + Conversion::toMidi1 ({ 0, meta.asSpan() }, [&] (const auto p) { packets.add (p); }); MidiBuffer output; - converter.dispatch (packets, 0, [&] (const BytestreamMidiView& roundTripped) - { - output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp)); - }); + converter.dispatch (packets, 0, makeMidiMessageAppender (output)); packets.clear(); expect (equal (expected, output)); @@ -184,10 +189,7 @@ public: } MidiBuffer output; - converter.dispatch (modifiedPackets, 0, [&] (const BytestreamMidiView& roundTripped) - { - output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp)); - }); + converter.dispatch (modifiedPackets, 0, makeMidiMessageAppender (output)); // All Utility messages should have been ignored expect (output.getNumEvents() == 1); @@ -219,10 +221,7 @@ public: } MidiBuffer output; - converter.dispatch (modifiedPackets, 0, [&] (const BytestreamMidiView& roundTripped) - { - output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp)); - }); + converter.dispatch (modifiedPackets, 0, makeMidiMessageAppender (output)); const auto numOutputs = output.getNumEvents(); const auto numInputs = realtimeMessages.getNumEvents(); @@ -283,10 +282,7 @@ public: } MidiBuffer output; - converter.dispatch (modifiedPackets, 0, [&] (const BytestreamMidiView& roundTripped) - { - output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp)); - }); + converter.dispatch (modifiedPackets, 0, makeMidiMessageAppender (output)); const auto numOutputs = output.getNumEvents(); const auto numInputs = realtimeMessages.getNumEvents(); @@ -329,7 +325,7 @@ public: Packets p; for (const auto meta : noteOn) - Conversion::toMidi1 (ump::BytestreamMidiView (meta), [&] (const auto packet) { p.add (packet); }); + Conversion::toMidi1 ({ 0, meta.asSpan() }, [&] (const auto packet) { p.add (packet); }); return p; }(); @@ -363,10 +359,7 @@ public: const auto pushToOutput = [&] (const Packets& p) { - converter.dispatch (p, 0, [&] (const BytestreamMidiView& roundTripped) - { - output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp)); - }); + converter.dispatch (p, 0, makeMidiMessageAppender (output)); }; pushToOutput (modifiedPackets); @@ -866,7 +859,7 @@ private: static Packets toMidi1 (const MidiMessage& msg) { Packets packets; - Conversion::toMidi1 (ump::BytestreamMidiView (&msg), [&] (const auto p) { packets.add (p); }); + Conversion::toMidi1 ({ 0, msg.asSpan() }, [&] (const auto p) { packets.add (p); }); return packets; } @@ -996,6 +989,11 @@ private: { return a.data == b.data; } + + static MidiMessage makeMidiMessage (const BytesOnGroup& b, double time) + { + return { b.bytes.data(), (int) b.bytes.size(), time }; + } }; static UniversalMidiPacketTests universalMidiPacketTests; diff --git a/modules/juce_audio_devices/midi_io/ump/juce_UMPU32InputHandler.h b/modules/juce_audio_devices/midi_io/ump/juce_UMPU32InputHandler.h index c6d41ff539..a7b4b1cf60 100644 --- a/modules/juce_audio_devices/midi_io/ump/juce_UMPU32InputHandler.h +++ b/modules/juce_audio_devices/midi_io/ump/juce_UMPU32InputHandler.h @@ -91,9 +91,9 @@ struct U32ToBytestreamHandler : public U32InputHandler void pushMidiData (Span words, double time) override { - dispatcher.dispatch (words, time, [this] (const BytestreamMidiView& m) + dispatcher.dispatch (words, time, [&] (const BytesOnGroup& roundTripped, double t) { - callback.handleIncomingMidiMessage (&input, m.getMessage()); + callback.handleIncomingMidiMessage (&input, MidiMessage { roundTripped.bytes.data(), (int) roundTripped.bytes.size(), t }); }); } diff --git a/modules/juce_audio_devices/native/juce_CoreMidi_mac.mm b/modules/juce_audio_devices/native/juce_CoreMidi_mac.mm index 0092922495..57afb1d11c 100644 --- a/modules/juce_audio_devices/native/juce_CoreMidi_mac.mm +++ b/modules/juce_audio_devices/native/juce_CoreMidi_mac.mm @@ -75,7 +75,7 @@ namespace CoreMidiHelpers { virtual ~SenderBase() noexcept = default; - virtual void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m) = 0; + virtual void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytesOnGroup& m) = 0; virtual void send (MIDIPortRef port, MIDIEndpointRef endpoint, ump::Iterator b, ump::Iterator e) = 0; }; @@ -85,7 +85,7 @@ namespace CoreMidiHelpers template <> struct API_AVAILABLE (macos (11.0), ios (14.0)) Sender final : public SenderBase { - void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m) override + void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytesOnGroup& m) override { newSendImpl (port, endpoint, m); } @@ -171,7 +171,7 @@ namespace CoreMidiHelpers template <> struct Sender final : public SenderBase { - void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m) override + void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytesOnGroup& m) override { oldSendImpl (port, endpoint, m); } @@ -180,7 +180,7 @@ namespace CoreMidiHelpers { std::for_each (b, e, [&] (const ump::View& v) { - bytestreamConverter.convert (v, 0.0, [&] (const ump::BytestreamMidiView& m) + bytestreamConverter.convert (v, 0.0, [&] (const ump::BytesOnGroup& m, double) { send (port, endpoint, m); }); @@ -190,7 +190,7 @@ namespace CoreMidiHelpers private: ump::ToBytestreamConverter bytestreamConverter { 2048 }; - void oldSendImpl (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& message) + void oldSendImpl (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytesOnGroup& message) { #if JUCE_IOS const MIDITimeStamp timeStamp = mach_absolute_time(); @@ -203,7 +203,10 @@ namespace CoreMidiHelpers auto* packetToSend = &stackPacket; auto dataSize = message.bytes.size(); - if (message.isSysEx()) + const auto bytes = message.bytes; + const auto isSysEx = ! bytes.empty() && bytes.front() == std::byte { 0xf0 }; + + if (isSysEx) { const int maxPacketSize = 256; int pos = 0, bytesLeft = (int) dataSize; @@ -262,7 +265,7 @@ namespace CoreMidiHelpers : sender (makeImpl()) {} - void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m) + void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytesOnGroup& m) { sender->send (port, endpoint, m); } @@ -358,7 +361,7 @@ namespace CoreMidiHelpers endpoint.release(); } - void send (const ump::BytestreamMidiView& m) + void send (const ump::BytesOnGroup& m) { sender.send (*port, *endpoint, m); } @@ -1266,7 +1269,7 @@ MidiOutput::~MidiOutput() void MidiOutput::sendMessageNow (const MidiMessage& message) { - internal->send (ump::BytestreamMidiView (&message)); + internal->send ({ 0, message.asSpan() }); } MidiDeviceListConnection MidiDeviceListConnection::make (std::function cb) diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm index 26c62bb7c6..755a1c9a58 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm @@ -1596,9 +1596,9 @@ public: toBytestreamDispatcher.dispatch ({ reinterpret_cast (packet->words), (size_t) packet->wordCount }, static_cast (packet->timeStamp + inOffsetSampleFrame), - [this] (const ump::BytestreamMidiView& message) + [this] (const ump::BytesOnGroup& x, double t) { - incomingEvents.addEvent (message.getMessage(), (int) message.timestamp); + incomingEvents.addEvent ({ x.bytes.data(), (int) x.bytes.size(), t }, (int) t); }); packet = MIDIEventPacketNext (packet); diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm index 6d1ce73460..a03d1f1868 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm @@ -1489,9 +1489,9 @@ private: converter.dispatch ({ reinterpret_cast (packet->words), (size_t) packet->wordCount }, static_cast (packet->timeStamp - (MIDITimeStamp) startTime), - [this] (const ump::BytestreamMidiView& message) + [this] (const ump::BytesOnGroup& x, double t) { - midiMessages.addEvent (message.getMessage(), (int) message.timestamp); + midiMessages.addEvent ({ x.bytes.data(), (int) x.bytes.size(), t }, (int) t); }); packet = MIDIEventPacketNext (packet); diff --git a/modules/juce_audio_processors/format_types/juce_AU_Shared.h b/modules/juce_audio_processors/format_types/juce_AU_Shared.h index 92a4d48139..63e3afd44c 100644 --- a/modules/juce_audio_processors/format_types/juce_AU_Shared.h +++ b/modules/juce_audio_processors/format_types/juce_AU_Shared.h @@ -715,7 +715,7 @@ struct AudioUnitHelpers for (const auto metadata : buffer) { - toUmp1Converter.convert (ump::BytestreamMidiView (metadata), [&] (const ump::View& view) + toUmp1Converter.convert ({ 0, metadata.asSpan() }, [&] (const ump::View& view) { add (view, metadata.samplePosition);