Browse Source

Add MIDIDevice_BigBuffer, for high speed MIDI devices

main
PaulStoffregen 5 years ago
parent
commit
a316ad50e8
3 changed files with 67 additions and 28 deletions
  1. +48
    -10
      USBHost_t36.h
  2. +1
    -0
      keywords.txt
  3. +18
    -18
      midi.cpp

+ 48
- 10
USBHost_t36.h View File



//-------------------------------------------------------------------------- //--------------------------------------------------------------------------


class MIDIDevice : public USBDriver {
class MIDIDeviceBase : public USBDriver {
public: public:
enum { SYSEX_MAX_LEN = 290 }; enum { SYSEX_MAX_LEN = 290 };


ActiveSensing = 0xFE, // System Real Time - Active Sensing ActiveSensing = 0xFE, // System Real Time - Active Sensing
SystemReset = 0xFF, // System Real Time - System Reset SystemReset = 0xFF, // System Real Time - System Reset
}; };
MIDIDevice(USBHost &host) { init(); }
MIDIDevice(USBHost *host) { init(); }

MIDIDeviceBase(USBHost &host, uint32_t *rx, uint32_t *tx1, uint32_t *tx2,
uint16_t bufsize, uint32_t *rqueue, uint16_t qsize) :
rx_buffer(rx), tx_buffer1(tx1), tx_buffer2(tx2),
rx_queue(rqueue), max_packet_size(bufsize), rx_queue_size(qsize) {
init();
}
void sendNoteOff(uint8_t note, uint8_t velocity, uint8_t channel, uint8_t cable=0) { void sendNoteOff(uint8_t note, uint8_t velocity, uint8_t channel, uint8_t cable=0) {
send(0x80, note, velocity, channel, cable); send(0x80, note, velocity, channel, cable);
} }
private: private:
Pipe_t *rxpipe; Pipe_t *rxpipe;
Pipe_t *txpipe; Pipe_t *txpipe;
enum { MAX_PACKET_SIZE = 64 };
enum { RX_QUEUE_SIZE = 80 }; // must be more than MAX_PACKET_SIZE/4
uint32_t rx_buffer[MAX_PACKET_SIZE/4];
uint32_t tx_buffer1[MAX_PACKET_SIZE/4];
uint32_t tx_buffer2[MAX_PACKET_SIZE/4];
//enum { MAX_PACKET_SIZE = 64 };
//enum { RX_QUEUE_SIZE = 80 }; // must be more than MAX_PACKET_SIZE/4
//uint32_t rx_buffer[MAX_PACKET_SIZE/4];
//uint32_t tx_buffer1[MAX_PACKET_SIZE/4];
//uint32_t tx_buffer2[MAX_PACKET_SIZE/4];
uint32_t * const rx_buffer;
uint32_t * const tx_buffer1;
uint32_t * const tx_buffer2;
uint16_t rx_size; uint16_t rx_size;
uint16_t tx_size; uint16_t tx_size;
uint32_t rx_queue[RX_QUEUE_SIZE];
//uint32_t rx_queue[RX_QUEUE_SIZE];
uint32_t * const rx_queue;
bool rx_packet_queued; bool rx_packet_queued;
const uint16_t max_packet_size;
const uint16_t rx_queue_size;
uint16_t rx_head; uint16_t rx_head;
uint16_t rx_tail; uint16_t rx_tail;
volatile uint8_t tx1_count; volatile uint8_t tx1_count;
strbuf_t mystring_bufs[1]; strbuf_t mystring_bufs[1];
}; };


class MIDIDevice : public MIDIDeviceBase {
public:
MIDIDevice(USBHost &host) :
MIDIDeviceBase(host, rx, tx1, tx2, MAX_PACKET_SIZE, queue, RX_QUEUE_SIZE) {};
// MIDIDevice(USBHost *host) : ....
private:
enum { MAX_PACKET_SIZE = 64 };
enum { RX_QUEUE_SIZE = 80 }; // must be more than MAX_PACKET_SIZE/4
uint32_t rx[MAX_PACKET_SIZE/4];
uint32_t tx1[MAX_PACKET_SIZE/4];
uint32_t tx2[MAX_PACKET_SIZE/4];
uint32_t queue[RX_QUEUE_SIZE];
};

class MIDIDevice_BigBuffer : public MIDIDeviceBase {
public:
MIDIDevice_BigBuffer(USBHost &host) :
MIDIDeviceBase(host, rx, tx1, tx2, MAX_PACKET_SIZE, queue, RX_QUEUE_SIZE) {};
// MIDIDevice(USBHost *host) : ....
private:
enum { MAX_PACKET_SIZE = 512 };
enum { RX_QUEUE_SIZE = 400 }; // must be more than MAX_PACKET_SIZE/4
uint32_t rx[MAX_PACKET_SIZE/4];
uint32_t tx1[MAX_PACKET_SIZE/4];
uint32_t tx2[MAX_PACKET_SIZE/4];
uint32_t queue[RX_QUEUE_SIZE];
};


//-------------------------------------------------------------------------- //--------------------------------------------------------------------------


class USBSerial: public USBDriver, public Stream { class USBSerial: public USBDriver, public Stream {

+ 1
- 0
keywords.txt View File

KeyboardController KEYWORD1 KeyboardController KEYWORD1
MouseController KEYWORD1 MouseController KEYWORD1
MIDIDevice KEYWORD1 MIDIDevice KEYWORD1
MIDIDevice_BigBuffer KEYWORD1
USBSerial KEYWORD1 USBSerial KEYWORD1
AntPlus KEYWORD1 AntPlus KEYWORD1
JoystickController KEYWORD1 JoystickController KEYWORD1

+ 18
- 18
midi.cpp View File

#define print USBHost::print_ #define print USBHost::print_
#define println USBHost::println_ #define println USBHost::println_


void MIDIDevice::init()
void MIDIDeviceBase::init()
{ {
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t)); contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t)); contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t));
// EP_CONTROL_UNDEFINED 0x00 // EP_CONTROL_UNDEFINED 0x00
// ASSOCIATION_CONTROL 0x01 // ASSOCIATION_CONTROL 0x01


bool MIDIDevice::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
bool MIDIDeviceBase::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
{ {
// only claim at interface level // only claim at interface level
if (type != 1) return false; if (type != 1) return false;
return false; return false;
} }
// if an IN endpoint was found, create its pipe // if an IN endpoint was found, create its pipe
if (rx_ep && rx_size <= MAX_PACKET_SIZE) {
if (rx_ep && rx_size <= max_packet_size) {
rxpipe = new_Pipe(dev, rx_ep_type, rx_ep, 1, rx_size); rxpipe = new_Pipe(dev, rx_ep_type, rx_ep, 1, rx_size);
if (rxpipe) { if (rxpipe) {
rxpipe->callback_function = rx_callback; rxpipe->callback_function = rx_callback;
rxpipe = NULL; rxpipe = NULL;
} }
// if an OUT endpoint was found, create its pipe // if an OUT endpoint was found, create its pipe
if (tx_ep && tx_size <= MAX_PACKET_SIZE) {
if (tx_ep && tx_size <= max_packet_size) {
txpipe = new_Pipe(dev, tx_ep_type, tx_ep, 0, tx_size); txpipe = new_Pipe(dev, tx_ep_type, tx_ep, 0, tx_size);
if (txpipe) { if (txpipe) {
txpipe->callback_function = tx_callback; txpipe->callback_function = tx_callback;
return (rxpipe || txpipe); return (rxpipe || txpipe);
} }


void MIDIDevice::rx_callback(const Transfer_t *transfer)
void MIDIDeviceBase::rx_callback(const Transfer_t *transfer)
{ {
if (transfer->driver) { if (transfer->driver) {
((MIDIDevice *)(transfer->driver))->rx_data(transfer); ((MIDIDevice *)(transfer->driver))->rx_data(transfer);
} }
} }


void MIDIDevice::tx_callback(const Transfer_t *transfer)
void MIDIDeviceBase::tx_callback(const Transfer_t *transfer)
{ {
if (transfer->driver) { if (transfer->driver) {
((MIDIDevice *)(transfer->driver))->tx_data(transfer); ((MIDIDevice *)(transfer->driver))->tx_data(transfer);
} }
} }


void MIDIDevice::rx_data(const Transfer_t *transfer)
void MIDIDeviceBase::rx_data(const Transfer_t *transfer)
{ {
println("MIDIDevice Receive"); println("MIDIDevice Receive");
print(" MIDI Data: "); print(" MIDI Data: ");
for (uint32_t i=0; i < len; i++) { for (uint32_t i=0; i < len; i++) {
uint32_t msg = rx_buffer[i]; uint32_t msg = rx_buffer[i];
if (msg) { if (msg) {
if (++head >= RX_QUEUE_SIZE) head = 0;
if (++head >= rx_queue_size) head = 0;
rx_queue[head] = msg; rx_queue[head] = msg;
} }
} }
rx_head = head; rx_head = head;
rx_tail = tail; rx_tail = tail;
uint32_t avail = (head < tail) ? tail - head - 1 : RX_QUEUE_SIZE - 1 - head + tail;
uint32_t avail = (head < tail) ? tail - head - 1 : rx_queue_size - 1 - head + tail;
//println("rx_size = ", rx_size); //println("rx_size = ", rx_size);
println("avail = ", avail); println("avail = ", avail);
if (avail >= (uint32_t)(rx_size>>2)) { if (avail >= (uint32_t)(rx_size>>2)) {
} }
} }


void MIDIDevice::tx_data(const Transfer_t *transfer)
void MIDIDeviceBase::tx_data(const Transfer_t *transfer)
{ {
println("MIDIDevice transmit complete"); println("MIDIDevice transmit complete");
print(" MIDI Data: "); print(" MIDI Data: ");
} }




void MIDIDevice::disconnect()
void MIDIDeviceBase::disconnect()
{ {
// should rx_queue be cleared? // should rx_queue be cleared?
// as-is, the user can still read MIDI messages // as-is, the user can still read MIDI messages
} }




void MIDIDevice::write_packed(uint32_t data)
void MIDIDeviceBase::write_packed(uint32_t data)
{ {
if (!txpipe) return; if (!txpipe) return;
uint32_t tx_max = tx_size / 4; uint32_t tx_max = tx_size / 4;
} }
} }


void MIDIDevice::send_sysex_buffer_has_term(const uint8_t *data, uint32_t length, uint8_t cable)
void MIDIDeviceBase::send_sysex_buffer_has_term(const uint8_t *data, uint32_t length, uint8_t cable)
{ {
cable = (cable & 0x0F) << 4; cable = (cable & 0x0F) << 4;
while (length > 3) { while (length > 3) {
} }
} }


void MIDIDevice::send_sysex_add_term_bytes(const uint8_t *data, uint32_t length, uint8_t cable)
void MIDIDeviceBase::send_sysex_add_term_bytes(const uint8_t *data, uint32_t length, uint8_t cable)
{ {
cable = (cable & 0x0F) << 4; cable = (cable & 0x0F) << 4;








bool MIDIDevice::read(uint8_t channel)
bool MIDIDeviceBase::read(uint8_t channel)
{ {
uint32_t n, head, tail, avail, ch, type1, type2, b1; uint32_t n, head, tail, avail, ch, type1, type2, b1;


head = rx_head; head = rx_head;
tail = rx_tail; tail = rx_tail;
if (head == tail) return false; if (head == tail) return false;
if (++tail >= RX_QUEUE_SIZE) tail = 0;
if (++tail >= rx_queue_size) tail = 0;
n = rx_queue[tail]; n = rx_queue[tail];
rx_tail = tail; rx_tail = tail;
if (!rx_packet_queued && rxpipe) { if (!rx_packet_queued && rxpipe) {
avail = (head < tail) ? tail - head - 1 : RX_QUEUE_SIZE - 1 - head + tail;
avail = (head < tail) ? tail - head - 1 : rx_queue_size - 1 - head + tail;
if (avail >= (uint32_t)(rx_size>>2)) { if (avail >= (uint32_t)(rx_size>>2)) {
__disable_irq(); __disable_irq();
queue_Data_Transfer(rxpipe, rx_buffer, rx_size, this); queue_Data_Transfer(rxpipe, rx_buffer, rx_size, this);
return false; return false;
} }


void MIDIDevice::sysex_byte(uint8_t b)
void MIDIDeviceBase::sysex_byte(uint8_t b)
{ {
if (handleSysExPartial && msg_sysex_len >= SYSEX_MAX_LEN) { if (handleSysExPartial && msg_sysex_len >= SYSEX_MAX_LEN) {
// when buffer is full, send another chunk to partial handler. // when buffer is full, send another chunk to partial handler.

Loading…
Cancel
Save