diff --git a/libs/backends/coreaudio/coreaudio_backend.cc b/libs/backends/coreaudio/coreaudio_backend.cc index f074ad4c3c..85bd2355bc 100644 --- a/libs/backends/coreaudio/coreaudio_backend.cc +++ b/libs/backends/coreaudio/coreaudio_backend.cc @@ -17,6 +17,21 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* use an additional midi message parser + * + * coreaudio does packetize midi. every packet includes a timestamp. + * With any real midi-device with a phyical layer + * 1 packet = 1 event (no concurrent events are possible on a cable) + * + * Howver, some USB-midi keyboards manage to send concurrent events + * which end up in the same packet (eg. 6 byte message: 2 note-on). + * + * An additional parser is needed to separate them + */ +#define USE_MIDI_PARSER + + #include #include #include @@ -105,12 +120,11 @@ CoreAudioBackend::CoreAudioBackend (AudioEngine& e, AudioBackendInfo& info) , _processed_samples (0) , _port_change_flag (false) #ifdef USE_MIDI_PARSER - , _event(0) - , _first_time(true) , _unbuffered_bytes(0) , _total_bytes(0) , _expected_bytes(0) , _status_byte(0) + , _parser_bytes(0) #endif { _instance_name = s_instance_name; @@ -1719,16 +1733,23 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos #ifndef USE_MIDI_PARSER midi_event_put((void*)mbuf, time, data, size); #else + assert (size < 128);// coremidi limit per packet + bool first_time = true; // this would need to be rememberd per port. for (size_t mb = 0; mb < size; ++mb) { - if (_first_time && !(data[mb] & 0x80)) { - // expect a status byte at the beginning or every Packet - assert (0); + if (first_time && !(data[mb] & 0x80)) { + /* expect a status byte at the beginning or every Packet. + * + * This parser drops messages spanning multiple packets + * (sysex > 127 bytes). + * see also libs/backends/alsa/alsa_rawmidi.cc + * which implements a complete parser per port without this limit. + */ continue; } - _first_time = false; + first_time = false; if (midi_process_byte (data[mb])) { - midi_event_put ((void*)mbuf, time, _parser_buffer, _event._size); + midi_event_put ((void*)mbuf, time, _parser_buffer, _parser_bytes); } } #endif diff --git a/libs/backends/coreaudio/coreaudio_backend.h b/libs/backends/coreaudio/coreaudio_backend.h index 4f4e844442..0d598f586a 100644 --- a/libs/backends/coreaudio/coreaudio_backend.h +++ b/libs/backends/coreaudio/coreaudio_backend.h @@ -445,8 +445,6 @@ class CoreAudioBackend : public AudioBackend { return NULL; } -#define USE_MIDI_PARSER - #ifdef USE_MIDI_PARSER bool midi_process_byte (const uint8_t); @@ -462,13 +460,13 @@ class CoreAudioBackend : public AudioBackend { void midi_prepare_byte_event (const uint8_t byte) { _parser_buffer[0] = byte; - _event.prepare(1); + _parser_bytes = 1; } bool midi_prepare_buffered_event () { const bool result = _unbuffered_bytes == 0; if (result) { - _event.prepare (_total_bytes); + _parser_bytes = _total_bytes; } _total_bytes = 0; _unbuffered_bytes = 0; @@ -479,25 +477,12 @@ class CoreAudioBackend : public AudioBackend { return result; } - struct ParserEvent { - size_t _size; - bool _pending; - ParserEvent (const size_t size) - : _size(size) - , _pending(false) {} - - void prepare (const size_t size) { - _size = size; - _pending = true; - } - } _event; - - bool _first_time; size_t _unbuffered_bytes; size_t _total_bytes; size_t _expected_bytes; uint8_t _status_byte; - uint8_t _parser_buffer[1024]; + uint8_t _parser_buffer[128]; + uint8_t _parser_bytes; #endif }; // class CoreAudioBackend