summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2015-07-01 18:14:48 +0200
committerRobin Gareus <robin@gareus.org>2015-07-01 18:14:48 +0200
commitb687ed9339b160a0ec9b98a3e121079fc52ca42e (patch)
treed3fdc61fc886e54084435e345a671912fc1029d6
parentda0ca575390ff2af6868bc7b9c175c8e3ebe8e03 (diff)
consolidate & document Coreaudio midi parser
-rw-r--r--libs/backends/coreaudio/coreaudio_backend.cc35
-rw-r--r--libs/backends/coreaudio/coreaudio_backend.h23
2 files changed, 32 insertions, 26 deletions
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 <regex.h>
#include <sys/mman.h>
#include <sys/time.h>
@@ -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