summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-08-05 15:21:51 +0200
committerRobin Gareus <robin@gareus.org>2017-08-05 15:36:36 +0200
commitf4c76f89d3a3c4687e7292b5458c2c680c51cba4 (patch)
tree490066763a55a10f0561e69b9497c8281b483c12 /libs
parent59a63a08f99e1cb17ba5775afa4ad514cc5b163f (diff)
Coreaudio backend RT-safe MIDI buffer allocation
Diffstat (limited to 'libs')
-rw-r--r--libs/backends/coreaudio/coreaudio_backend.cc54
-rw-r--r--libs/backends/coreaudio/coreaudio_backend.h10
2 files changed, 30 insertions, 34 deletions
diff --git a/libs/backends/coreaudio/coreaudio_backend.cc b/libs/backends/coreaudio/coreaudio_backend.cc
index 060c7b5db3..be8005c690 100644
--- a/libs/backends/coreaudio/coreaudio_backend.cc
+++ b/libs/backends/coreaudio/coreaudio_backend.cc
@@ -114,6 +114,8 @@ CoreAudioBackend::CoreAudioBackend (AudioEngine& e, AudioBackendInfo& info)
pthread_mutex_init (&_freewheel_mutex, 0);
pthread_cond_init (&_freewheel_signal, 0);
+ _port_connection_queue.reserve (128);
+
_pcmio = new CoreAudioPCM ();
_midiio = new CoreMidiIo ();
@@ -1415,11 +1417,11 @@ CoreAudioBackend::midi_event_get (
if (event_index >= source.size ()) {
return -1;
}
- CoreMidiEvent * const event = source[event_index].get ();
+ CoreMidiEvent const& event = source[event_index].get ();
- timestamp = event->timestamp ();
- size = event->size ();
- *buf = event->data ();
+ timestamp = event.timestamp ();
+ size = event.size ();
+ *buf = event.data ();
return 0;
}
@@ -1430,15 +1432,18 @@ CoreAudioBackend::_midi_event_put (
const uint8_t* buffer, size_t size)
{
if (!buffer || !port_buffer) return -1;
+ if (size >= MaxCoreMidiEventSize) {
+ return -1;
+ }
CoreMidiBuffer& dst = * static_cast<CoreMidiBuffer*>(port_buffer);
- if (dst.size () && (pframes_t)dst.back ()->timestamp () > timestamp) {
#ifndef NDEBUG
+ if (dst.size () && (pframes_t)dst.back ().timestamp () > timestamp) {
// nevermind, ::get_buffer() sorts events
fprintf (stderr, "CoreMidiBuffer: unordered event: %d > %d\n",
- (pframes_t)dst.back ()->timestamp (), timestamp);
-#endif
+ (pframes_t)dst.back ().timestamp (), timestamp);
}
- dst.push_back (boost::shared_ptr<CoreMidiEvent>(new CoreMidiEvent (timestamp, buffer, size)));
+#endif
+ dst.push_back (CoreMidiEvent (timestamp, buffer, size));
return 0;
}
@@ -1802,7 +1807,7 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos
continue;
}
uint64_t time_ns;
- uint8_t data[128]; // matches CoreMidi's MIDIPacket
+ uint8_t data[MaxCoreMidiEventSize];
size_t size = sizeof(data);
port->clear_events ();
@@ -1845,15 +1850,10 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos
/* queue outgoing midi */
i = 0;
for (std::vector<CoreBackendPort*>::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<const CoreMidiPort*>(*it)->const_buffer();
- _midiio->send_events (i, nominal_time, (void*)src);
-#else // works..
const CoreMidiBuffer *src = static_cast<const CoreMidiPort*>(*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());
+ _midiio->send_event (i,tamp (), mit->data (), mit->size ());
}
-#endif
}
/* write back audio */
@@ -2159,13 +2159,16 @@ CoreMidiPort::CoreMidiPort (CoreAudioBackend &b, const std::string& name, PortFl
{
_buffer[0].clear ();
_buffer[1].clear ();
+
+ _buffer[0].reserve (256);
+ _buffer[1].reserve (256);
}
CoreMidiPort::~CoreMidiPort () { }
struct MidiEventSorter {
- bool operator() (const boost::shared_ptr<CoreMidiEvent>& a, const boost::shared_ptr<CoreMidiEvent>& b) {
- return *a < *b;
+ bool operator() (CoreMidiEvent const& a, CoreMidiEvent const& b) {
+ return a < b;
}
};
@@ -2179,7 +2182,7 @@ void* CoreMidiPort::get_buffer (pframes_t /* nframes */)
++i) {
const CoreMidiBuffer * src = static_cast<const CoreMidiPort*>(*i)->const_buffer ();
for (CoreMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
- (_buffer[_bufperiod]).push_back (boost::shared_ptr<CoreMidiEvent>(new CoreMidiEvent (**it)));
+ (_buffer[_bufperiod]).push_back (*it);
}
}
std::stable_sort ((_buffer[_bufperiod]).begin (), (_buffer[_bufperiod]).end (), MidiEventSorter());
@@ -2348,10 +2351,8 @@ CoreMidiPort::process_byte(const uint64_t time, const uint8_t byte)
CoreMidiEvent::CoreMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size)
: _size (size)
, _timestamp (timestamp)
- , _data (0)
{
- if (size > 0) {
- _data = (uint8_t*) malloc (size);
+ if (size > 0 && size < MaxCoreMidiEventSize) {
memcpy (_data, data, size);
}
}
@@ -2359,14 +2360,9 @@ CoreMidiEvent::CoreMidiEvent (const pframes_t timestamp, const uint8_t* data, si
CoreMidiEvent::CoreMidiEvent (const CoreMidiEvent& other)
: _size (other.size ())
, _timestamp (other.timestamp ())
- , _data (0)
{
- if (other.size () && other.const_data ()) {
- _data = (uint8_t*) malloc (other.size ());
- memcpy (_data, other.const_data (), other.size ());
+ if (other._size > 0) {
+ assert (other._size < MaxCoreMidiEventSize);
+ memcpy (_data, other._data, other._size);
}
};
-
-CoreMidiEvent::~CoreMidiEvent () {
- free (_data);
-};
diff --git a/libs/backends/coreaudio/coreaudio_backend.h b/libs/backends/coreaudio/coreaudio_backend.h
index 1a302bc749..5a036117ac 100644
--- a/libs/backends/coreaudio/coreaudio_backend.h
+++ b/libs/backends/coreaudio/coreaudio_backend.h
@@ -38,6 +38,8 @@
#include "coreaudio_pcmio.h"
#include "coremidi_io.h"
+#define MaxCoreMidiEventSize 128 // matches CoreMidi's MIDIPacket
+
namespace ARDOUR {
class CoreAudioBackend;
@@ -46,19 +48,17 @@ class CoreMidiEvent {
public:
CoreMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size);
CoreMidiEvent (const CoreMidiEvent& other);
- ~CoreMidiEvent ();
size_t size () const { return _size; };
pframes_t timestamp () const { return _timestamp; };
- const unsigned char* const_data () const { return _data; };
- unsigned char* data () { return _data; };
+ const uint8_t* () const { return _data; };
bool operator< (const CoreMidiEvent &other) const { return timestamp () < other.timestamp (); };
private:
size_t _size;
pframes_t _timestamp;
- uint8_t *_data;
+ uint8_t _data[MaxCoreMidiEventSize];
};
-typedef std::vector<boost::shared_ptr<CoreMidiEvent> > CoreMidiBuffer;
+typedef std::vector<CoreMidiEvent> CoreMidiBuffer;
class CoreBackendPort {
protected: