diff --git a/libs/backends/coreaudio/coreaudio_backend.cc b/libs/backends/coreaudio/coreaudio_backend.cc index b3459511fb..0e978bff71 100644 --- a/libs/backends/coreaudio/coreaudio_backend.cc +++ b/libs/backends/coreaudio/coreaudio_backend.cc @@ -1577,7 +1577,7 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos pre_process(); // cycle-length in usec - const int64_t nominal_time = 1e6 * n_samples / _samplerate; + const double nominal_time = 1e6 * n_samples / _samplerate; clock1 = g_get_monotonic_time(); @@ -1627,10 +1627,15 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos /* queue outgoing midi */ i = 0; for (std::vector::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it, ++i) { +#if 0 // something's still b0rked with CoreMidiIo::send_events() + const CoreMidiBuffer *src = static_cast(*it)->const_buffer(); + _midiio->send_events (i, nominal_time, (void*)src); +#else // works.. const CoreMidiBuffer *src = static_cast(*it)->const_buffer(); for (CoreMidiBuffer::const_iterator mit = src->begin (); mit != src->end (); ++mit) { _midiio->send_event (i, (*mit)->timestamp() / nominal_time, (*mit)->data(), (*mit)->size()); } +#endif } /* write back audio */ @@ -1644,7 +1649,7 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos /* calc DSP load. */ clock2 = g_get_monotonic_time(); const int64_t elapsed_time = clock2 - clock1; - _dsp_load = elapsed_time / (float) nominal_time; + _dsp_load = elapsed_time / nominal_time; pthread_mutex_unlock (&_process_callback_mutex); return 0; diff --git a/libs/backends/coreaudio/coremidi_io.cc b/libs/backends/coreaudio/coremidi_io.cc index 365bde9457..8b6bad82e8 100644 --- a/libs/backends/coreaudio/coremidi_io.cc +++ b/libs/backends/coreaudio/coremidi_io.cc @@ -20,6 +20,7 @@ #include #include "coremidi_io.h" +#include "coreaudio_backend.h" using namespace ARDOUR; @@ -36,13 +37,16 @@ static void midiInputCallback(const MIDIPacketList *list, void *procRef, void *s } RingBuffer * rb = static_cast *> (srcRef); if (!rb) return; - for (UInt32 i = 0; i < list->numPackets; i++) { - const MIDIPacket *packet = &list->packet[i]; - if (rb->write_space() < sizeof(MIDIPacket)) { + MIDIPacket const *p = &list->packet[0]; + for (UInt32 i = 0; i < list->numPackets; ++i) { + uint32_t len = ((p->length + 3)&~3) + sizeof(MIDITimeStamp) + sizeof(UInt16); + if (rb->write_space() < sizeof(uint32_t) + len) { fprintf(stderr, "CoreMIDI: dropped MIDI event\n"); continue; } - rb->write((uint8_t*)packet, sizeof(MIDIPacket)); + rb->write ((uint8_t*)&len, sizeof(uint32_t)); + rb->write ((uint8_t*)p, len); + p = MIDIPacketNext (p); } } @@ -176,10 +180,16 @@ CoreMidiIo::recv_event (uint32_t port, double cycle_time_us, uint64_t &time, uin } assert(port < _n_midi_in); - while (_rb[port]->read_space() >= sizeof(MIDIPacket)) { + const size_t minsize = 1 + sizeof(uint32_t) + sizeof(MIDITimeStamp) + sizeof(UInt16); + + while (_rb[port]->read_space() > minsize) { MIDIPacket packet; - size_t rv = _rb[port]->read((uint8_t*)&packet, sizeof(MIDIPacket)); - assert(rv == sizeof(MIDIPacket)); + size_t rv; + uint32_t s = 0; + rv = _rb[port]->read((uint8_t*)&s, sizeof(uint32_t)); + assert(rv == sizeof(uint32_t)); + rv = _rb[port]->read((uint8_t*)&packet, s); + assert(rv == s); _input_queue[port].push_back(boost::shared_ptr(new _CoreMIDIPacket (&packet))); } @@ -212,6 +222,40 @@ CoreMidiIo::recv_event (uint32_t port, double cycle_time_us, uint64_t &time, uin return 0; } +int +CoreMidiIo::send_events (uint32_t port, double timescale, const void *b) +{ + if (!_active || _time_at_cycle_start == 0) { + return 0; + } + + assert(port < _n_midi_out); + const UInt64 ts = AudioConvertHostTimeToNanos(_time_at_cycle_start); + + const CoreMidiBuffer *src = static_cast(b); + + int32_t bytes[8192]; // int for alignment + MIDIPacketList *mpl = (MIDIPacketList*)bytes; + MIDIPacket *cur = MIDIPacketListInit(mpl); + + for (CoreMidiBuffer::const_iterator mit = src->begin (); mit != src->end (); ++mit) { + assert((*mit)->size() < 256); + cur = MIDIPacketListAdd(mpl, sizeof(bytes), cur, + AudioConvertNanosToHostTime(ts + (*mit)->timestamp() / timescale), + (*mit)->size(), (*mit)->data()); + if (!cur) { +#ifndef DEBUG + printf("CoreMidi: Packet list overflow, dropped events\n"); +#endif + break; + } + } + if (mpl->numPackets > 0) { + MIDISend(_output_ports[port], _output_endpoints[port], mpl); + } + return 0; +} + int CoreMidiIo::send_event (uint32_t port, double reltime_us, const uint8_t *d, const size_t s) { diff --git a/libs/backends/coreaudio/coremidi_io.h b/libs/backends/coreaudio/coremidi_io.h index b5eda1c2fd..21806ab4fd 100644 --- a/libs/backends/coreaudio/coremidi_io.h +++ b/libs/backends/coreaudio/coremidi_io.h @@ -75,6 +75,7 @@ public: void start_cycle (); int send_event (uint32_t, double, const uint8_t *, const size_t); + int send_events (uint32_t, double, const void *); size_t recv_event (uint32_t, double, uint64_t &, uint8_t *, size_t &); uint32_t n_midi_inputs (void) const { return _n_midi_in; }