@@ -93,18 +93,18 @@ typedef struct ATTR_PACKED
9393{
9494 midi_header_t header;
9595 midi_timestamp_t timestamp;
96- uint8_t data[20 ];
96+ uint8_t data[BLE_MIDI_TX_BUFFER_SIZE ];
9797} midi_event_packet_t ;
9898
99- VERIFY_STATIC ( sizeof (midi_event_packet_t ) == 22 );
99+ VERIFY_STATIC ( sizeof (midi_event_packet_t ) == (BLE_MIDI_TX_BUFFER_SIZE + 2 ) );
100100
101101typedef struct ATTR_PACKED
102102{
103103 midi_header_t header;
104- uint8_t data[20 ];
104+ uint8_t data[BLE_MIDI_TX_BUFFER_SIZE ];
105105} midi_split_packet_t ;
106106
107- VERIFY_STATIC ( sizeof (midi_split_packet_t ) == 21 );
107+ VERIFY_STATIC ( sizeof (midi_split_packet_t ) == (BLE_MIDI_TX_BUFFER_SIZE + 1 ) );
108108
109109void blemidi_write_cb (BLECharacteristic& chr, uint8_t * data, uint16_t len, uint16_t offset);
110110
@@ -216,94 +216,63 @@ int BLEMidi::read ( void )
216216 return _rxd_fifo.read (&ch) ? (int ) ch : EOF;
217217}
218218
219- bool BLEMidi::oneByteMessage ( uint8_t status )
220- {
221- // system messages
222- if (status >= 0xF4 && status <= 0xFF ) return true ;
223-
224- // system common
225- if (status == 0xF1 ) return true ;
226-
227- return false ;
228- }
229-
230- bool BLEMidi::twoByteMessage ( uint8_t status )
231- {
232- // program change, aftertouch
233- if (status >= 0xC0 && status <= 0xDF ) return true ;
234-
235- // song select
236- if (status == 0xF3 ) return true ;
237-
238- return false ;
239- }
240-
241- bool BLEMidi::threeByteMessage ( uint8_t status )
242- {
243- // note off, note on, aftertouch, control change
244- if (status >= 0x80 && status <= 0xBF ) return true ;
245-
246- // pitch wheel change
247- if (status >= 0xE0 && status <= 0xEF ) return true ;
248-
249- // song position pointer
250- if (status == 0xF2 ) return true ;
251-
252- return false ;
253- }
254219
255220size_t BLEMidi::write ( uint8_t b )
256221{
257222 // MIDI Library will write event byte by byte.
258223 // We need to buffer the data until we have a full event,
259- // or until we reach the BLE payload limit.
224+ // or until we reach the TX buffer limit.
260225 static uint8_t count = 0 ;
261- static uint8_t buf[16 ] = { 0 };
262-
263- buf[count++] = b;
264-
265- // if we are at the end of a sysex message
266- // or at the end of the buffer
267- if ((b == 0xF7 ) || (count == 16 ))
226+ static uint8_t buf[BLE_MIDI_TX_BUFFER_SIZE] = { 0 };
227+
228+ // the current byte is a sysex end status message,
229+ // and we still have an existing buffer. send the
230+ // existing buffer and clear it so we can send
231+ // the sysex end status message with the appropriate
232+ // BLE header and timestamp bytes.
233+ if (b == 0xF7 && count > 0 )
268234 {
269-
270- // send full event if the first byte is a status byte
271- if (bitRead (buf[0 ], 7 )) {
235+ // send and clear the last of the existing buffer.
236+ // it should contain the final bytes in the sysex payload.
237+ if (bitRead (buf[0 ], 7 ))
272238 send (buf, count);
273- } else {
239+ else
274240 sendSplit (buf, count);
275- }
276241
277242 // reset buffer
278243 buf[0 ] = 0 ;
279244 count = 0 ;
280-
281- return 1 ;
282-
283245 }
284246
285- // don't send if this is a full or split sysex
286- if (buf[0 ] == 0xF0 || ! bitRead (buf[0 ], 7 ))
287- return 1 ;
288-
289- // don't send if we don't have 1 byte
290- if (oneByteMessage (buf[0 ]) && count != 1 )
291- return 1 ;
292-
293- // don't send if we don't have 2 bytes
294- if (twoByteMessage (buf[0 ]) && count != 2 )
295- return 1 ;
247+ // add the current byte to the buffer
248+ buf[count++] = b;
296249
297- // don't send if we don't have 3 bytes
298- if (threeByteMessage (buf[0 ]) && count != 3 )
299- return 1 ;
250+ // send matching 1, 2, or 3 byte messages
251+ // and clear the buffer
252+ if ( (oneByteMessage (buf[0 ]) && count == 1 ) ||
253+ (twoByteMessage (buf[0 ]) && count == 2 ) ||
254+ (threeByteMessage (buf[0 ]) && count == 3 ) )
255+ {
256+ send (buf, count);
257+ // reset buffer
258+ buf[0 ] = 0 ;
259+ count = 0 ;
260+ }
300261
301- // send full event
302- send (buf, count);
262+ // if we have a full buffer at this point, we
263+ // need to send a full or split sysex message
264+ // and reset the buffer.
265+ if (count == BLE_MIDI_TX_BUFFER_SIZE)
266+ {
267+ if (bitRead (buf[0 ], 7 ))
268+ send (buf, count);
269+ else
270+ sendSplit (buf, count);
303271
304- // reset buffer
305- buf[0 ] = 0 ;
306- count = 0 ;
272+ // reset buffer
273+ buf[0 ] = 0 ;
274+ count = 0 ;
275+ }
307276
308277 return 1 ;
309278
@@ -325,6 +294,48 @@ void BLEMidi::flush ( void )
325294 _rxd_fifo.clear ();
326295}
327296
297+ /* ------------------------------------------------------------------*/
298+ /* Message Type Helpers
299+ *------------------------------------------------------------------*/
300+ bool BLEMidi::oneByteMessage ( uint8_t status )
301+ {
302+ // system messages
303+ if (status >= 0xF4 && status <= 0xFF ) return true ;
304+
305+ // system common
306+ if (status == 0xF1 ) return true ;
307+
308+ // sysex end
309+ if (status == 0xF7 ) return true ;
310+
311+ return false ;
312+ }
313+
314+ bool BLEMidi::twoByteMessage ( uint8_t status )
315+ {
316+ // program change, aftertouch
317+ if (status >= 0xC0 && status <= 0xDF ) return true ;
318+
319+ // song select
320+ if (status == 0xF3 ) return true ;
321+
322+ return false ;
323+ }
324+
325+ bool BLEMidi::threeByteMessage ( uint8_t status )
326+ {
327+ // note off, note on, aftertouch, control change
328+ if (status >= 0x80 && status <= 0xBF ) return true ;
329+
330+ // pitch wheel change
331+ if (status >= 0xE0 && status <= 0xEF ) return true ;
332+
333+ // song position pointer
334+ if (status == 0xF2 ) return true ;
335+
336+ return false ;
337+ }
338+
328339/* ------------------------------------------------------------------*/
329340/* Send Event (notify)
330341 *------------------------------------------------------------------*/
0 commit comments