mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
cont’d work on the coreaudio backend & cleanup
This commit is contained in:
parent
408090adce
commit
6b87e706eb
7 changed files with 854 additions and 319 deletions
|
|
@ -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();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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"), ¬ifyProc, this, &_midiClient);
|
||||
err = MIDIClientCreate(CFSTR("Ardour"), ¬ifyProc, 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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']
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue