Browse Source

USB MIDI support sending sysex with or without termination bytes

main
PaulStoffregen 6 years ago
parent
commit
8c6655f312
2 changed files with 35 additions and 27 deletions
  1. +30
    -2
      teensy3/usb_midi.c
  2. +5
    -25
      teensy3/usb_midi.h

+ 30
- 2
teensy3/usb_midi.c View File

tx_noautoflush = 0; tx_noautoflush = 0;
} }


void usb_midi_send_sysex(const uint8_t *data, uint32_t length, uint8_t cable)
void usb_midi_send_sysex_buffer_has_term(const uint8_t *data, uint32_t length, uint8_t cable)
{ {
// TODO: MIDI 2.5 lib automatically adds start and stop bytes
cable = (cable & 0x0F) << 4; cable = (cable & 0x0F) << 4;
while (length > 3) { while (length > 3) {
usb_midi_write_packed(0x04 | cable | (data[0] << 8) | (data[1] << 16) | (data[2] << 24)); usb_midi_write_packed(0x04 | cable | (data[0] << 8) | (data[1] << 16) | (data[2] << 24));
} }
} }


void usb_midi_send_sysex_add_term_bytes(const uint8_t *data, uint32_t length, uint8_t cable)
{
cable = (cable & 0x0F) << 4;

if (length == 0) {
usb_midi_write_packed(0x06 | cable | (0xF0 << 8) | (0xF7 << 16));
return;
} else if (length == 1) {
usb_midi_write_packed(0x07 | cable | (0xF0 << 8) | (data[0] << 16) | (0xF7 << 24));
return;
} else {
usb_midi_write_packed(0x04 | cable | (0xF0 << 8) | (data[0] << 16) | (data[1] << 24));
data += 2;
length -= 2;
}
while (length >= 3) {
usb_midi_write_packed(0x04 | cable | (data[0] << 8) | (data[1] << 16) | (data[2] << 24));
data += 3;
length -= 3;
}
if (length == 2) {
usb_midi_write_packed(0x07 | cable | (data[0] << 8) | (data[1] << 16) | (0xF7 << 24));
} else if (length == 1) {
usb_midi_write_packed(0x06 | cable | (data[0] << 8) | (0xF7 << 16));
} else {
usb_midi_write_packed(0x05 | cable | (0xF7 << 8));
}
}

void usb_midi_flush_output(void) void usb_midi_flush_output(void)
{ {
if (tx_noautoflush == 0 && tx_packet && tx_packet->index > 0) { if (tx_noautoflush == 0 && tx_packet && tx_packet->index > 0) {

+ 5
- 25
teensy3/usb_midi.h View File



#include <inttypes.h> #include <inttypes.h>


/*
These were originally meant to allow programs written for
Francois Best's MIDI library to be easily used with
Teensy's usbMIDI which implements the same API. However,
the MIDI library definitions have changed, so these names
now conflict. They've never been documented (the PJRC web
page documents usbMIDI.getType() in numbers) so they are
now commented out so usbMIDI and the MIDI library can be
used together without conflict.
#define NoteOff 0
#define NoteOn 1
#define AfterTouchPoly 2
#define ControlChange 3
#define ProgramChange 4
#define AfterTouchChannel 5
#define PitchBend 6
#define SystemExclusive 7
*/

// maximum sysex length we can receive // maximum sysex length we can receive
#if defined(__MKL26Z64__) || defined(__MK20DX128__) #if defined(__MKL26Z64__) || defined(__MK20DX128__)
#define USB_MIDI_SYSEX_MAX 60 #define USB_MIDI_SYSEX_MAX 60
extern "C" { extern "C" {
#endif #endif
void usb_midi_write_packed(uint32_t n); void usb_midi_write_packed(uint32_t n);
void usb_midi_send_sysex(const uint8_t *data, uint32_t length, uint8_t cable);
void usb_midi_send_sysex_buffer_has_term(const uint8_t *data, uint32_t length, uint8_t cable);
void usb_midi_send_sysex_add_term_bytes(const uint8_t *data, uint32_t length, uint8_t cable);
void usb_midi_flush_output(void); void usb_midi_flush_output(void);
int usb_midi_read(uint32_t channel); int usb_midi_read(uint32_t channel);
uint32_t usb_midi_available(void); uint32_t usb_midi_available(void);
// MIDI 4.3 also has version that takes float -1.0 to +1.0 // MIDI 4.3 also has version that takes float -1.0 to +1.0
send(0xE0, value, value >> 7, channel, cable); send(0xE0, value, value >> 7, channel, cable);
} }
void sendSysEx(uint32_t length, const uint8_t *data, bool hasTerm=false, uint8_t cable=0) __attribute__((always_inline)) {
void sendSysEx(uint32_t length, const uint8_t *data, bool hasTerm=true, uint8_t cable=0) __attribute__((always_inline)) {
if (cable >= MIDI_NUM_CABLES) return; if (cable >= MIDI_NUM_CABLES) return;
if (hasTerm) { if (hasTerm) {
if (length > 2) {
usb_midi_send_sysex(data + 1, length - 2, cable);
}
usb_midi_send_sysex_buffer_has_term(data, length, cable);
} else { } else {
usb_midi_send_sysex(data, length, cable);
usb_midi_send_sysex_add_term_bytes(data, length, cable);
} }
} }
void sendRealTime(uint8_t type, uint8_t cable=0) __attribute__((always_inline)) __attribute__((always_inline)) { void sendRealTime(uint8_t type, uint8_t cable=0) __attribute__((always_inline)) __attribute__((always_inline)) {

Loading…
Cancel
Save