mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
consolidate & document Coreaudio midi parser
This commit is contained in:
parent
da0ca57539
commit
b687ed9339
2 changed files with 32 additions and 26 deletions
|
|
@ -17,6 +17,21 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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 <regex.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
@ -105,12 +120,11 @@ CoreAudioBackend::CoreAudioBackend (AudioEngine& e, AudioBackendInfo& info)
|
||||||
, _processed_samples (0)
|
, _processed_samples (0)
|
||||||
, _port_change_flag (false)
|
, _port_change_flag (false)
|
||||||
#ifdef USE_MIDI_PARSER
|
#ifdef USE_MIDI_PARSER
|
||||||
, _event(0)
|
|
||||||
, _first_time(true)
|
|
||||||
, _unbuffered_bytes(0)
|
, _unbuffered_bytes(0)
|
||||||
, _total_bytes(0)
|
, _total_bytes(0)
|
||||||
, _expected_bytes(0)
|
, _expected_bytes(0)
|
||||||
, _status_byte(0)
|
, _status_byte(0)
|
||||||
|
, _parser_bytes(0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
_instance_name = s_instance_name;
|
_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
|
#ifndef USE_MIDI_PARSER
|
||||||
midi_event_put((void*)mbuf, time, data, size);
|
midi_event_put((void*)mbuf, time, data, size);
|
||||||
#else
|
#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) {
|
for (size_t mb = 0; mb < size; ++mb) {
|
||||||
if (_first_time && !(data[mb] & 0x80)) {
|
if (first_time && !(data[mb] & 0x80)) {
|
||||||
// expect a status byte at the beginning or every Packet
|
/* expect a status byte at the beginning or every Packet.
|
||||||
assert (0);
|
*
|
||||||
|
* 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;
|
continue;
|
||||||
}
|
}
|
||||||
_first_time = false;
|
first_time = false;
|
||||||
|
|
||||||
if (midi_process_byte (data[mb])) {
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -445,8 +445,6 @@ class CoreAudioBackend : public AudioBackend {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define USE_MIDI_PARSER
|
|
||||||
|
|
||||||
#ifdef USE_MIDI_PARSER
|
#ifdef USE_MIDI_PARSER
|
||||||
|
|
||||||
bool midi_process_byte (const uint8_t);
|
bool midi_process_byte (const uint8_t);
|
||||||
|
|
@ -462,13 +460,13 @@ class CoreAudioBackend : public AudioBackend {
|
||||||
|
|
||||||
void midi_prepare_byte_event (const uint8_t byte) {
|
void midi_prepare_byte_event (const uint8_t byte) {
|
||||||
_parser_buffer[0] = byte;
|
_parser_buffer[0] = byte;
|
||||||
_event.prepare(1);
|
_parser_bytes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool midi_prepare_buffered_event () {
|
bool midi_prepare_buffered_event () {
|
||||||
const bool result = _unbuffered_bytes == 0;
|
const bool result = _unbuffered_bytes == 0;
|
||||||
if (result) {
|
if (result) {
|
||||||
_event.prepare (_total_bytes);
|
_parser_bytes = _total_bytes;
|
||||||
}
|
}
|
||||||
_total_bytes = 0;
|
_total_bytes = 0;
|
||||||
_unbuffered_bytes = 0;
|
_unbuffered_bytes = 0;
|
||||||
|
|
@ -479,25 +477,12 @@ class CoreAudioBackend : public AudioBackend {
|
||||||
return result;
|
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 _unbuffered_bytes;
|
||||||
size_t _total_bytes;
|
size_t _total_bytes;
|
||||||
size_t _expected_bytes;
|
size_t _expected_bytes;
|
||||||
uint8_t _status_byte;
|
uint8_t _status_byte;
|
||||||
uint8_t _parser_buffer[1024];
|
uint8_t _parser_buffer[128];
|
||||||
|
uint8_t _parser_bytes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}; // class CoreAudioBackend
|
}; // class CoreAudioBackend
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue