20
20
21
21
#ifndef BSUMP_H
22
22
#define BSUMP_H
23
+ #include < cstdint>
23
24
24
25
#define BSTOUMP_BUFFER 4
25
26
27
+ #ifndef clear
28
+ #define clear (dest, c,n ) for (uint16_t i = 0 ; i < n ; i ++) dest[i] = c;
29
+ #endif
26
30
27
- #include < cstdint >
31
+ #include " utils.h "
28
32
29
33
class bytestreamToUMP {
30
34
@@ -45,28 +49,235 @@ class bytestreamToUMP{
45
49
uint8_t rpnMsbValue[16 ];
46
50
uint8_t rpnMsb[16 ];
47
51
uint8_t rpnLsb[16 ];
48
-
49
- void bsToUMP (uint8_t b0, uint8_t b1, uint8_t b2);
50
- void increaseWrite ();
51
-
52
52
int readIndex = 0 ;
53
53
int writeIndex = 0 ;
54
54
int bufferLength = 0 ;
55
+
56
+ void bsToUMP (uint8_t b0, uint8_t b1, uint8_t b2){
57
+ uint8_t status = b0 & 0xF0 ;
58
+
59
+ if (b0 >= TIMING_CODE){
60
+ umpMess[writeIndex] = ((UMP_SYSTEM << 4 ) + defaultGroup + 0L ) << 24 ;
61
+ umpMess[writeIndex] += (b0 + 0L ) << 16 ;
62
+ umpMess[writeIndex] += b1 << 8 ;
63
+ umpMess[writeIndex] += b2;
64
+ increaseWrite ();
65
+ }else if (status>=NOTE_OFF && status<=PITCH_BEND){
66
+ if (outputMIDI2){
67
+ uint8_t channel = b0 & 0xF ;
68
+
69
+ if (status==NOTE_ON && b2==0 ){
70
+ status=NOTE_OFF;
71
+ b2 = 0x40 ;
72
+ }
73
+
74
+ umpMess[writeIndex] = ((UMP_M2CVM << 4 ) + defaultGroup + 0L ) << 24 ;
75
+ umpMess[writeIndex] += (status + channel + 0L )<<16 ;
76
+
77
+ if (status==NOTE_ON || status==NOTE_OFF){
78
+ umpMess[writeIndex] += (b1 + 0L ) <<8 ;
79
+ increaseWrite ();
80
+ umpMess[writeIndex] = (M2Utils::scaleUp (b2,7 ,16 ) << 16 );
81
+ increaseWrite ();
82
+ } else if (status == KEY_PRESSURE){
83
+ umpMess[writeIndex] += (b1 + 0L ) <<8 ;
84
+ increaseWrite ();
85
+ umpMess[writeIndex] = (M2Utils::scaleUp (b2,7 ,16 ) << 16 );
86
+ increaseWrite ();
87
+ } else if (status == PITCH_BEND){
88
+ increaseWrite ();
89
+ umpMess[writeIndex] = M2Utils::scaleUp ((b1<<7 ) + b2,14 ,32 );
90
+ increaseWrite ();
91
+ } else if (status == PROGRAM_CHANGE){
92
+ if (bankMSB[channel]!=255 && bankLSB[channel]!=255 ){
93
+ umpMess[writeIndex] += 1 ;
94
+ increaseWrite ();
95
+ umpMess[writeIndex] += (bankMSB[channel] <<8 ) + bankLSB[channel ];
96
+ }
97
+ umpMess[writeIndex] += (b1 + 0L ) << 24 ;
98
+ increaseWrite ();
99
+ } else if (status == CHANNEL_PRESSURE){
100
+ increaseWrite ();
101
+ umpMess[writeIndex] = M2Utils::scaleUp (b1,7 ,32 );
102
+ increaseWrite ();
103
+ } else if (status == CC){
104
+ switch (b1){
105
+ case 0 :
106
+ bankMSB[channel] = b2;
107
+ return ;
108
+ case 32 :
109
+ bankLSB[channel] = b2;
110
+ return ;
111
+
112
+ case 6 : // RPN MSB Value
113
+ if (rpnMsb[channel]==255 || rpnLsb[channel]==255 ){
114
+ return ;
115
+ }
116
+
117
+ if (rpnMode[channel] && rpnMsb[channel] == 0 && (rpnLsb[channel] == 0 || rpnLsb[channel] == 6 )){
118
+ status = rpnMode[channel]? RPN: NRPN;
119
+
120
+ umpMess[writeIndex] = ((UMP_M2CVM << 4 ) + defaultGroup + 0L ) << 24 ;
121
+ umpMess[writeIndex] += (status + channel + 0L )<<16 ;
122
+ umpMess[writeIndex] += ((int )rpnMsb[channel]<<7 ) + rpnLsb[channel] + 0L ;
123
+ increaseWrite ();
124
+ umpMess[writeIndex] = M2Utils::scaleUp (((int )b2<<7 ),14 ,32 );
125
+ increaseWrite ();
55
126
127
+ }else {
128
+ rpnMsbValue[channel] = b2;
129
+ return ;
130
+ }
131
+ break ;
132
+ case 38 : // RPN LSB Value
133
+ if (rpnMsb[channel]==255 || rpnLsb[channel]==255 ){
134
+ return ;
135
+ }
136
+ status = rpnMode[channel]? RPN: NRPN;
137
+
138
+ umpMess[writeIndex] = ((UMP_M2CVM << 4 ) + defaultGroup + 0L ) << 24 ;
139
+ umpMess[writeIndex] += (status + channel + 0L )<<16 ;
140
+ umpMess[writeIndex] += ((int )rpnMsb[channel]<<7 ) + rpnLsb[channel] + 0L ;
141
+ increaseWrite ();
142
+ umpMess[writeIndex] = M2Utils::scaleUp (((int )rpnMsbValue[channel]<<7 ) + b2,14 ,32 );
143
+ increaseWrite ();
144
+ break ;
145
+ case 99 :
146
+ rpnMode[channel] = false ;
147
+ rpnMsb[channel] = b2;
148
+ return ;
149
+ case 98 :
150
+ rpnMode[channel] = false ;
151
+ rpnLsb[channel] = b2;
152
+ return ;
153
+ case 101 :
154
+ rpnMode[channel] = true ;
155
+ rpnMsb[channel] = b2;
156
+ return ;
157
+
158
+ case 100 :
159
+ rpnMode[channel] = true ;
160
+ rpnLsb[channel] = b2;
161
+ return ;
162
+
163
+ default :
164
+ umpMess[writeIndex] += (b1 + 0L ) <<8 ;
165
+ increaseWrite ();
166
+ umpMess[writeIndex] = M2Utils::scaleUp (b2,7 ,32 );
167
+ increaseWrite ();
168
+ break ;
169
+ }
170
+ }
171
+
172
+
173
+ }
174
+ else {
175
+ umpMess[writeIndex] = ((UMP_M1CVM << 4 ) + defaultGroup + 0L ) << 24 ;
176
+ umpMess[writeIndex] += (b0 + 0L ) << 16 ;
177
+ umpMess[writeIndex] += b1 << 8 ;
178
+ umpMess[writeIndex] += b2;
179
+ increaseWrite ();
180
+ }
181
+ }
182
+ }
183
+
184
+ void increaseWrite (){
185
+ bufferLength++;
186
+ writeIndex++;
187
+ if (writeIndex == BSTOUMP_BUFFER) {
188
+ writeIndex = 0 ;
189
+ }
190
+ }
56
191
57
192
public:
58
193
uint8_t defaultGroup = 0 ;
59
194
bool outputMIDI2 = false ;
60
195
61
- bytestreamToUMP ();
196
+ bytestreamToUMP (){
197
+ clear (bankMSB, 255 , sizeof (bankMSB));
198
+ clear (bankLSB, 255 , sizeof (bankLSB));
199
+ clear (rpnMsbValue, 255 , sizeof (rpnMsbValue));
200
+ clear (rpnMsb, 255 , sizeof (rpnMsb));
201
+ clear (rpnLsb, 255 , sizeof (rpnLsb));
202
+ }
62
203
63
- bool availableUMP ();
204
+ bool availableUMP (){
205
+ return bufferLength;
206
+ }
64
207
65
- uint32_t readUMP ();
208
+ uint32_t readUMP (){
209
+ uint32_t mess = umpMess[readIndex];
210
+ bufferLength--; // Decrease buffer size after reading
211
+ readIndex++;
212
+ if (readIndex == BSTOUMP_BUFFER) {
213
+ readIndex = 0 ;
214
+ }
215
+
216
+ return mess;
217
+ }
66
218
67
- void bytestreamParse (uint8_t midi1Byte);
219
+ void bytestreamParse (uint8_t midi1Byte){
220
+
221
+ if (midi1Byte == TUNEREQUEST || midi1Byte >= TIMINGCLOCK) {
222
+ d0 = midi1Byte;
223
+ bsToUMP (midi1Byte,0 ,0 );
224
+ return ;
225
+ }
226
+
227
+ if (midi1Byte & NOTE_OFF) { // Status byte received
228
+ d0 = midi1Byte;
229
+ d1 = 255 ;
230
+
231
+ if (midi1Byte == SYSEX_START){
232
+ sysex7State = 1 ;
233
+ sysex7Pos = 0 ;
234
+ }else
235
+ if (midi1Byte == SYSEX_STOP){
236
+
237
+ umpMess[writeIndex] = ((UMP_SYSEX7 << 4 ) + defaultGroup + 0L ) << 24 ;
238
+ umpMess[writeIndex] += ((sysex7State == 1 ?0 :3 ) + 0L ) << 20 ;
239
+ umpMess[writeIndex] += ((sysex7Pos + 0L ) << 16 ) ;
240
+ umpMess[writeIndex] += (sysex[0 ] << 8 ) + sysex[1 ];
241
+ increaseWrite ();
242
+ umpMess[writeIndex] = ((sysex[2 ] + 0L ) << 24 ) + ((sysex[3 ] + 0L )<< 16 ) + (sysex[4 ] << 8 ) + sysex[5 ];
243
+ increaseWrite ();
244
+
245
+ sysex7State = 0 ;
246
+ clear (sysex, 0 , sizeof (sysex));
247
+ }
248
+ } else if (sysex7State >= 1 ){
249
+ // Check IF new UMP Message Type 3
250
+ if (sysex7Pos%6 == 0 && sysex7Pos !=0 ){
251
+ umpMess[writeIndex] = ((UMP_SYSEX7 << 4 ) + defaultGroup + 0L ) << 24 ;
252
+ umpMess[writeIndex] += (sysex7State + 0L ) << 20 ;
253
+ umpMess[writeIndex] += 6L << 16 ;
254
+ umpMess[writeIndex] += (sysex[0 ] << 8 ) + sysex[1 ];
255
+ increaseWrite ();
256
+ umpMess[writeIndex] = ((sysex[2 ] + 0L ) << 24 ) + ((sysex[3 ] + 0L )<< 16 ) + (sysex[4 ] << 8 ) + sysex[5 ] + 0L ;
257
+ increaseWrite ();
258
+ clear (sysex, 0 , sizeof (sysex));
259
+ sysex7State=2 ;
260
+ sysex7Pos=0 ;
261
+ }
68
262
69
-
263
+ sysex[sysex7Pos] = midi1Byte;
264
+ sysex7Pos++;
265
+ } else if (d1 != 255 ) { // Second byte
266
+ bsToUMP (d0, d1, midi1Byte);
267
+ d1 = 255 ;
268
+ } else if (d0){ // status byte set
269
+ if (
270
+ (d0 & 0xF0 ) == PROGRAM_CHANGE
271
+ || (d0 & 0xF0 ) == CHANNEL_PRESSURE
272
+ || d0 == TIMING_CODE
273
+ || d0 == SONG_SELECT
274
+ ) {
275
+ bsToUMP (d0, midi1Byte, 0 );
276
+ } else if (d0 < SYSEX_START || d0 == SPP) { // First data byte
277
+ d1=midi1Byte;
278
+ }
279
+ }
280
+ }
70
281
};
71
282
72
283
#endif
0 commit comments