Sfoglia il codice sorgente

USB MIDI support sending sysex with or without termination bytes

main
PaulStoffregen 6 anni fa
parent
commit
8c6655f312
2 ha cambiato i file con 35 aggiunte e 27 eliminazioni
  1. +30
    -2
      teensy3/usb_midi.c
  2. +5
    -25
      teensy3/usb_midi.h

+ 30
- 2
teensy3/usb_midi.c Vedi File

@@ -138,9 +138,8 @@ void usb_midi_write_packed(uint32_t n)
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;
while (length > 3) {
usb_midi_write_packed(0x04 | cable | (data[0] << 8) | (data[1] << 16) | (data[2] << 24));
@@ -156,6 +155,35 @@ void usb_midi_send_sysex(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)
{
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)
{
if (tx_noautoflush == 0 && tx_packet && tx_packet->index > 0) {

+ 5
- 25
teensy3/usb_midi.h Vedi File

@@ -37,25 +37,6 @@

#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
#if defined(__MKL26Z64__) || defined(__MK20DX128__)
#define USB_MIDI_SYSEX_MAX 60
@@ -68,7 +49,8 @@ used together without conflict.
extern "C" {
#endif
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);
int usb_midi_read(uint32_t channel);
uint32_t usb_midi_available(void);
@@ -180,14 +162,12 @@ class usb_midi_class
// MIDI 4.3 also has version that takes float -1.0 to +1.0
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 (hasTerm) {
if (length > 2) {
usb_midi_send_sysex(data + 1, length - 2, cable);
}
usb_midi_send_sysex_buffer_has_term(data, length, cable);
} 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)) {

Loading…
Annulla
Salva