LMMS
Loading...
Searching...
No Matches
juce_UMPMidi1ToBytestreamTranslator.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23#ifndef DOXYGEN
24
25namespace juce
26{
28{
29
37{
38public:
42 explicit Midi1ToBytestreamTranslator (int initialBufferSize)
43 {
44 pendingSysExData.reserve (size_t (initialBufferSize));
45 }
46
48 void reset()
49 {
50 pendingSysExData.clear();
51 pendingSysExTime = 0.0;
52 }
53
62 template <typename MessageCallback>
63 void dispatch (const View& packet, double time, MessageCallback&& callback)
64 {
65 const auto firstWord = *packet.data();
66
67 if (! pendingSysExData.empty() && shouldPacketTerminateSysExEarly (firstWord))
68 pendingSysExData.clear();
69
70 switch (packet.size())
71 {
72 case 1:
73 {
74 // Utility messages don't translate to bytestream format
75 if (Utils::getMessageType (firstWord) != 0x00)
76 callback (fromUmp (PacketX1 { firstWord }, time));
77
78 break;
79 }
80
81 case 2:
82 {
83 if (Utils::getMessageType (firstWord) == 0x3)
84 processSysEx (PacketX2 { packet[0], packet[1] }, time, callback);
85
86 break;
87 }
88
89 case 3: // no 3-word packets in the current spec
90 case 4: // no 4-word packets translate to bytestream format
91 default:
92 break;
93 }
94 }
95
106 static MidiMessage fromUmp (const PacketX1& m, double time = 0)
107 {
108 const auto word = m.front();
110
111 const std::array<uint8_t, 3> bytes { { uint8_t ((word >> 0x10) & 0xff),
112 uint8_t ((word >> 0x08) & 0xff),
113 uint8_t ((word >> 0x00) & 0xff) } };
114 const auto numBytes = MidiMessage::getMessageLengthFromFirstByte (bytes.front());
115 return MidiMessage (bytes.data(), numBytes, time);
116 }
117
118private:
119 template <typename MessageCallback>
120 void processSysEx (const PacketX2& packet,
121 double time,
122 MessageCallback&& callback)
123 {
124 switch (getSysEx7Kind (packet[0]))
125 {
127 startSysExMessage (time);
128 pushBytes (packet);
130 break;
131
133 startSysExMessage (time);
134 pushBytes (packet);
135 break;
136
138 if (pendingSysExData.empty())
139 break;
140
141 pushBytes (packet);
142 break;
143
145 if (pendingSysExData.empty())
146 break;
147
148 pushBytes (packet);
150 break;
151 }
152 }
153
154 void pushBytes (const PacketX2& packet)
155 {
156 const auto bytes = SysEx7::getDataBytes (packet);
158 bytes.data.begin(),
159 bytes.data.begin() + bytes.size);
160 }
161
162 void startSysExMessage (double time)
163 {
164 pendingSysExTime = time;
165 pendingSysExData.push_back (0xf0);
166 }
167
168 template <typename MessageCallback>
169 void terminateSysExMessage (MessageCallback&& callback)
170 {
171 pendingSysExData.push_back (0xf7);
173 int (pendingSysExData.size()),
175 pendingSysExData.clear();
176 }
177
179 {
180 return ! (isSysExContinuation (firstWord)
181 || isSystemRealTime (firstWord)
182 || isJROrNOP (firstWord));
183 }
184
186 {
187 return SysEx7::Kind ((word >> 0x14) & 0xf);
188 }
189
190 static bool isJROrNOP (uint32_t word)
191 {
192 return Utils::getMessageType (word) == 0x0;
193 }
194
196 {
197 if (Utils::getMessageType (word) != 0x3)
198 return false;
199
200 const auto kind = getSysEx7Kind (word);
201 return kind == SysEx7::Kind::continuation || kind == SysEx7::Kind::end;
202 }
203
205 {
206 return Utils::getMessageType (word) == 0x1 && ((word >> 0x10) & 0xff) >= 0xf8;
207 }
208
209 std::vector<uint8_t> pendingSysExData;
210
211 double pendingSysExTime = 0.0;
212};
213
214}
215}
216
217#endif
static int getMessageLengthFromFirstByte(uint8 firstByte) noexcept
Definition MidiMessage.cpp:82
Definition juce_MidiMessage.h:35
static bool isJROrNOP(uint32_t word)
Definition juce_UMPMidi1ToBytestreamTranslator.h:190
double pendingSysExTime
Definition juce_UMPMidi1ToBytestreamTranslator.h:211
Midi1ToBytestreamTranslator(int initialBufferSize)
Definition juce_UMPMidi1ToBytestreamTranslator.h:42
void dispatch(const View &packet, double time, MessageCallback &&callback)
Definition juce_UMPMidi1ToBytestreamTranslator.h:63
void startSysExMessage(double time)
Definition juce_UMPMidi1ToBytestreamTranslator.h:162
void terminateSysExMessage(MessageCallback &&callback)
Definition juce_UMPMidi1ToBytestreamTranslator.h:169
void pushBytes(const PacketX2 &packet)
Definition juce_UMPMidi1ToBytestreamTranslator.h:154
static SysEx7::Kind getSysEx7Kind(uint32_t word)
Definition juce_UMPMidi1ToBytestreamTranslator.h:185
static MidiMessage fromUmp(const PacketX1 &m, double time=0)
Definition juce_UMPMidi1ToBytestreamTranslator.h:106
std::vector< uint8_t > pendingSysExData
Definition juce_UMPMidi1ToBytestreamTranslator.h:209
static bool isSystemRealTime(uint32_t word)
Definition juce_UMPMidi1ToBytestreamTranslator.h:204
static bool shouldPacketTerminateSysExEarly(uint32_t firstWord)
Definition juce_UMPMidi1ToBytestreamTranslator.h:178
void processSysEx(const PacketX2 &packet, double time, MessageCallback &&callback)
Definition juce_UMPMidi1ToBytestreamTranslator.h:120
void reset()
Definition juce_UMPMidi1ToBytestreamTranslator.h:48
static bool isSysExContinuation(uint32_t word)
Definition juce_UMPMidi1ToBytestreamTranslator.h:195
Definition juce_UMPView.h:46
uint32_t size() const noexcept
Definition juce_UMPView.cpp:28
const uint32_t * data() const noexcept
Definition juce_UMPView.h:57
unsigned * m
Definition inflate.c:1559
#define jassert(expression)
unsigned int uint32_t
Definition mid.cpp:100
unsigned char uint8_t
Definition mid.cpp:98
Definition juce_UMP_test.cpp:26
Packet< 1 > PacketX1
Definition juce_UMPacket.h:185
Packet< 2 > PacketX2
Definition juce_UMPacket.h:186
Definition carla_juce.cpp:31
short word
Definition private.h:22
Kind
Definition juce_UMPSysEx7.h:49
@ end
Definition juce_UMPSysEx7.h:60
@ continuation
Definition juce_UMPSysEx7.h:57
@ begin
Definition juce_UMPSysEx7.h:54
@ complete
Definition juce_UMPSysEx7.h:51
static PacketBytes getDataBytes(const PacketX2 &packet)
Definition juce_UMPSysEx7.cpp:34
static uint32_t getNumWordsForMessageType(uint32_t)
Definition juce_UMPUtils.cpp:28
static constexpr uint8_t getMessageType(uint32_t w) noexcept
Definition juce_UMPUtils.h:108
RECT const char void(* callback)(const char *droppath))) SWELL_API_DEFINE(BOOL
Definition swell-functions.h:1004
typedef int(UZ_EXP MsgFn)()