CoreAudio: subscribe to device-alive property
This notifies the user about device disconnect and properly shuts down the backend.
This commit is contained in:
parent
65c81feb5e
commit
a7ca4cf8a1
@ -60,6 +60,12 @@ static void error_callback_ptr (void *arg)
|
|||||||
d->error_callback();
|
d->error_callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void halted_callback_ptr (void *arg)
|
||||||
|
{
|
||||||
|
CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
|
||||||
|
d->halted_callback();
|
||||||
|
}
|
||||||
|
|
||||||
static void xrun_callback_ptr (void *arg)
|
static void xrun_callback_ptr (void *arg)
|
||||||
{
|
{
|
||||||
CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
|
CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
|
||||||
@ -544,6 +550,7 @@ CoreAudioBackend::_start (bool for_latency_measurement)
|
|||||||
_last_process_start = 0;
|
_last_process_start = 0;
|
||||||
|
|
||||||
_pcmio->set_error_callback (error_callback_ptr, this);
|
_pcmio->set_error_callback (error_callback_ptr, this);
|
||||||
|
_pcmio->set_halted_callback (halted_callback_ptr, this);
|
||||||
_pcmio->set_buffer_size_callback (buffer_size_callback_ptr, this);
|
_pcmio->set_buffer_size_callback (buffer_size_callback_ptr, this);
|
||||||
_pcmio->set_sample_rate_callback (sample_rate_callback_ptr, this);
|
_pcmio->set_sample_rate_callback (sample_rate_callback_ptr, this);
|
||||||
|
|
||||||
@ -1521,16 +1528,31 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CoreAudioBackend::error_callback ()
|
CoreAudioBackend::unset_callbacks ()
|
||||||
{
|
{
|
||||||
_pcmio->set_error_callback (NULL, NULL);
|
_pcmio->set_error_callback (NULL, NULL);
|
||||||
|
_pcmio->set_halted_callback (NULL, NULL);
|
||||||
_pcmio->set_sample_rate_callback (NULL, NULL);
|
_pcmio->set_sample_rate_callback (NULL, NULL);
|
||||||
_pcmio->set_xrun_callback (NULL, NULL);
|
_pcmio->set_xrun_callback (NULL, NULL);
|
||||||
_midiio->set_port_changed_callback(NULL, NULL);
|
_midiio->set_port_changed_callback(NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CoreAudioBackend::error_callback ()
|
||||||
|
{
|
||||||
|
unset_callbacks ();
|
||||||
engine.halted_callback("CoreAudio Process aborted.");
|
engine.halted_callback("CoreAudio Process aborted.");
|
||||||
_active_ca = false;
|
_active_ca = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CoreAudioBackend::halted_callback ()
|
||||||
|
{
|
||||||
|
unset_callbacks ();
|
||||||
|
engine.halted_callback("Audio device was disconnected or shut down.");
|
||||||
|
stop ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CoreAudioBackend::xrun_callback ()
|
CoreAudioBackend::xrun_callback ()
|
||||||
{
|
{
|
||||||
@ -1558,10 +1580,7 @@ CoreAudioBackend::sample_rate_callback ()
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_pcmio->set_error_callback (NULL, NULL);
|
unset_callbacks ();
|
||||||
_pcmio->set_sample_rate_callback (NULL, NULL);
|
|
||||||
_pcmio->set_xrun_callback (NULL, NULL);
|
|
||||||
_midiio->set_port_changed_callback(NULL, NULL);
|
|
||||||
engine.halted_callback("Sample Rate Changed.");
|
engine.halted_callback("Sample Rate Changed.");
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
@ -234,6 +234,7 @@ class CoreAudioBackend : public AudioBackend, public PortEngineSharedImpl {
|
|||||||
// really private, but needing static access:
|
// really private, but needing static access:
|
||||||
int process_callback(uint32_t, uint64_t);
|
int process_callback(uint32_t, uint64_t);
|
||||||
void error_callback();
|
void error_callback();
|
||||||
|
void halted_callback();
|
||||||
void xrun_callback();
|
void xrun_callback();
|
||||||
void buffer_size_callback();
|
void buffer_size_callback();
|
||||||
void sample_rate_callback();
|
void sample_rate_callback();
|
||||||
@ -371,6 +372,8 @@ class CoreAudioBackend : public AudioBackend, public PortEngineSharedImpl {
|
|||||||
enum DeviceFilter { All, Input, Output, Duplex };
|
enum DeviceFilter { All, Input, Output, Duplex };
|
||||||
uint32_t name_to_id(std::string, DeviceFilter filter = All) const;
|
uint32_t name_to_id(std::string, DeviceFilter filter = All) const;
|
||||||
|
|
||||||
|
void unset_callbacks ();
|
||||||
|
|
||||||
/* processing */
|
/* processing */
|
||||||
float _dsp_load;
|
float _dsp_load;
|
||||||
ARDOUR::DSPLoadCalculator _dsp_load_calc;
|
ARDOUR::DSPLoadCalculator _dsp_load_calc;
|
||||||
|
@ -139,6 +139,9 @@ static OSStatus property_callback_ptr (AudioObjectID inObjectID, UInt32 inNumber
|
|||||||
case kAudioDevicePropertyNominalSampleRate:
|
case kAudioDevicePropertyNominalSampleRate:
|
||||||
self->sample_rate_callback();
|
self->sample_rate_callback();
|
||||||
break;
|
break;
|
||||||
|
case kAudioDevicePropertyDeviceIsAlive:
|
||||||
|
self->halted_callback();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -222,6 +225,7 @@ CoreAudioPCM::CoreAudioPCM ()
|
|||||||
, _n_devices (0)
|
, _n_devices (0)
|
||||||
, _process_callback (0)
|
, _process_callback (0)
|
||||||
, _error_callback (0)
|
, _error_callback (0)
|
||||||
|
, _halted_callback (0)
|
||||||
, _hw_changed_callback (0)
|
, _hw_changed_callback (0)
|
||||||
, _xrun_callback (0)
|
, _xrun_callback (0)
|
||||||
, _buffer_size_callback (0)
|
, _buffer_size_callback (0)
|
||||||
@ -266,7 +270,6 @@ CoreAudioPCM::~CoreAudioPCM ()
|
|||||||
pthread_mutex_destroy (&_discovery_lock);
|
pthread_mutex_destroy (&_discovery_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CoreAudioPCM::hw_changed_callback() {
|
CoreAudioPCM::hw_changed_callback() {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -278,6 +281,15 @@ CoreAudioPCM::hw_changed_callback() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CoreAudioPCM::halted_callback() {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
printf("CoreAudio halted callback..\n");
|
||||||
|
#endif
|
||||||
|
if (_halted_callback) {
|
||||||
|
_halted_callback(_halted_arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CoreAudioPCM::available_sample_rates(uint32_t device_id, std::vector<float>& sampleRates)
|
CoreAudioPCM::available_sample_rates(uint32_t device_id, std::vector<float>& sampleRates)
|
||||||
@ -711,12 +723,15 @@ CoreAudioPCM::pcm_stop ()
|
|||||||
AudioObjectRemovePropertyListener(_active_device_id, &prop, &property_callback_ptr, this);
|
AudioObjectRemovePropertyListener(_active_device_id, &prop, &property_callback_ptr, this);
|
||||||
prop.mSelector = kAudioDevicePropertyNominalSampleRate;
|
prop.mSelector = kAudioDevicePropertyNominalSampleRate;
|
||||||
AudioObjectRemovePropertyListener(_active_device_id, &prop, &property_callback_ptr, this);
|
AudioObjectRemovePropertyListener(_active_device_id, &prop, &property_callback_ptr, this);
|
||||||
|
prop.mSelector = kAudioDevicePropertyDeviceIsAlive;
|
||||||
|
AudioObjectRemovePropertyListener(_active_device_id, &prop, &property_callback_ptr, this);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (_active_device_id > 0) {
|
if (_active_device_id > 0) {
|
||||||
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDeviceProcessorOverload, property_callback_ptr);
|
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDeviceProcessorOverload, property_callback_ptr);
|
||||||
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDevicePropertyBufferFrameSize, property_callback_ptr);
|
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDevicePropertyBufferFrameSize, property_callback_ptr);
|
||||||
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDevicePropertyNominalSampleRate, property_callback_ptr);
|
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDevicePropertyNominalSampleRate, property_callback_ptr);
|
||||||
|
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDevicePropertyDeviceIsAlive, property_callback_ptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -746,6 +761,7 @@ CoreAudioPCM::pcm_stop ()
|
|||||||
_output_names.clear();
|
_output_names.clear();
|
||||||
|
|
||||||
_error_callback = 0;
|
_error_callback = 0;
|
||||||
|
_halted_callback = 0;
|
||||||
_process_callback = 0;
|
_process_callback = 0;
|
||||||
_xrun_callback = 0;
|
_xrun_callback = 0;
|
||||||
}
|
}
|
||||||
@ -973,6 +989,10 @@ CoreAudioPCM::pcm_start (
|
|||||||
err = add_listener (_active_device_id, kAudioDevicePropertyNominalSampleRate, this);
|
err = add_listener (_active_device_id, kAudioDevicePropertyNominalSampleRate, this);
|
||||||
if (err != noErr) { errorMsg="kAudioDevicePropertyNominalSampleRate, Listen"; _state = -9; goto error; }
|
if (err != noErr) { errorMsg="kAudioDevicePropertyNominalSampleRate, Listen"; _state = -9; goto error; }
|
||||||
|
|
||||||
|
err = add_listener (_active_device_id, kAudioDevicePropertyDeviceIsAlive, this);
|
||||||
|
if (err != noErr) { errorMsg="kAudioDevicePropertyNominalSampleRate, Listen"; _state = -9; goto error; }
|
||||||
|
|
||||||
|
|
||||||
_samples_per_period = current_buffer_size_id(_active_device_id);
|
_samples_per_period = current_buffer_size_id(_active_device_id);
|
||||||
|
|
||||||
// Setup callback
|
// Setup callback
|
||||||
|
@ -101,6 +101,14 @@ public:
|
|||||||
_error_arg = error_arg;
|
_error_arg = error_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_halted_callback (
|
||||||
|
void ( halted_callback (void*)),
|
||||||
|
void * halted_arg
|
||||||
|
) {
|
||||||
|
_halted_callback = halted_callback;
|
||||||
|
_halted_arg = halted_arg;
|
||||||
|
}
|
||||||
|
|
||||||
void set_hw_changed_callback (
|
void set_hw_changed_callback (
|
||||||
void ( callback (void*)),
|
void ( callback (void*)),
|
||||||
void * arg
|
void * arg
|
||||||
@ -148,6 +156,7 @@ public:
|
|||||||
void buffer_size_callback ();
|
void buffer_size_callback ();
|
||||||
void sample_rate_callback ();
|
void sample_rate_callback ();
|
||||||
void hw_changed_callback ();
|
void hw_changed_callback ();
|
||||||
|
void halted_callback ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float current_sample_rate_id (AudioDeviceID id, bool input);
|
float current_sample_rate_id (AudioDeviceID id, bool input);
|
||||||
@ -192,6 +201,9 @@ private:
|
|||||||
void (* _error_callback) (void*);
|
void (* _error_callback) (void*);
|
||||||
void * _error_arg;
|
void * _error_arg;
|
||||||
|
|
||||||
|
void (* _halted_callback) (void*);
|
||||||
|
void * _halted_arg;
|
||||||
|
|
||||||
void (* _hw_changed_callback) (void*);
|
void (* _hw_changed_callback) (void*);
|
||||||
void * _hw_changed_arg;
|
void * _hw_changed_arg;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user