mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
UMP: Migrate to std::byte
This commit is contained in:
parent
f1f68007c6
commit
78a12d2f57
13 changed files with 230 additions and 191 deletions
|
|
@ -27,6 +27,44 @@ namespace juce
|
|||
namespace universal_midi_packets
|
||||
{
|
||||
|
||||
/** Represents a MIDI message that happened at a particular time.
|
||||
|
||||
Unlike MidiMessage, BytestreamMidiView is non-owning.
|
||||
*/
|
||||
struct BytestreamMidiView
|
||||
{
|
||||
constexpr BytestreamMidiView (Span<const std::byte> bytesIn, double timestampIn)
|
||||
: bytes (bytesIn), timestamp (timestampIn) {}
|
||||
|
||||
/** Creates a view over the provided message.
|
||||
|
||||
Note that the argument is a pointer, not a reference, in order to avoid taking a reference
|
||||
to a temporary.
|
||||
*/
|
||||
explicit BytestreamMidiView (const MidiMessage* msg)
|
||||
: bytes (unalignedPointerCast<const std::byte*> (msg->getRawData()),
|
||||
static_cast<size_t> (msg->getRawDataSize())),
|
||||
timestamp (msg->getTimeStamp()) {}
|
||||
|
||||
explicit BytestreamMidiView (const MidiMessageMetadata msg)
|
||||
: bytes (unalignedPointerCast<const std::byte*> (msg.data),
|
||||
static_cast<size_t> (msg.numBytes)),
|
||||
timestamp (msg.samplePosition) {}
|
||||
|
||||
MidiMessage getMessage() const
|
||||
{
|
||||
return MidiMessage (bytes.data(), (int) bytes.size(), timestamp);
|
||||
}
|
||||
|
||||
bool isSysEx() const
|
||||
{
|
||||
return ! bytes.empty() && bytes.front() == std::byte { 0xf0 };
|
||||
}
|
||||
|
||||
Span<const std::byte> bytes;
|
||||
double timestamp = 0.0;
|
||||
};
|
||||
|
||||
/**
|
||||
Functions to assist conversion of UMP messages to/from other formats,
|
||||
especially older 'bytestream' formatted MidiMessages.
|
||||
|
|
@ -40,13 +78,17 @@ struct Conversion
|
|||
`callback` is a function which accepts a single View argument.
|
||||
*/
|
||||
template <typename PacketCallbackFunction>
|
||||
static void toMidi1 (const MidiMessage& m, PacketCallbackFunction&& callback)
|
||||
static void toMidi1 (const BytestreamMidiView& m, PacketCallbackFunction&& callback)
|
||||
{
|
||||
const auto* data = m.getRawData();
|
||||
const auto firstByte = data[0];
|
||||
const auto size = m.getRawDataSize();
|
||||
const auto size = m.bytes.size();
|
||||
|
||||
if (firstByte != 0xf0)
|
||||
if (size <= 0)
|
||||
return;
|
||||
|
||||
const auto* data = m.bytes.data();
|
||||
const auto firstByte = data[0];
|
||||
|
||||
if (firstByte != std::byte { 0xf0 })
|
||||
{
|
||||
const auto mask = [size]() -> uint32_t
|
||||
{
|
||||
|
|
@ -61,15 +103,15 @@ struct Conversion
|
|||
return 0x00000000;
|
||||
}();
|
||||
|
||||
const auto extraByte = (uint8_t) ((((firstByte & 0xf0) == 0xf0) ? 0x1 : 0x2) << 0x4);
|
||||
const auto extraByte = ((((firstByte & std::byte { 0xf0 }) == std::byte { 0xf0 }) ? std::byte { 0x1 } : std::byte { 0x2 }) << 0x4);
|
||||
const PacketX1 packet { mask & Utils::bytesToWord (extraByte, data[0], data[1], data[2]) };
|
||||
callback (View (packet.data()));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto numSysExBytes = m.getSysExDataSize();
|
||||
const auto numSysExBytes = (ssize_t) (size - 2);
|
||||
const auto numMessages = SysEx7::getNumPacketsRequiredForDataSize ((uint32_t) numSysExBytes);
|
||||
auto* dataOffset = m.getSysExData();
|
||||
auto* dataOffset = data + 1;
|
||||
|
||||
if (numMessages <= 1)
|
||||
{
|
||||
|
|
@ -78,9 +120,9 @@ struct Conversion
|
|||
return;
|
||||
}
|
||||
|
||||
constexpr auto byteIncrement = 6;
|
||||
constexpr ssize_t byteIncrement = 6;
|
||||
|
||||
for (auto i = numSysExBytes; i > 0; i -= byteIncrement, dataOffset += byteIncrement)
|
||||
for (auto i = static_cast<ssize_t> (numSysExBytes); i > 0; i -= byteIncrement, dataOffset += byteIncrement)
|
||||
{
|
||||
const auto func = [&]
|
||||
{
|
||||
|
|
@ -99,20 +141,6 @@ struct Conversion
|
|||
}
|
||||
}
|
||||
|
||||
/** Converts a MidiMessage to one or more messages in UMP format, using
|
||||
the MIDI 1.0 Protocol.
|
||||
|
||||
`packets` is an out-param to allow the caller to control
|
||||
allocation/deallocation. Returning a new Packets object would
|
||||
require every call to toMidi1 to allocate. With this version, no
|
||||
allocations will occur, provided that `packets` has adequate reserved
|
||||
space.
|
||||
*/
|
||||
static void toMidi1 (const MidiMessage& m, Packets& packets)
|
||||
{
|
||||
toMidi1 (m, [&] (const View& view) { packets.add (view); });
|
||||
}
|
||||
|
||||
/** Widens a 7-bit MIDI 1.0 value to a 8-bit MIDI 2.0 value. */
|
||||
static uint8_t scaleTo8 (uint8_t word7Bit)
|
||||
{
|
||||
|
|
@ -198,7 +226,7 @@ struct Conversion
|
|||
}
|
||||
|
||||
const auto status = Utils::getStatus (firstWord);
|
||||
const auto typeAndGroup = (uint8_t) ((0x2 << 0x4) | Utils::getGroup (firstWord));
|
||||
const auto typeAndGroup = ((std::byte { 0x2 } << 0x4) | std::byte { Utils::getGroup (firstWord) });
|
||||
|
||||
switch (status)
|
||||
{
|
||||
|
|
@ -207,18 +235,18 @@ struct Conversion
|
|||
case 0xa: // poly pressure
|
||||
case 0xb: // control change
|
||||
{
|
||||
const auto statusAndChannel = (uint8_t) ((firstWord >> 0x10) & 0xff);
|
||||
const auto byte2 = (uint8_t) ((firstWord >> 0x08) & 0xff);
|
||||
const auto byte3 = scaleTo7 (v[1]);
|
||||
const auto statusAndChannel = std::byte ((firstWord >> 0x10) & 0xff);
|
||||
const auto byte2 = std::byte ((firstWord >> 0x08) & 0xff);
|
||||
const auto byte3 = std::byte { scaleTo7 (v[1]) };
|
||||
|
||||
// If this is a note-on, and the scaled byte is 0,
|
||||
// the scaled velocity should be 1 instead of 0
|
||||
const auto needsCorrection = status == 0x9 && byte3 == 0;
|
||||
const auto correctedByte = (uint8_t) (needsCorrection ? 1 : byte3);
|
||||
const auto needsCorrection = status == 0x9 && byte3 == std::byte { 0 };
|
||||
const auto correctedByte = needsCorrection ? std::byte { 1 } : byte3;
|
||||
|
||||
const auto shouldIgnore = status == 0xb && [&]
|
||||
{
|
||||
switch (byte2)
|
||||
switch (uint8_t (byte2))
|
||||
{
|
||||
case 0:
|
||||
case 6:
|
||||
|
|
@ -247,13 +275,13 @@ struct Conversion
|
|||
|
||||
case 0xd: // channel pressure
|
||||
{
|
||||
const auto statusAndChannel = (uint8_t) ((firstWord >> 0x10) & 0xff);
|
||||
const auto byte2 = scaleTo7 (v[1]);
|
||||
const auto statusAndChannel = std::byte ((firstWord >> 0x10) & 0xff);
|
||||
const auto byte2 = std::byte { scaleTo7 (v[1]) };
|
||||
|
||||
const PacketX1 packet { Utils::bytesToWord (typeAndGroup,
|
||||
statusAndChannel,
|
||||
byte2,
|
||||
0) };
|
||||
std::byte { 0 }) };
|
||||
callback (View (packet.data()));
|
||||
return;
|
||||
}
|
||||
|
|
@ -261,17 +289,17 @@ struct Conversion
|
|||
case 0x2: // rpn
|
||||
case 0x3: // nrpn
|
||||
{
|
||||
const auto ccX = (uint8_t) (status == 0x2 ? 101 : 99);
|
||||
const auto ccY = (uint8_t) (status == 0x2 ? 100 : 98);
|
||||
const auto statusAndChannel = (uint8_t) ((0xb << 0x4) | Utils::getChannel (firstWord));
|
||||
const auto ccX = status == 0x2 ? std::byte { 101 } : std::byte { 99 };
|
||||
const auto ccY = status == 0x2 ? std::byte { 100 } : std::byte { 98 };
|
||||
const auto statusAndChannel = std::byte ((0xb << 0x4) | Utils::getChannel (firstWord));
|
||||
const auto data = scaleTo14 (v[1]);
|
||||
|
||||
const PacketX1 packets[]
|
||||
{
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, ccX, (uint8_t) ((firstWord >> 0x8) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, ccY, (uint8_t) ((firstWord >> 0x0) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, 6, (uint8_t) ((data >> 0x7) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, 38, (uint8_t) ((data >> 0x0) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, ccX, std::byte ((firstWord >> 0x8) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, ccY, std::byte ((firstWord >> 0x0) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, std::byte { 6 }, std::byte ((data >> 0x7) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, std::byte { 38 }, std::byte ((data >> 0x0) & 0x7f)) },
|
||||
};
|
||||
|
||||
for (const auto& packet : packets)
|
||||
|
|
@ -284,24 +312,24 @@ struct Conversion
|
|||
{
|
||||
if (firstWord & 1)
|
||||
{
|
||||
const auto statusAndChannel = (uint8_t) ((0xb << 0x4) | Utils::getChannel (firstWord));
|
||||
const auto statusAndChannel = std::byte ((0xb << 0x4) | Utils::getChannel (firstWord));
|
||||
const auto secondWord = v[1];
|
||||
|
||||
const PacketX1 packets[]
|
||||
{
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, 0, (uint8_t) ((secondWord >> 0x8) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, 32, (uint8_t) ((secondWord >> 0x0) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, std::byte { 0 }, std::byte ((secondWord >> 0x8) & 0x7f)) },
|
||||
PacketX1 { Utils::bytesToWord (typeAndGroup, statusAndChannel, std::byte { 32 }, std::byte ((secondWord >> 0x0) & 0x7f)) },
|
||||
};
|
||||
|
||||
for (const auto& packet : packets)
|
||||
callback (View (packet.data()));
|
||||
}
|
||||
|
||||
const auto statusAndChannel = (uint8_t) ((0xc << 0x4) | Utils::getChannel (firstWord));
|
||||
const auto statusAndChannel = std::byte ((0xc << 0x4) | Utils::getChannel (firstWord));
|
||||
const PacketX1 packet { Utils::bytesToWord (typeAndGroup,
|
||||
statusAndChannel,
|
||||
(uint8_t) ((v[1] >> 0x18) & 0x7f),
|
||||
0) };
|
||||
std::byte ((v[1] >> 0x18) & 0x7f),
|
||||
std::byte { 0 }) };
|
||||
callback (View (packet.data()));
|
||||
return;
|
||||
}
|
||||
|
|
@ -309,11 +337,11 @@ struct Conversion
|
|||
case 0xe: // pitch bend
|
||||
{
|
||||
const auto data = scaleTo14 (v[1]);
|
||||
const auto statusAndChannel = (uint8_t) ((firstWord >> 0x10) & 0xff);
|
||||
const auto statusAndChannel = std::byte ((firstWord >> 0x10) & 0xff);
|
||||
const PacketX1 packet { Utils::bytesToWord (typeAndGroup,
|
||||
statusAndChannel,
|
||||
(uint8_t) (data & 0x7f),
|
||||
(uint8_t) ((data >> 7) & 0x7f)) };
|
||||
std::byte (data & 0x7f),
|
||||
std::byte ((data >> 7) & 0x7f)) };
|
||||
callback (View (packet.data()));
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace universal_midi_packets
|
|||
struct ToUMP1Converter
|
||||
{
|
||||
template <typename Fn>
|
||||
void convert (const MidiMessage& m, Fn&& fn)
|
||||
void convert (const BytestreamMidiView& m, Fn&& fn)
|
||||
{
|
||||
Conversion::toMidi1 (m, std::forward<Fn> (fn));
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ namespace universal_midi_packets
|
|||
struct ToUMP2Converter
|
||||
{
|
||||
template <typename Fn>
|
||||
void convert (const MidiMessage& m, Fn&& fn)
|
||||
void convert (const BytestreamMidiView& m, Fn&& fn)
|
||||
{
|
||||
Conversion::toMidi1 (m, [&] (const View& v)
|
||||
{
|
||||
|
|
@ -98,7 +98,7 @@ namespace universal_midi_packets
|
|||
}
|
||||
|
||||
template <typename Fn>
|
||||
void convert (const MidiMessage& m, Fn&& fn)
|
||||
void convert (const BytestreamMidiView& m, Fn&& fn)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public:
|
|||
|
||||
void handleIncomingMidiMessage (void*, const MidiMessage& msg) const
|
||||
{
|
||||
Conversion::toMidi1 (msg, [&] (const View& view)
|
||||
Conversion::toMidi1 (BytestreamMidiView (&msg), [&] (const View& view)
|
||||
{
|
||||
dispatch.converter.convert (view, *callbackPtr);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ struct Factory
|
|||
static PacketX2 makeSysEx (uint8_t group,
|
||||
uint8_t status,
|
||||
uint8_t numBytes,
|
||||
const uint8_t* data)
|
||||
const std::byte* data)
|
||||
{
|
||||
jassert (numBytes <= 6);
|
||||
|
||||
|
|
@ -250,28 +250,28 @@ struct Factory
|
|||
|
||||
static PacketX2 makeSysExIn1Packet (uint8_t group,
|
||||
uint8_t numBytes,
|
||||
const uint8_t* data)
|
||||
const std::byte* data)
|
||||
{
|
||||
return Detail::makeSysEx (group, 0x0, numBytes, data);
|
||||
}
|
||||
|
||||
static PacketX2 makeSysExStart (uint8_t group,
|
||||
uint8_t numBytes,
|
||||
const uint8_t* data)
|
||||
const std::byte* data)
|
||||
{
|
||||
return Detail::makeSysEx (group, 0x1, numBytes, data);
|
||||
}
|
||||
|
||||
static PacketX2 makeSysExContinue (uint8_t group,
|
||||
uint8_t numBytes,
|
||||
const uint8_t* data)
|
||||
const std::byte* data)
|
||||
{
|
||||
return Detail::makeSysEx (group, 0x2, numBytes, data);
|
||||
}
|
||||
|
||||
static PacketX2 makeSysExEnd (uint8_t group,
|
||||
uint8_t numBytes,
|
||||
const uint8_t* data)
|
||||
const std::byte* data)
|
||||
{
|
||||
return Detail::makeSysEx (group, 0x3, numBytes, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,10 @@ public:
|
|||
{
|
||||
// Utility messages don't translate to bytestream format
|
||||
if (Utils::getMessageType (firstWord) != 0x00)
|
||||
callback (fromUmp (PacketX1 { firstWord }, time));
|
||||
{
|
||||
const auto message = fromUmp (PacketX1 { firstWord }, time);
|
||||
callback (BytestreamMidiView (&message));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -162,16 +165,14 @@ private:
|
|||
void startSysExMessage (double time)
|
||||
{
|
||||
pendingSysExTime = time;
|
||||
pendingSysExData.push_back (0xf0);
|
||||
pendingSysExData.push_back (std::byte { 0xf0 });
|
||||
}
|
||||
|
||||
template <typename MessageCallback>
|
||||
void terminateSysExMessage (MessageCallback&& callback)
|
||||
{
|
||||
pendingSysExData.push_back (0xf7);
|
||||
callback (MidiMessage (pendingSysExData.data(),
|
||||
int (pendingSysExData.size()),
|
||||
pendingSysExTime));
|
||||
pendingSysExData.push_back (std::byte { 0xf7 });
|
||||
callback (BytestreamMidiView (pendingSysExData, pendingSysExTime));
|
||||
pendingSysExData.clear();
|
||||
}
|
||||
|
||||
|
|
@ -206,7 +207,7 @@ private:
|
|||
return Utils::getMessageType (word) == 0x1 && ((word >> 0x10) & 0xff) >= 0xf8;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> pendingSysExData;
|
||||
std::vector<std::byte> pendingSysExData;
|
||||
|
||||
double pendingSysExTime = 0.0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ namespace universal_midi_packets
|
|||
PacketX2 Midi1ToMidi2DefaultTranslator::processNoteOnOrOff (const HelperValues helpers)
|
||||
{
|
||||
const auto velocity = helpers.byte2;
|
||||
const auto needsConversion = (helpers.byte0 >> 0x4) == 0x9 && velocity == 0;
|
||||
const auto firstByte = needsConversion ? (uint8_t) ((0x8 << 0x4) | (helpers.byte0 & 0xf))
|
||||
const auto needsConversion = (helpers.byte0 & std::byte { 0xf0 }) == std::byte { 0x90 } && velocity == std::byte { 0 };
|
||||
const auto firstByte = needsConversion ? (std::byte { 0x80 } | (helpers.byte0 & std::byte { 0xf }))
|
||||
: helpers.byte0;
|
||||
|
||||
return PacketX2
|
||||
{
|
||||
Utils::bytesToWord (helpers.typeAndGroup, firstByte, helpers.byte1, 0),
|
||||
(uint32_t) (Conversion::scaleTo16 (velocity) << 0x10)
|
||||
Utils::bytesToWord (helpers.typeAndGroup, firstByte, helpers.byte1, std::byte { 0 }),
|
||||
(uint32_t) (Conversion::scaleTo16 (uint8_t (velocity)) << 0x10)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -43,8 +43,8 @@ PacketX2 Midi1ToMidi2DefaultTranslator::processPolyPressure (const HelperValues
|
|||
{
|
||||
return PacketX2
|
||||
{
|
||||
Utils::bytesToWord (helpers.typeAndGroup, helpers.byte0, helpers.byte1, 0),
|
||||
Conversion::scaleTo32 (helpers.byte2)
|
||||
Utils::bytesToWord (helpers.typeAndGroup, helpers.byte0, helpers.byte1, std::byte { 0 }),
|
||||
Conversion::scaleTo32 (uint8_t (helpers.byte2))
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ bool Midi1ToMidi2DefaultTranslator::processControlChange (const HelperValues hel
|
|||
PacketX2& packet)
|
||||
{
|
||||
const auto statusAndChannel = helpers.byte0;
|
||||
const auto cc = helpers.byte1;
|
||||
const auto cc = uint8_t (helpers.byte1);
|
||||
|
||||
const auto shouldAccumulate = [&]
|
||||
{
|
||||
|
|
@ -70,8 +70,8 @@ bool Midi1ToMidi2DefaultTranslator::processControlChange (const HelperValues hel
|
|||
return false;
|
||||
}();
|
||||
|
||||
const auto group = (uint8_t) (helpers.typeAndGroup & 0xf);
|
||||
const auto channel = (uint8_t) (statusAndChannel & 0xf);
|
||||
const auto group = (uint8_t) (helpers.typeAndGroup & std::byte { 0xf });
|
||||
const auto channel = (uint8_t) (statusAndChannel & std::byte { 0xf });
|
||||
const auto byte = helpers.byte2;
|
||||
|
||||
if (shouldAccumulate)
|
||||
|
|
@ -86,13 +86,13 @@ bool Midi1ToMidi2DefaultTranslator::processControlChange (const HelperValues hel
|
|||
const auto msb = bytes[2];
|
||||
const auto lsb = bytes[3];
|
||||
|
||||
const auto value = (uint16_t) (((msb & 0x7f) << 7) | (lsb & 0x7f));
|
||||
const auto value = uint16_t ((uint16_t (msb & std::byte { 0x7f }) << 7) | uint16_t (lsb & std::byte { 0x7f }));
|
||||
|
||||
const auto newStatus = (uint8_t) (accumulator.getKind() == PnKind::nrpn ? 0x3 : 0x2);
|
||||
|
||||
packet = PacketX2
|
||||
{
|
||||
Utils::bytesToWord (helpers.typeAndGroup, (uint8_t) ((newStatus << 0x4) | channel), bank, index),
|
||||
Utils::bytesToWord (helpers.typeAndGroup, std::byte ((newStatus << 0x4) | channel), bank, index),
|
||||
Conversion::scaleTo32 (value)
|
||||
};
|
||||
return true;
|
||||
|
|
@ -103,35 +103,41 @@ bool Midi1ToMidi2DefaultTranslator::processControlChange (const HelperValues hel
|
|||
|
||||
if (cc == 0)
|
||||
{
|
||||
groupBanks[group][channel].setMsb (byte);
|
||||
groupBanks[group][channel].setMsb (uint8_t (byte));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cc == 32)
|
||||
{
|
||||
groupBanks[group][channel].setLsb (byte);
|
||||
groupBanks[group][channel].setLsb (uint8_t (byte));
|
||||
return false;
|
||||
}
|
||||
|
||||
packet = PacketX2
|
||||
{
|
||||
Utils::bytesToWord (helpers.typeAndGroup, statusAndChannel, cc, 0),
|
||||
Conversion::scaleTo32 (helpers.byte2)
|
||||
Utils::bytesToWord (helpers.typeAndGroup, statusAndChannel, std::byte { cc }, std::byte { 0 }),
|
||||
Conversion::scaleTo32 (uint8_t (helpers.byte2))
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
PacketX2 Midi1ToMidi2DefaultTranslator::processProgramChange (const HelperValues helpers) const
|
||||
{
|
||||
const auto group = (uint8_t) (helpers.typeAndGroup & 0xf);
|
||||
const auto channel = (uint8_t) (helpers.byte0 & 0xf);
|
||||
const auto group = (uint8_t) (helpers.typeAndGroup & std::byte { 0xf });
|
||||
const auto channel = (uint8_t) (helpers.byte0 & std::byte { 0xf });
|
||||
const auto bank = groupBanks[group][channel];
|
||||
const auto valid = bank.isValid();
|
||||
|
||||
return PacketX2
|
||||
{
|
||||
Utils::bytesToWord (helpers.typeAndGroup, helpers.byte0, 0, valid ? 1 : 0),
|
||||
Utils::bytesToWord (helpers.byte1, 0, valid ? bank.getMsb() : 0, valid ? bank.getLsb() : 0)
|
||||
Utils::bytesToWord (helpers.typeAndGroup,
|
||||
helpers.byte0,
|
||||
std::byte { 0 },
|
||||
valid ? std::byte { 1 } : std::byte { 0 }),
|
||||
Utils::bytesToWord (helpers.byte1,
|
||||
std::byte { 0 },
|
||||
valid ? std::byte { bank.getMsb() } : std::byte { 0 },
|
||||
valid ? std::byte { bank.getLsb() } : std::byte { 0 })
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -139,8 +145,8 @@ PacketX2 Midi1ToMidi2DefaultTranslator::processChannelPressure (const HelperValu
|
|||
{
|
||||
return PacketX2
|
||||
{
|
||||
Utils::bytesToWord (helpers.typeAndGroup, helpers.byte0, 0, 0),
|
||||
Conversion::scaleTo32 (helpers.byte1)
|
||||
Utils::bytesToWord (helpers.typeAndGroup, helpers.byte0, std::byte { 0 }, std::byte { 0 }),
|
||||
Conversion::scaleTo32 (uint8_t (helpers.byte1))
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -148,16 +154,16 @@ PacketX2 Midi1ToMidi2DefaultTranslator::processPitchBend (const HelperValues hel
|
|||
{
|
||||
const auto lsb = helpers.byte1;
|
||||
const auto msb = helpers.byte2;
|
||||
const auto value = (uint16_t) (msb << 7 | lsb);
|
||||
const auto value = uint16_t (uint16_t (msb) << 7 | uint16_t (lsb));
|
||||
|
||||
return PacketX2
|
||||
{
|
||||
Utils::bytesToWord (helpers.typeAndGroup, helpers.byte0, 0, 0),
|
||||
Utils::bytesToWord (helpers.typeAndGroup, helpers.byte0, std::byte { 0 }, std::byte { 0 }),
|
||||
Conversion::scaleTo32 (value)
|
||||
};
|
||||
}
|
||||
|
||||
bool Midi1ToMidi2DefaultTranslator::PnAccumulator::addByte (uint8_t cc, uint8_t byte)
|
||||
bool Midi1ToMidi2DefaultTranslator::PnAccumulator::addByte (uint8_t cc, std::byte byte)
|
||||
{
|
||||
const auto isStart = cc == 99 || cc == 101;
|
||||
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ public:
|
|||
|
||||
const HelperValues helperValues
|
||||
{
|
||||
(uint8_t) ((0x4 << 0x4) | Utils::getGroup (firstWord)),
|
||||
(uint8_t) ((firstWord >> 0x10) & 0xff),
|
||||
(uint8_t) ((firstWord >> 0x08) & 0x7f),
|
||||
(uint8_t) ((firstWord >> 0x00) & 0x7f),
|
||||
std::byte ((0x4 << 0x4) | Utils::getGroup (firstWord)),
|
||||
std::byte ((firstWord >> 0x10) & 0xff),
|
||||
std::byte ((firstWord >> 0x08) & 0x7f),
|
||||
std::byte ((firstWord >> 0x00) & 0x7f),
|
||||
};
|
||||
|
||||
switch (Utils::getStatus (firstWord))
|
||||
|
|
@ -128,10 +128,10 @@ private:
|
|||
|
||||
struct HelperValues
|
||||
{
|
||||
uint8_t typeAndGroup;
|
||||
uint8_t byte0;
|
||||
uint8_t byte1;
|
||||
uint8_t byte2;
|
||||
std::byte typeAndGroup;
|
||||
std::byte byte0;
|
||||
std::byte byte1;
|
||||
std::byte byte2;
|
||||
};
|
||||
|
||||
static PacketX2 processNoteOnOrOff (const HelperValues helpers);
|
||||
|
|
@ -147,13 +147,13 @@ private:
|
|||
class PnAccumulator
|
||||
{
|
||||
public:
|
||||
bool addByte (uint8_t cc, uint8_t byte);
|
||||
bool addByte (uint8_t cc, std::byte byte);
|
||||
|
||||
const std::array<uint8_t, 4>& getBytes() const noexcept { return bytes; }
|
||||
const std::array<std::byte, 4>& getBytes() const noexcept { return bytes; }
|
||||
PnKind getKind() const noexcept { return kind; }
|
||||
|
||||
private:
|
||||
std::array<uint8_t, 4> bytes;
|
||||
std::array<std::byte, 4> bytes;
|
||||
uint8_t index = 0;
|
||||
PnKind kind = PnKind::nrpn;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ SysEx7::PacketBytes SysEx7::getDataBytes (const PacketX2& packet)
|
|||
|
||||
return
|
||||
{
|
||||
{ { packet.getU8<2>(),
|
||||
packet.getU8<3>(),
|
||||
packet.getU8<4>(),
|
||||
packet.getU8<5>(),
|
||||
packet.getU8<6>(),
|
||||
packet.getU8<7>() } },
|
||||
{ { std::byte { packet.getU8<2>() },
|
||||
std::byte { packet.getU8<3>() },
|
||||
std::byte { packet.getU8<4>() },
|
||||
std::byte { packet.getU8<5>() },
|
||||
std::byte { packet.getU8<6>() },
|
||||
std::byte { packet.getU8<7>() } } },
|
||||
jmin (numBytes, maxBytes)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ struct SysEx7
|
|||
/** Holds the bytes from a single SysEx-7 packet. */
|
||||
struct PacketBytes
|
||||
{
|
||||
std::array<uint8_t, 6> data;
|
||||
std::array<std::byte, 6> data;
|
||||
uint8_t size;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,12 @@ namespace universal_midi_packets
|
|||
struct Utils
|
||||
{
|
||||
/** Joins 4 bytes into a single 32-bit word. */
|
||||
static constexpr uint32_t bytesToWord (uint8_t a, uint8_t b, uint8_t c, uint8_t d)
|
||||
static constexpr uint32_t bytesToWord (std::byte a, std::byte b, std::byte c, std::byte d)
|
||||
{
|
||||
return uint32_t (a << 0x18 | b << 0x10 | c << 0x08 | d << 0x00);
|
||||
return uint32_t (a) << 0x18
|
||||
| uint32_t (b) << 0x10
|
||||
| uint32_t (c) << 0x08
|
||||
| uint32_t (d) << 0x00;
|
||||
}
|
||||
|
||||
/** Returns the expected number of 32-bit words in a Universal MIDI Packet, given
|
||||
|
|
|
|||
|
|
@ -48,18 +48,18 @@ public:
|
|||
|
||||
forEachNonSysExTestMessage (random, [&] (const MidiMessage& m)
|
||||
{
|
||||
Packets packets;
|
||||
Conversion::toMidi1 (m, packets);
|
||||
const auto packets = toMidi1 (m);
|
||||
expect (packets.size() == 1);
|
||||
|
||||
// Make sure that the message type is correct
|
||||
expect (Utils::getMessageType (packets.data()[0]) == ((m.getRawData()[0] >> 0x4) == 0xf ? 0x1 : 0x2));
|
||||
const auto msgType = Utils::getMessageType (packets.data()[0]);
|
||||
expect (msgType == ((m.getRawData()[0] >> 0x4) == 0xf ? 0x1 : 0x2));
|
||||
|
||||
translator.dispatch (View {packets.data() },
|
||||
0,
|
||||
[&] (const MidiMessage& roundTripped)
|
||||
[&] (const BytestreamMidiView& roundTripped)
|
||||
{
|
||||
expect (equal (m, roundTripped));
|
||||
expect (equal (m, roundTripped.getMessage()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -68,8 +68,7 @@ public:
|
|||
{
|
||||
{
|
||||
// Zero length message
|
||||
Packets packets;
|
||||
Conversion::toMidi1 (createRandomSysEx (random, 0), packets);
|
||||
const auto packets = toMidi1 (createRandomSysEx (random, 0));
|
||||
expect (packets.size() == 2);
|
||||
|
||||
expect (packets.data()[0] == 0x30000000);
|
||||
|
|
@ -78,51 +77,50 @@ public:
|
|||
|
||||
{
|
||||
const auto message = createRandomSysEx (random, 1);
|
||||
Packets packets;
|
||||
Conversion::toMidi1 (message, packets);
|
||||
const auto packets = toMidi1 (message);
|
||||
expect (packets.size() == 2);
|
||||
|
||||
const auto* sysEx = message.getSysExData();
|
||||
expect (packets.data()[0] == Utils::bytesToWord (0x30, 0x01, sysEx[0], 0));
|
||||
expect (packets.data()[0] == Utils::bytesToWord (std::byte { 0x30 },
|
||||
std::byte { 0x01 },
|
||||
std::byte { sysEx[0] },
|
||||
std::byte { 0 }));
|
||||
expect (packets.data()[1] == 0x00000000);
|
||||
}
|
||||
|
||||
{
|
||||
const auto message = createRandomSysEx (random, 6);
|
||||
Packets packets;
|
||||
Conversion::toMidi1 (message, packets);
|
||||
const auto packets = toMidi1 (message);
|
||||
expect (packets.size() == 2);
|
||||
|
||||
const auto* sysEx = message.getSysExData();
|
||||
expect (packets.data()[0] == Utils::bytesToWord (0x30, 0x06, sysEx[0], sysEx[1]));
|
||||
expect (packets.data()[1] == Utils::bytesToWord (sysEx[2], sysEx[3], sysEx[4], sysEx[5]));
|
||||
expect (packets.data()[0] == Utils::bytesToWord (std::byte { 0x30 }, std::byte { 0x06 }, std::byte { sysEx[0] }, std::byte { sysEx[1] }));
|
||||
expect (packets.data()[1] == Utils::bytesToWord (std::byte { sysEx[2] }, std::byte { sysEx[3] }, std::byte { sysEx[4] }, std::byte { sysEx[5] }));
|
||||
}
|
||||
|
||||
{
|
||||
const auto message = createRandomSysEx (random, 12);
|
||||
Packets packets;
|
||||
Conversion::toMidi1 (message, packets);
|
||||
const auto packets = toMidi1 (message);
|
||||
expect (packets.size() == 4);
|
||||
|
||||
const auto* sysEx = message.getSysExData();
|
||||
expect (packets.data()[0] == Utils::bytesToWord (0x30, 0x16, sysEx[0], sysEx[1]));
|
||||
expect (packets.data()[1] == Utils::bytesToWord (sysEx[2], sysEx[3], sysEx[4], sysEx[5]));
|
||||
expect (packets.data()[2] == Utils::bytesToWord (0x30, 0x36, sysEx[6], sysEx[7]));
|
||||
expect (packets.data()[3] == Utils::bytesToWord (sysEx[8], sysEx[9], sysEx[10], sysEx[11]));
|
||||
expect (packets.data()[0] == Utils::bytesToWord (std::byte { 0x30 }, std::byte { 0x16 }, std::byte { sysEx[0] }, std::byte { sysEx[1] }));
|
||||
expect (packets.data()[1] == Utils::bytesToWord (std::byte { sysEx[2] }, std::byte { sysEx[3] }, std::byte { sysEx[4] }, std::byte { sysEx[5] }));
|
||||
expect (packets.data()[2] == Utils::bytesToWord (std::byte { 0x30 }, std::byte { 0x36 }, std::byte { sysEx[6] }, std::byte { sysEx[7] }));
|
||||
expect (packets.data()[3] == Utils::bytesToWord (std::byte { sysEx[8] }, std::byte { sysEx[9] }, std::byte { sysEx[10] }, std::byte { sysEx[11] }));
|
||||
}
|
||||
|
||||
{
|
||||
const auto message = createRandomSysEx (random, 13);
|
||||
Packets packets;
|
||||
Conversion::toMidi1 (message, packets);
|
||||
const auto packets = toMidi1 (message);
|
||||
expect (packets.size() == 6);
|
||||
|
||||
const auto* sysEx = message.getSysExData();
|
||||
expect (packets.data()[0] == Utils::bytesToWord (0x30, 0x16, sysEx[0], sysEx[1]));
|
||||
expect (packets.data()[1] == Utils::bytesToWord (sysEx[2], sysEx[3], sysEx[4], sysEx[5]));
|
||||
expect (packets.data()[2] == Utils::bytesToWord (0x30, 0x26, sysEx[6], sysEx[7]));
|
||||
expect (packets.data()[3] == Utils::bytesToWord (sysEx[8], sysEx[9], sysEx[10], sysEx[11]));
|
||||
expect (packets.data()[4] == Utils::bytesToWord (0x30, 0x31, sysEx[12], 0));
|
||||
expect (packets.data()[0] == Utils::bytesToWord (std::byte { 0x30 }, std::byte { 0x16 }, std::byte { sysEx[0] }, std::byte { sysEx[1] }));
|
||||
expect (packets.data()[1] == Utils::bytesToWord (std::byte { sysEx[2] }, std::byte { sysEx[3] }, std::byte { sysEx[4] }, std::byte { sysEx[5] }));
|
||||
expect (packets.data()[2] == Utils::bytesToWord (std::byte { 0x30 }, std::byte { 0x26 }, std::byte { sysEx[6] }, std::byte { sysEx[7] }));
|
||||
expect (packets.data()[3] == Utils::bytesToWord (std::byte { sysEx[8] }, std::byte { sysEx[9] }, std::byte { sysEx[10] }, std::byte { sysEx[11] }));
|
||||
expect (packets.data()[4] == Utils::bytesToWord (std::byte { 0x30 }, std::byte { 0x31 }, std::byte { sysEx[12] }, std::byte { 0 }));
|
||||
expect (packets.data()[5] == 0x00000000);
|
||||
}
|
||||
}
|
||||
|
|
@ -133,15 +131,15 @@ public:
|
|||
const auto checkRoundTrip = [&] (const MidiBuffer& expected)
|
||||
{
|
||||
for (const auto meta : expected)
|
||||
Conversion::toMidi1 (meta.getMessage(), packets);
|
||||
Conversion::toMidi1 (ump::BytestreamMidiView (meta), [&] (const auto p) { packets.add (p); });
|
||||
|
||||
MidiBuffer output;
|
||||
converter.dispatch (packets.data(),
|
||||
packets.data() + packets.size(),
|
||||
0,
|
||||
[&] (const MidiMessage& roundTripped)
|
||||
[&] (const BytestreamMidiView& roundTripped)
|
||||
{
|
||||
output.addEvent (roundTripped, int (roundTripped.getTimeStamp()));
|
||||
output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp));
|
||||
});
|
||||
packets.clear();
|
||||
|
||||
|
|
@ -161,8 +159,7 @@ public:
|
|||
beginTest ("UMP SysEx7 messages interspersed with utility messages convert to bytestream");
|
||||
{
|
||||
const auto sysEx = createRandomSysEx (random, 100);
|
||||
Packets originalPackets;
|
||||
Conversion::toMidi1 (sysEx, originalPackets);
|
||||
const auto originalPackets = toMidi1 (sysEx);
|
||||
|
||||
Packets modifiedPackets;
|
||||
|
||||
|
|
@ -183,9 +180,9 @@ public:
|
|||
converter.dispatch (modifiedPackets.data(),
|
||||
modifiedPackets.data() + modifiedPackets.size(),
|
||||
0,
|
||||
[&] (const MidiMessage& roundTripped)
|
||||
[&] (const BytestreamMidiView& roundTripped)
|
||||
{
|
||||
output.addEvent (roundTripped, int (roundTripped.getTimeStamp()));
|
||||
output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp));
|
||||
});
|
||||
|
||||
// All Utility messages should have been ignored
|
||||
|
|
@ -198,8 +195,7 @@ public:
|
|||
beginTest ("UMP SysEx7 messages interspersed with System Realtime messages convert to bytestream");
|
||||
{
|
||||
const auto sysEx = createRandomSysEx (random, 200);
|
||||
Packets originalPackets;
|
||||
Conversion::toMidi1 (sysEx, originalPackets);
|
||||
const auto originalPackets = toMidi1 (sysEx);
|
||||
|
||||
Packets modifiedPackets;
|
||||
MidiBuffer realtimeMessages;
|
||||
|
|
@ -222,9 +218,9 @@ public:
|
|||
converter.dispatch (modifiedPackets.data(),
|
||||
modifiedPackets.data() + modifiedPackets.size(),
|
||||
0,
|
||||
[&] (const MidiMessage& roundTripped)
|
||||
[&] (const BytestreamMidiView& roundTripped)
|
||||
{
|
||||
output.addEvent (roundTripped, int (roundTripped.getTimeStamp()));
|
||||
output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp));
|
||||
});
|
||||
|
||||
const auto numOutputs = output.getNumEvents();
|
||||
|
|
@ -258,8 +254,7 @@ public:
|
|||
beginTest ("UMP SysEx7 messages interspersed with System Realtime and Utility messages convert to bytestream");
|
||||
{
|
||||
const auto sysEx = createRandomSysEx (random, 300);
|
||||
Packets originalPackets;
|
||||
Conversion::toMidi1 (sysEx, originalPackets);
|
||||
const auto originalPackets = toMidi1 (sysEx);
|
||||
|
||||
Packets modifiedPackets;
|
||||
MidiBuffer realtimeMessages;
|
||||
|
|
@ -290,9 +285,9 @@ public:
|
|||
converter.dispatch (modifiedPackets.data(),
|
||||
modifiedPackets.data() + modifiedPackets.size(),
|
||||
0,
|
||||
[&] (const MidiMessage& roundTripped)
|
||||
[&] (const BytestreamMidiView& roundTripped)
|
||||
{
|
||||
output.addEvent (roundTripped, int (roundTripped.getTimeStamp()));
|
||||
output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp));
|
||||
});
|
||||
|
||||
const auto numOutputs = output.getNumEvents();
|
||||
|
|
@ -336,19 +331,14 @@ public:
|
|||
Packets p;
|
||||
|
||||
for (const auto meta : noteOn)
|
||||
Conversion::toMidi1 (meta.getMessage(), p);
|
||||
Conversion::toMidi1 (ump::BytestreamMidiView (meta), [&] (const auto packet) { p.add (packet); });
|
||||
|
||||
return p;
|
||||
}();
|
||||
|
||||
const auto sysEx = createRandomSysEx (random, 300);
|
||||
|
||||
const auto originalPackets = [&]
|
||||
{
|
||||
Packets p;
|
||||
Conversion::toMidi1 (sysEx, p);
|
||||
return p;
|
||||
}();
|
||||
const auto originalPackets = toMidi1 (sysEx);
|
||||
|
||||
const auto modifiedPackets = [&]
|
||||
{
|
||||
|
|
@ -378,9 +368,9 @@ public:
|
|||
converter.dispatch (p.data(),
|
||||
p.data() + p.size(),
|
||||
0,
|
||||
[&] (const MidiMessage& roundTripped)
|
||||
[&] (const BytestreamMidiView& roundTripped)
|
||||
{
|
||||
output.addEvent (roundTripped, int (roundTripped.getTimeStamp()));
|
||||
output.addEvent (roundTripped.getMessage(), int (roundTripped.timestamp));
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -390,8 +380,7 @@ public:
|
|||
expect (equal (output, noteOn));
|
||||
|
||||
const auto newSysEx = createRandomSysEx (random, 300);
|
||||
Packets newSysExPackets;
|
||||
Conversion::toMidi1 (newSysEx, newSysExPackets);
|
||||
const auto newSysExPackets = toMidi1 (newSysEx);
|
||||
|
||||
// If we push another midi event without interrupting it,
|
||||
// it should get through without being modified,
|
||||
|
|
@ -678,12 +667,17 @@ public:
|
|||
|
||||
beginTest ("MIDI 2 -> 1 messages which don't convert");
|
||||
{
|
||||
const uint8_t opcodes[] { 0x0, 0x1, 0x4, 0x5, 0x6, 0xf };
|
||||
const std::byte opcodes[] { std::byte { 0x0 },
|
||||
std::byte { 0x1 },
|
||||
std::byte { 0x4 },
|
||||
std::byte { 0x5 },
|
||||
std::byte { 0x6 },
|
||||
std::byte { 0xf } };
|
||||
|
||||
for (const auto opcode : opcodes)
|
||||
{
|
||||
Packets midi2;
|
||||
midi2.add (PacketX2 { Utils::bytesToWord (0x40, (uint8_t) (opcode << 0x4), 0, 0), 0x0 });
|
||||
midi2.add (PacketX2 { Utils::bytesToWord (std::byte { 0x40 }, std::byte { opcode << 0x4 }, std::byte { 0 }, std::byte { 0 }), 0x0 });
|
||||
checkMidi2ToMidi1Conversion (midi2, {});
|
||||
}
|
||||
}
|
||||
|
|
@ -785,7 +779,7 @@ public:
|
|||
for (const auto cc : CCs)
|
||||
{
|
||||
Packets midi1;
|
||||
midi1.add (PacketX1 { Utils::bytesToWord (0x20, 0xb0, cc, 0x00) });
|
||||
midi1.add (PacketX1 { Utils::bytesToWord (std::byte { 0x20 }, std::byte { 0xb0 }, std::byte { cc }, std::byte { 0x00 }) });
|
||||
|
||||
checkMidi1ToMidi2Conversion (midi1, {});
|
||||
}
|
||||
|
|
@ -874,6 +868,13 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
static Packets toMidi1 (const MidiMessage& msg)
|
||||
{
|
||||
Packets packets;
|
||||
Conversion::toMidi1 (ump::BytestreamMidiView (&msg), [&] (const auto p) { packets.add (p); });
|
||||
return packets;
|
||||
}
|
||||
|
||||
static Packets convertMidi2ToMidi1 (const Packets& midi2)
|
||||
{
|
||||
Packets r;
|
||||
|
|
@ -934,10 +935,10 @@ private:
|
|||
{
|
||||
const auto status = random.nextInt (3);
|
||||
|
||||
return PacketX1 { Utils::bytesToWord (0,
|
||||
uint8_t (status << 0x4),
|
||||
uint8_t (status == 0 ? 0 : random.nextInt (0x100)),
|
||||
uint8_t (status == 0 ? 0 : random.nextInt (0x100))) };
|
||||
return PacketX1 { Utils::bytesToWord (std::byte { 0 },
|
||||
std::byte (status << 0x4),
|
||||
std::byte (status == 0 ? 0 : random.nextInt (0x100)),
|
||||
std::byte (status == 0 ? 0 : random.nextInt (0x100))) };
|
||||
}
|
||||
|
||||
PacketX1 createRandomRealtimeUMP (Random& random)
|
||||
|
|
@ -946,19 +947,19 @@ private:
|
|||
{
|
||||
switch (random.nextInt (6))
|
||||
{
|
||||
case 0: return 0xf8;
|
||||
case 1: return 0xfa;
|
||||
case 2: return 0xfb;
|
||||
case 3: return 0xfc;
|
||||
case 4: return 0xfe;
|
||||
case 5: return 0xff;
|
||||
case 0: return std::byte { 0xf8 };
|
||||
case 1: return std::byte { 0xfa };
|
||||
case 2: return std::byte { 0xfb };
|
||||
case 3: return std::byte { 0xfc };
|
||||
case 4: return std::byte { 0xfe };
|
||||
case 5: return std::byte { 0xff };
|
||||
}
|
||||
|
||||
jassertfalse;
|
||||
return 0x00;
|
||||
return std::byte { 0x00 };
|
||||
}();
|
||||
|
||||
return PacketX1 { Utils::bytesToWord (0x10, uint8_t (status), 0x00, 0x00) };
|
||||
return PacketX1 { Utils::bytesToWord (std::byte { 0x10 }, status, std::byte { 0x00 }, std::byte { 0x00 }) };
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ struct U32ToBytestreamHandler : public U32InputHandler
|
|||
|
||||
void pushMidiData (const uint32_t* begin, const uint32_t* end, double time) override
|
||||
{
|
||||
dispatcher.dispatch (begin, end, time, [this] (const MidiMessage& m)
|
||||
dispatcher.dispatch (begin, end, time, [this] (const BytestreamMidiView& m)
|
||||
{
|
||||
callback.handleIncomingMidiMessage (&input, m);
|
||||
callback.handleIncomingMidiMessage (&input, m.getMessage());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace CoreMidiHelpers
|
|||
{
|
||||
virtual ~SenderBase() noexcept = default;
|
||||
|
||||
virtual void send (MIDIPortRef port, MIDIEndpointRef endpoint, const MidiMessage& m) = 0;
|
||||
virtual void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m) = 0;
|
||||
virtual void send (MIDIPortRef port, MIDIEndpointRef endpoint, ump::Iterator b, ump::Iterator e) = 0;
|
||||
|
||||
virtual ump::MidiProtocol getProtocol() const noexcept = 0;
|
||||
|
|
@ -88,7 +88,7 @@ namespace CoreMidiHelpers
|
|||
: umpConverter (getProtocolForEndpoint (ep))
|
||||
{}
|
||||
|
||||
void send (MIDIPortRef port, MIDIEndpointRef endpoint, const MidiMessage& m) override
|
||||
void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m) override
|
||||
{
|
||||
newSendImpl (port, endpoint, m);
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ namespace CoreMidiHelpers
|
|||
{
|
||||
explicit Sender (MIDIEndpointRef) {}
|
||||
|
||||
void send (MIDIPortRef port, MIDIEndpointRef endpoint, const MidiMessage& m) override
|
||||
void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m) override
|
||||
{
|
||||
oldSendImpl (port, endpoint, m);
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ namespace CoreMidiHelpers
|
|||
{
|
||||
std::for_each (b, e, [&] (const ump::View& v)
|
||||
{
|
||||
bytestreamConverter.convert (v, 0.0, [&] (const MidiMessage& m)
|
||||
bytestreamConverter.convert (v, 0.0, [&] (const ump::BytestreamMidiView& m)
|
||||
{
|
||||
send (port, endpoint, m);
|
||||
});
|
||||
|
|
@ -206,7 +206,7 @@ namespace CoreMidiHelpers
|
|||
private:
|
||||
ump::ToBytestreamConverter bytestreamConverter { 2048 };
|
||||
|
||||
void oldSendImpl (MIDIPortRef port, MIDIEndpointRef endpoint, const MidiMessage& message)
|
||||
void oldSendImpl (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& message)
|
||||
{
|
||||
#if JUCE_IOS
|
||||
const MIDITimeStamp timeStamp = mach_absolute_time();
|
||||
|
|
@ -217,7 +217,7 @@ namespace CoreMidiHelpers
|
|||
HeapBlock<MIDIPacketList> allocatedPackets;
|
||||
MIDIPacketList stackPacket;
|
||||
auto* packetToSend = &stackPacket;
|
||||
auto dataSize = (size_t) message.getRawDataSize();
|
||||
auto dataSize = message.bytes.size();
|
||||
|
||||
if (message.isSysEx())
|
||||
{
|
||||
|
|
@ -234,7 +234,7 @@ namespace CoreMidiHelpers
|
|||
{
|
||||
p->timeStamp = timeStamp;
|
||||
p->length = (UInt16) jmin (maxPacketSize, bytesLeft);
|
||||
memcpy (p->data, message.getRawData() + pos, p->length);
|
||||
memcpy (p->data, message.bytes.data() + pos, p->length);
|
||||
pos += p->length;
|
||||
bytesLeft -= p->length;
|
||||
p = MIDIPacketNext (p);
|
||||
|
|
@ -254,7 +254,7 @@ namespace CoreMidiHelpers
|
|||
auto& p = *(packetToSend->packet);
|
||||
p.timeStamp = timeStamp;
|
||||
p.length = (UInt16) dataSize;
|
||||
memcpy (p.data, message.getRawData(), dataSize);
|
||||
memcpy (p.data, message.bytes.data(), dataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -278,7 +278,7 @@ namespace CoreMidiHelpers
|
|||
: sender (makeImpl (ep))
|
||||
{}
|
||||
|
||||
void send (MIDIPortRef port, MIDIEndpointRef endpoint, const MidiMessage& m)
|
||||
void send (MIDIPortRef port, MIDIEndpointRef endpoint, const ump::BytestreamMidiView& m)
|
||||
{
|
||||
sender->send (port, endpoint, m);
|
||||
}
|
||||
|
|
@ -379,7 +379,7 @@ namespace CoreMidiHelpers
|
|||
endpoint.release();
|
||||
}
|
||||
|
||||
void send (const MidiMessage& m)
|
||||
void send (const ump::BytestreamMidiView& m)
|
||||
{
|
||||
sender.send (*port, *endpoint, m);
|
||||
}
|
||||
|
|
@ -1298,7 +1298,7 @@ MidiOutput::~MidiOutput()
|
|||
|
||||
void MidiOutput::sendMessageNow (const MidiMessage& message)
|
||||
{
|
||||
internal->send (message);
|
||||
internal->send (ump::BytestreamMidiView (&message));
|
||||
}
|
||||
|
||||
MidiDeviceListConnection MidiDeviceListConnection::make (std::function<void()> cb)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue