cont’d work on the coreaudio backend & cleanup

This commit is contained in:
Robin Gareus 2015-03-06 03:21:47 +01:00
parent 408090adce
commit 6b87e706eb
7 changed files with 854 additions and 319 deletions

View file

@ -41,6 +41,13 @@ std::vector<std::string> CoreAudioBackend::_midi_options;
std::vector<AudioBackend::DeviceStatus> CoreAudioBackend::_audio_device_status;
std::vector<AudioBackend::DeviceStatus> CoreAudioBackend::_midi_device_status;
static void hw_changed_callback_ptr (void *arg)
{
CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
d->hw_changed_callback();
}
CoreAudioBackend::CoreAudioBackend (AudioEngine& e, AudioBackendInfo& info)
: AudioBackend (e, info)
, _run (false)
@ -70,6 +77,7 @@ CoreAudioBackend::CoreAudioBackend (AudioEngine& e, AudioBackendInfo& info)
_pcmio = new CoreAudioPCM ();
_midiio = new CoreMidiIo ();
_pcmio->set_hw_changed_callback (hw_changed_callback_ptr, this);
_pcmio->discover();
_midiio->discover();
}
@ -114,25 +122,16 @@ CoreAudioBackend::enumerate_devices () const
std::vector<float>
CoreAudioBackend::available_sample_rates (const std::string&) const
{
// TODO ask _pcmio for available rates
std::vector<float> sr;
sr.push_back (44100.0);
sr.push_back (48000.0);
_pcmio->available_sample_rates(name_to_id(_audio_device), sr);
return sr;
}
std::vector<uint32_t>
CoreAudioBackend::available_buffer_sizes (const std::string&) const
{
// TODO ask _pcmio for available rates
std::vector<uint32_t> bs;
bs.push_back (64);
bs.push_back (128);
bs.push_back (256);
bs.push_back (512);
bs.push_back (1024);
bs.push_back (2048);
bs.push_back (4096);
_pcmio->available_buffer_sizes(name_to_id(_audio_device), bs);
return bs;
}
@ -164,6 +163,8 @@ int
CoreAudioBackend::set_device_name (const std::string& d)
{
_audio_device = d;
const float sr = _pcmio->current_sample_rate(name_to_id(_audio_device));
if (sr > 0) { set_sample_rate(sr); }
return 0;
}
@ -171,6 +172,7 @@ int
CoreAudioBackend::set_sample_rate (float sr)
{
if (sr <= 0) { return -1; }
// TODO check if it's in the list of valid SR
_samplerate = sr;
engine.sample_rate_change (sr);
return 0;
@ -363,6 +365,12 @@ CoreAudioBackend::midi_device_enabled (std::string const device) const
return nfo->enabled;
}
void
CoreAudioBackend::launch_control_app ()
{
_pcmio->launch_control_app(name_to_id(_audio_device));
}
/* State Control */
static void * pthread_freewheel (void *arg)
@ -391,7 +399,6 @@ static void midi_port_change (void *arg)
d->coremidi_rediscover ();
}
int
CoreAudioBackend::_start (bool for_latency_measurement)
{
@ -414,21 +421,7 @@ CoreAudioBackend::_start (bool for_latency_measurement)
_ports.clear();
}
#if 0
assert(_rmidi_in.size() == 0);
assert(_rmidi_out.size() == 0);
#endif
uint32_t device_id = UINT32_MAX;
std::map<size_t, std::string> devices;
_pcmio->device_list(devices);
for (std::map<size_t, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
if (i->second == _audio_device) {
device_id = i->first;
break;
}
}
uint32_t device_id = name_to_id(_audio_device);
assert(_active_ca == false);
assert(_active_fw == false);
@ -485,11 +478,8 @@ CoreAudioBackend::_start (bool for_latency_measurement)
_run = true;
_port_change_flag = false;
printf("MIDI: %s\n", _midi_driver_option.c_str());
if (_midi_driver_option == _("CoreMidi")) {
//register_system_midi_ports();
_midiio->setPortChangedCallback(midi_port_change, this);
_midiio->set_port_changed_callback(midi_port_change, this);
_midiio->discover();
}
@ -510,7 +500,6 @@ CoreAudioBackend::_start (bool for_latency_measurement)
engine.reconnect_ports ();
if (pthread_create (&_freeewheel_thread, NULL, pthread_freewheel, this))
{
PBD::error << _("CoreAudioBackend: failed to create process thread.") << endmsg;
@ -523,13 +512,11 @@ CoreAudioBackend::_start (bool for_latency_measurement)
while ((!_active_ca || !_active_fw) && --timeout > 0) { Glib::usleep (1000); }
if (timeout == 0) {
printf("CoreAudioBackend: failed to start.");
PBD::error << _("CoreAudioBackend: failed to start.") << endmsg;
}
if (!_active_fw) {
PBD::error << _("CoreAudioBackend: failed to start freewheeling thread.") << endmsg;
printf("CoreAudioBackend: fw .\n");
_run = false;
_pcmio->pcm_stop();
unregister_ports();
@ -539,7 +526,6 @@ CoreAudioBackend::_start (bool for_latency_measurement)
}
if (!_active_ca) {
printf("CoreAudioBackend: ca .\n");
PBD::error << _("CoreAudioBackend: failed to start coreaudio.") << endmsg;
stop();
_run = false;
@ -560,28 +546,13 @@ CoreAudioBackend::stop ()
_run = false;
_pcmio->pcm_stop();
_midiio->setPortChangedCallback(NULL, NULL);
_midiio->set_port_changed_callback(NULL, NULL);
if (pthread_join (_freeewheel_thread, &status)) {
PBD::error << _("CoreAudioBackend: failed to terminate.") << endmsg;
return -1;
}
#if 0
while (!_rmidi_out.empty ()) {
CoreMidiIO *m = _rmidi_out.back ();
m->stop();
_rmidi_out.pop_back ();
delete m;
}
while (!_rmidi_in.empty ()) {
CoreMidiIO *m = _rmidi_in.back ();
m->stop();
_rmidi_in.pop_back ();
delete m;
}
#endif
unregister_ports();
_active_ca = false;
@ -637,6 +608,20 @@ CoreAudioBackend::samples_since_cycle_start ()
return 0;
}
uint32_t
CoreAudioBackend::name_to_id(std::string device_name) const {
uint32_t device_id = UINT32_MAX;
std::map<size_t, std::string> devices;
_pcmio->device_list(devices);
for (std::map<size_t, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
if (i->second == device_name) {
device_id = i->first;
break;
}
}
return device_id;
}
void *
CoreAudioBackend::coreaudio_process_thread (void *arg)
@ -872,8 +857,12 @@ int
CoreAudioBackend::register_system_audio_ports()
{
LatencyRange lr;
printf("COREAUDIO LATENCY: i:%d, o:%d\n",
_pcmio->get_latency(name_to_id(_audio_device), true),
_pcmio->get_latency(name_to_id(_audio_device), false));
// TODO ask _pcmio for port latencies
//TODO set latencies
//TODO query port names
const int a_ins = _n_inputs > 0 ? _n_inputs : 2;
const int a_out = _n_outputs > 0 ? _n_outputs : 2;
@ -907,6 +896,7 @@ CoreAudioBackend::register_system_midi_ports()
int midi_ins = _system_midi_out.size();
int midi_outs = _system_midi_in.size();
//TODO query port names
for (uint32_t i = midi_ins; i < _midiio->n_midi_outputs(); ++i) {
char tmp[64];
snprintf(tmp, sizeof(tmp), "system:midi_playback_%d", ++midi_ins);
@ -917,7 +907,6 @@ CoreAudioBackend::register_system_midi_ports()
LatencyRange lr;
lr.min = lr.max = _samples_per_period; // TODO add per-port midi-systemic latency
set_latency_range (p, false, lr);
//static_cast<CoreMidiPort*>(p)->set_n_periods(2);
_system_midi_out.push_back(static_cast<CoreBackendPort*>(p));
}
@ -931,7 +920,6 @@ CoreAudioBackend::register_system_midi_ports()
LatencyRange lr;
lr.min = lr.max = _samples_per_period; // TODO add per-port midi-systemic latency
set_latency_range (p, false, lr);
//static_cast<CoreMidiPort*>(p)->set_n_periods(2);
_system_midi_in.push_back(static_cast<CoreBackendPort*>(p));
}
@ -946,6 +934,8 @@ CoreAudioBackend::coremidi_rediscover()
pthread_mutex_lock (&_process_callback_mutex);
// TODO maintain device-specific connections, rather
// than re-map.
while (_system_midi_out.size() > _midiio->n_midi_outputs()) {
CoreBackendPort* p = _system_midi_out.back();
_system_midi_out.pop_back();
@ -961,7 +951,6 @@ CoreAudioBackend::coremidi_rediscover()
register_system_midi_ports();
_port_change_flag = true;
_reinit_thread_callback = true; // XXX, rather hook into _pcmio's hardwarePropertyChangeCallback
pthread_mutex_unlock (&_process_callback_mutex);
}
@ -1404,7 +1393,6 @@ CoreAudioBackend::process_callback ()
}
if (_reinit_thread_callback || _main_thread != pthread_self()) {
printf("REINIT THREAD\n");
_reinit_thread_callback = false;
_main_thread = pthread_self();
AudioEngine::thread_init_callback (this);
@ -1417,6 +1405,7 @@ CoreAudioBackend::process_callback ()
#if 0 // here in RT callback ?? XXX
if (_samples_per_period != n_samples) {
printf("CoreAudio Adjust SPP %zu -> %d\n", _samples_per_period, n_samples);
_samples_per_period = n_samples;
engine.buffer_size_change (_samples_per_period);
// TODO update latencies
@ -1428,7 +1417,7 @@ CoreAudioBackend::process_callback ()
clock1 = g_get_monotonic_time();
// TODO get midi
/* get midi */
i=0;
for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it, ++i) {
CoreMidiBuffer* mbuf = static_cast<CoreMidiBuffer*>((*it)->get_buffer(0));
@ -1465,12 +1454,12 @@ CoreAudioBackend::process_callback ()
return -1;
}
// mixdown midi
/* mixdown midi */
for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
//static_cast<CoreMidiPort*>(*it)->next_period();
static_cast<CoreMidiPort*>(*it)->get_buffer(0);
}
// queue outgoing midi
/* queue outgoing midi */
i = 0;
for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it, ++i) {
const CoreMidiBuffer *src = static_cast<const CoreMidiPort*>(*it)->const_buffer();
@ -1487,15 +1476,14 @@ CoreAudioBackend::process_callback ()
_processed_samples += n_samples;
// calc DSP load.
/* calc DSP load. */
clock2 = g_get_monotonic_time();
const int64_t elapsed_time = clock2 - clock1;
_dsp_load = elapsed_time / (float) nominal_time;
//engine.Xrun (); // TODO, if any
// port-connection change
/* port-connection change */
post_process();
pthread_mutex_unlock (&_process_callback_mutex);
return 0;
@ -1504,11 +1492,16 @@ CoreAudioBackend::process_callback ()
void
CoreAudioBackend::error_callback ()
{
printf("ERROR CALLBACK\n");
_pcmio->set_error_callback (NULL, NULL);
engine.halted_callback("CoreAudio Process aborted.");
}
void
CoreAudioBackend::hw_changed_callback ()
{
_reinit_thread_callback = true;
engine.request_device_list_update();
}
/******************************************************************************/

View file

@ -199,8 +199,8 @@ class CoreAudioBackend : public AudioBackend {
bool can_set_systemic_midi_latencies () const { return false; /* XXX */}
/* External control app */
std::string control_app_name () const { return std::string (); }
void launch_control_app () {}
std::string control_app_name () const { return std::string ("Apple"); }
void launch_control_app ();
/* MIDI */
std::vector<std::string> enumerate_midi_options () const;
@ -214,6 +214,7 @@ class CoreAudioBackend : public AudioBackend {
// really private, but needing static access:
int process_callback();
void error_callback();
void hw_changed_callback();
protected:
/* State Control */
@ -333,6 +334,9 @@ class CoreAudioBackend : public AudioBackend {
uint32_t _systemic_audio_input_latency;
uint32_t _systemic_audio_output_latency;
/* coreaudio specific */
uint32_t name_to_id(std::string) const;
/* midi settings */
struct CoreMidiDeviceInfo {
bool enabled;
@ -380,9 +384,6 @@ class CoreAudioBackend : public AudioBackend {
std::vector<CoreBackendPort *> _system_midi_in;
std::vector<CoreBackendPort *> _system_midi_out;
//std::vector<CoreMidiOut *> _rmidi_out;
//std::vector<CoreMidiIn *> _rmidi_in;
struct PortConnectData {
std::string a;
std::string b;

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@
#include <AudioToolbox/AudioToolbox.h>
#include <map>
#include <vector>
#include <string>
#define AUHAL_OUTPUT_ELEMENT 0
@ -43,6 +44,16 @@ public:
void discover();
void device_list(std::map<size_t, std::string> &devices) const { devices = _devices;}
int available_sample_rates (uint32_t device_id, std::vector<float>& sampleRates);
int available_buffer_sizes (uint32_t device_id, std::vector<uint32_t>& sampleRates);
uint32_t available_channels (uint32_t device_id, bool input);
float current_sample_rate(uint32 device_id, bool input = false);
uint32_t get_latency(uint32 device_id, bool input);
std::string cached_port_name(uint32_t portnum, bool input) const;
void launch_control_app (uint32_t device_id);
void pcm_stop (void);
int pcm_start (
uint32_t input_device,
@ -53,13 +64,22 @@ public:
void * process_arg
);
// TODO: combine callbacks below, add a enum type
void set_error_callback (
void ( error_callback (void*)),
void * error_arg
) {
_error_callback = error_callback;
_error_arg = error_arg;
}
) {
_error_callback = error_callback;
_error_arg = error_arg;
}
void set_hw_changed_callback (
void ( callback (void*)),
void * arg
) {
_hw_changed_callback = callback;
_hw_changed_arg = arg;
}
// must be called from process_callback;
int get_capture_channel (uint32_t chn, float *input, uint32_t n_samples);
@ -74,13 +94,17 @@ public:
UInt32 inNumberFrames,
AudioBufferList* ioData);
void hwPropertyChange();
void hwPropertyChange();
private:
int set_device_sample_rate (uint32 device_id, float rate, bool input);
void get_stream_latencies(uint32 device_id, bool input, std::vector<uint32>& latencies);
void cache_port_names(uint32 device_id, bool input);
AudioUnit _auhal;
AudioDeviceID* _deviceIDs;
AudioBufferList* _inputAudioBufferList;
AudioBufferList* _outputAudioBufferList;
AudioDeviceID* _device_ids;
AudioBufferList* _input_audio_buffer_list;
AudioBufferList* _output_audio_buffer_list;
int _state;
@ -89,7 +113,7 @@ private:
uint32_t _capture_channels;
uint32_t _playback_channels;
bool _in_process;
size_t _numDevices;
size_t _n_devices;
int (* _process_callback) (void*);
void * _process_arg;
@ -97,9 +121,15 @@ private:
void (* _error_callback) (void*);
void * _error_arg;
void (* _hw_changed_callback) (void*);
void * _hw_changed_arg;
// TODO proper device info struct
std::map<size_t, std::string> _devices;
// TODO proper device info struct
uint32_t * _device_ins;
uint32_t * _device_outs;
std::vector<std::string> _input_names;
std::vector<std::string> _output_names;
pthread_mutex_t _discovery_lock;
};

View file

@ -40,12 +40,12 @@ static void midiInputCallback(const MIDIPacketList *list, void *procRef, void *s
CoreMidiIo::CoreMidiIo()
: _midiClient (0)
, _inputEndPoints (0)
, _outputEndPoints (0)
, _inputPorts (0)
, _outputPorts (0)
, _inputQueue (0)
: _midi_client (0)
, _input_endpoints (0)
, _output_endpoints (0)
, _input_ports (0)
, _output_ports (0)
, _input_queue (0)
, _rb (0)
, _n_midi_in (0)
, _n_midi_out (0)
@ -55,7 +55,7 @@ CoreMidiIo::CoreMidiIo()
, _changed_arg (0)
{
OSStatus err;
err = MIDIClientCreate(CFSTR("Ardour"), &notifyProc, this, &_midiClient);
err = MIDIClientCreate(CFSTR("Ardour"), &notifyProc, this, &_midi_client);
if (noErr != err) {
fprintf(stderr, "Creating Midi Client failed\n");
}
@ -65,7 +65,7 @@ CoreMidiIo::CoreMidiIo()
CoreMidiIo::~CoreMidiIo()
{
cleanup();
MIDIClientDispose(_midiClient); _midiClient = 0;
MIDIClientDispose(_midi_client); _midi_client = 0;
}
void
@ -73,19 +73,19 @@ CoreMidiIo::cleanup()
{
_active = false;
for (uint32_t i = 0 ; i < _n_midi_in ; ++i) {
MIDIPortDispose(_inputPorts[i]);
_inputQueue[i].clear();
MIDIPortDispose(_input_ports[i]);
_input_queue[i].clear();
delete _rb[i];
}
for (uint32_t i = 0 ; i < _n_midi_out ; ++i) {
MIDIPortDispose(_outputPorts[i]);
MIDIPortDispose(_output_ports[i]);
}
free(_inputPorts); _inputPorts = 0;
free(_inputEndPoints); _inputEndPoints = 0;
free(_inputQueue); _inputQueue = 0;
free(_outputPorts); _outputPorts = 0;
free(_outputEndPoints); _outputEndPoints = 0;
free(_input_ports); _input_ports = 0;
free(_input_endpoints); _input_endpoints = 0;
free(_input_queue); _input_queue = 0;
free(_output_ports); _output_ports = 0;
free(_output_endpoints); _output_endpoints = 0;
free(_rb); _rb = 0;
_n_midi_in = 0;
@ -103,37 +103,37 @@ CoreMidiIo::notify_proc(const MIDINotification *message)
{
switch(message->messageID) {
case kMIDIMsgSetupChanged:
printf("kMIDIMsgSetupChanged\n");
/* this one catches all of the added/removed/changed below */
//printf("kMIDIMsgSetupChanged\n");
discover();
break;
case kMIDIMsgObjectAdded:
{
const MIDIObjectAddRemoveNotification *n = (const MIDIObjectAddRemoveNotification*) message;
printf("kMIDIMsgObjectAdded\n");
//const MIDIObjectAddRemoveNotification *n = (const MIDIObjectAddRemoveNotification*) message;
//printf("kMIDIMsgObjectAdded\n");
}
break;
case kMIDIMsgObjectRemoved:
{
const MIDIObjectAddRemoveNotification *n = (const MIDIObjectAddRemoveNotification*) message;
printf("kMIDIMsgObjectRemoved\n");
//const MIDIObjectAddRemoveNotification *n = (const MIDIObjectAddRemoveNotification*) message;
//printf("kMIDIMsgObjectRemoved\n");
}
break;
case kMIDIMsgPropertyChanged:
{
const MIDIObjectPropertyChangeNotification *n = (const MIDIObjectPropertyChangeNotification*) message;
printf("kMIDIMsgObjectRemoved\n");
//const MIDIObjectPropertyChangeNotification *n = (const MIDIObjectPropertyChangeNotification*) message;
//printf("kMIDIMsgObjectRemoved\n");
}
break;
case kMIDIMsgThruConnectionsChanged:
printf("kMIDIMsgThruConnectionsChanged\n");
//printf("kMIDIMsgThruConnectionsChanged\n");
break;
case kMIDIMsgSerialPortOwnerChanged:
printf("kMIDIMsgSerialPortOwnerChanged\n");
//printf("kMIDIMsgSerialPortOwnerChanged\n");
break;
case kMIDIMsgIOError:
printf("kMIDIMsgIOError\n");
cleanup();
//discover();
fprintf(stderr, "kMIDIMsgIOError\n");
discover();
break;
}
}
@ -150,19 +150,19 @@ CoreMidiIo::recv_event (uint32_t port, double cycle_time_us, uint64_t &time, uin
MIDIPacket packet;
size_t rv = _rb[port]->read((uint8_t*)&packet, sizeof(MIDIPacket));
assert(rv == sizeof(MIDIPacket));
_inputQueue[port].push_back(boost::shared_ptr<CoreMIDIPacket>(new _CoreMIDIPacket (&packet)));
_input_queue[port].push_back(boost::shared_ptr<CoreMIDIPacket>(new _CoreMIDIPacket (&packet)));
}
UInt64 start = _time_at_cycle_start;
UInt64 end = AudioConvertNanosToHostTime(AudioConvertHostTimeToNanos(_time_at_cycle_start) + cycle_time_us * 1e3);
for (CoreMIDIQueue::iterator it = _inputQueue[port].begin (); it != _inputQueue[port].end (); ) {
for (CoreMIDIQueue::iterator it = _input_queue[port].begin (); it != _input_queue[port].end (); ) {
if ((*it)->timeStamp < end) {
if ((*it)->timeStamp < start) {
uint64_t dt = AudioConvertHostTimeToNanos(start - (*it)->timeStamp);
//printf("Stale Midi Event dt:%.2fms\n", dt * 1e-6);
if (dt > 1e-4) { // 100ms, maybe too large
it = _inputQueue[port].erase(it);
it = _input_queue[port].erase(it);
continue;
}
time = 0;
@ -173,7 +173,7 @@ CoreMidiIo::recv_event (uint32_t port, double cycle_time_us, uint64_t &time, uin
if (s > 0) {
memcpy(d, (*it)->data, s);
}
_inputQueue[port].erase(it);
_input_queue[port].erase(it);
return s;
}
++it;
@ -204,7 +204,7 @@ CoreMidiIo::send_event (uint32_t port, double reltime_us, const uint8_t *d, cons
assert(s < 256);
memcpy(mp->data, d, s);
MIDISend(_outputPorts[port], _outputEndPoints[port], &pl);
MIDISend(_output_ports[port], _output_endpoints[port], &pl);
return 0;
}
@ -213,20 +213,20 @@ CoreMidiIo::discover()
{
cleanup();
assert(!_active && _midiClient);
assert(!_active && _midi_client);
ItemCount srcCount = MIDIGetNumberOfSources();
ItemCount dstCount = MIDIGetNumberOfDestinations();
if (srcCount > 0) {
_inputPorts = (MIDIPortRef *) malloc (srcCount * sizeof(MIDIPortRef));
_inputEndPoints = (MIDIEndpointRef*) malloc (srcCount * sizeof(MIDIEndpointRef));
_inputQueue = (CoreMIDIQueue*) calloc (srcCount, sizeof(CoreMIDIQueue));
_input_ports = (MIDIPortRef *) malloc (srcCount * sizeof(MIDIPortRef));
_input_endpoints = (MIDIEndpointRef*) malloc (srcCount * sizeof(MIDIEndpointRef));
_input_queue = (CoreMIDIQueue*) calloc (srcCount, sizeof(CoreMIDIQueue));
_rb = (RingBuffer<uint8_t> **) malloc (srcCount * sizeof(RingBuffer<uint8_t>*));
}
if (dstCount > 0) {
_outputPorts = (MIDIPortRef *) malloc (dstCount * sizeof(MIDIPortRef));
_outputEndPoints = (MIDIEndpointRef*) malloc (dstCount * sizeof(MIDIEndpointRef));
_output_ports = (MIDIPortRef *) malloc (dstCount * sizeof(MIDIPortRef));
_output_endpoints = (MIDIEndpointRef*) malloc (dstCount * sizeof(MIDIEndpointRef));
}
for (ItemCount i = 0; i < srcCount; i++) {
@ -235,17 +235,18 @@ CoreMidiIo::discover()
CFStringRef port_name;
port_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("midi_capture_%lu"), i);
err = MIDIInputPortCreate (_midiClient, port_name, midiInputCallback, this, &_inputPorts[_n_midi_in]);
err = MIDIInputPortCreate (_midi_client, port_name, midiInputCallback, this, &_input_ports[_n_midi_in]);
if (noErr != err) {
fprintf(stderr, "Cannot create Midi Output\n");
// TODO handle errors
continue;
}
// TODO get device name/ID
_rb[_n_midi_in] = new RingBuffer<uint8_t>(1024 * sizeof(MIDIPacket));
_inputQueue[_n_midi_in] = CoreMIDIQueue();
MIDIPortConnectSource(_inputPorts[_n_midi_in], src, (void*) _rb[_n_midi_in]);
_input_queue[_n_midi_in] = CoreMIDIQueue();
MIDIPortConnectSource(_input_ports[_n_midi_in], src, (void*) _rb[_n_midi_in]);
CFRelease(port_name);
_inputEndPoints[_n_midi_in] = src;
_input_endpoints[_n_midi_in] = src;
++_n_midi_in;
}
@ -255,15 +256,16 @@ CoreMidiIo::discover()
port_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("midi_playback_%lu"), i);
OSStatus err;
err = MIDIOutputPortCreate (_midiClient, port_name, &_outputPorts[_n_midi_out]);
err = MIDIOutputPortCreate (_midi_client, port_name, &_output_ports[_n_midi_out]);
if (noErr != err) {
fprintf(stderr, "Cannot create Midi Output\n");
// TODO handle errors
continue;
}
MIDIPortConnectSource(_outputPorts[_n_midi_out], dst, NULL);
// TODO get device name/ID
MIDIPortConnectSource(_output_ports[_n_midi_out], dst, NULL);
CFRelease(port_name);
_outputEndPoints[_n_midi_out] = dst;
_output_endpoints[_n_midi_out] = dst;
++_n_midi_out;
}

View file

@ -76,7 +76,7 @@ public:
void notify_proc (const MIDINotification *message);
void setPortChangedCallback (void (changed_callback (void*)), void *arg) {
void set_port_changed_callback (void (changed_callback (void*)), void *arg) {
_changed_callback = changed_callback;
_changed_arg = arg;
}
@ -84,19 +84,20 @@ public:
private:
void cleanup ();
MIDIClientRef _midiClient;
MIDIEndpointRef * _inputEndPoints;
MIDIEndpointRef * _outputEndPoints;
MIDIPortRef * _inputPorts;
MIDIPortRef * _outputPorts;
CoreMIDIQueue * _inputQueue;
MIDIClientRef _midi_client;
MIDIEndpointRef * _input_endpoints;
MIDIEndpointRef * _output_endpoints;
MIDIPortRef * _input_ports;
MIDIPortRef * _output_ports;
CoreMIDIQueue * _input_queue;
RingBuffer<uint8_t> ** _rb;
uint32_t _n_midi_in;
uint32_t _n_midi_out;
uint32_t _n_midi_in;
uint32_t _n_midi_out;
MIDITimeStamp _time_at_cycle_start;
bool _active;
MIDITimeStamp _time_at_cycle_start;
bool _active;
void (* _changed_callback) (void*);
void * _changed_arg;

View file

@ -31,3 +31,6 @@ def build(bld):
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"',
'ARDOURBACKEND_DLL_EXPORTS', 'COREAUDIO_108'
]
# OSX 10.6 or later
obj.defines += ['COREAUDIO_108']