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();
|
||||
}
|
||||
|
||||
static void halted_callback_ptr (void *arg)
|
||||
{
|
||||
CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
|
||||
d->halted_callback();
|
||||
}
|
||||
|
||||
static void xrun_callback_ptr (void *arg)
|
||||
{
|
||||
CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
|
||||
@ -544,6 +550,7 @@ CoreAudioBackend::_start (bool for_latency_measurement)
|
||||
_last_process_start = 0;
|
||||
|
||||
_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_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
|
||||
CoreAudioBackend::error_callback ()
|
||||
CoreAudioBackend::unset_callbacks ()
|
||||
{
|
||||
_pcmio->set_error_callback (NULL, NULL);
|
||||
_pcmio->set_halted_callback (NULL, NULL);
|
||||
_pcmio->set_sample_rate_callback (NULL, NULL);
|
||||
_pcmio->set_xrun_callback (NULL, NULL);
|
||||
_midiio->set_port_changed_callback(NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
CoreAudioBackend::error_callback ()
|
||||
{
|
||||
unset_callbacks ();
|
||||
engine.halted_callback("CoreAudio Process aborted.");
|
||||
_active_ca = false;
|
||||
}
|
||||
|
||||
void
|
||||
CoreAudioBackend::halted_callback ()
|
||||
{
|
||||
unset_callbacks ();
|
||||
engine.halted_callback("Audio device was disconnected or shut down.");
|
||||
stop ();
|
||||
}
|
||||
|
||||
void
|
||||
CoreAudioBackend::xrun_callback ()
|
||||
{
|
||||
@ -1558,10 +1580,7 @@ CoreAudioBackend::sample_rate_callback ()
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
_pcmio->set_error_callback (NULL, NULL);
|
||||
_pcmio->set_sample_rate_callback (NULL, NULL);
|
||||
_pcmio->set_xrun_callback (NULL, NULL);
|
||||
_midiio->set_port_changed_callback(NULL, NULL);
|
||||
unset_callbacks ();
|
||||
engine.halted_callback("Sample Rate Changed.");
|
||||
stop();
|
||||
}
|
||||
|
@ -234,6 +234,7 @@ class CoreAudioBackend : public AudioBackend, public PortEngineSharedImpl {
|
||||
// really private, but needing static access:
|
||||
int process_callback(uint32_t, uint64_t);
|
||||
void error_callback();
|
||||
void halted_callback();
|
||||
void xrun_callback();
|
||||
void buffer_size_callback();
|
||||
void sample_rate_callback();
|
||||
@ -371,6 +372,8 @@ class CoreAudioBackend : public AudioBackend, public PortEngineSharedImpl {
|
||||
enum DeviceFilter { All, Input, Output, Duplex };
|
||||
uint32_t name_to_id(std::string, DeviceFilter filter = All) const;
|
||||
|
||||
void unset_callbacks ();
|
||||
|
||||
/* processing */
|
||||
float _dsp_load;
|
||||
ARDOUR::DSPLoadCalculator _dsp_load_calc;
|
||||
|
@ -139,6 +139,9 @@ static OSStatus property_callback_ptr (AudioObjectID inObjectID, UInt32 inNumber
|
||||
case kAudioDevicePropertyNominalSampleRate:
|
||||
self->sample_rate_callback();
|
||||
break;
|
||||
case kAudioDevicePropertyDeviceIsAlive:
|
||||
self->halted_callback();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -222,6 +225,7 @@ CoreAudioPCM::CoreAudioPCM ()
|
||||
, _n_devices (0)
|
||||
, _process_callback (0)
|
||||
, _error_callback (0)
|
||||
, _halted_callback (0)
|
||||
, _hw_changed_callback (0)
|
||||
, _xrun_callback (0)
|
||||
, _buffer_size_callback (0)
|
||||
@ -266,7 +270,6 @@ CoreAudioPCM::~CoreAudioPCM ()
|
||||
pthread_mutex_destroy (&_discovery_lock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CoreAudioPCM::hw_changed_callback() {
|
||||
#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
|
||||
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);
|
||||
prop.mSelector = kAudioDevicePropertyNominalSampleRate;
|
||||
AudioObjectRemovePropertyListener(_active_device_id, &prop, &property_callback_ptr, this);
|
||||
prop.mSelector = kAudioDevicePropertyDeviceIsAlive;
|
||||
AudioObjectRemovePropertyListener(_active_device_id, &prop, &property_callback_ptr, this);
|
||||
}
|
||||
#else
|
||||
if (_active_device_id > 0) {
|
||||
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, kAudioDevicePropertyNominalSampleRate, property_callback_ptr);
|
||||
AudioDeviceRemovePropertyListener(_active_device_id, 0, true, kAudioDevicePropertyDeviceIsAlive, property_callback_ptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -746,6 +761,7 @@ CoreAudioPCM::pcm_stop ()
|
||||
_output_names.clear();
|
||||
|
||||
_error_callback = 0;
|
||||
_halted_callback = 0;
|
||||
_process_callback = 0;
|
||||
_xrun_callback = 0;
|
||||
}
|
||||
@ -973,6 +989,10 @@ CoreAudioPCM::pcm_start (
|
||||
err = add_listener (_active_device_id, kAudioDevicePropertyNominalSampleRate, this);
|
||||
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);
|
||||
|
||||
// Setup callback
|
||||
|
@ -101,6 +101,14 @@ public:
|
||||
_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 ( callback (void*)),
|
||||
void * arg
|
||||
@ -148,6 +156,7 @@ public:
|
||||
void buffer_size_callback ();
|
||||
void sample_rate_callback ();
|
||||
void hw_changed_callback ();
|
||||
void halted_callback ();
|
||||
|
||||
private:
|
||||
float current_sample_rate_id (AudioDeviceID id, bool input);
|
||||
@ -192,6 +201,9 @@ private:
|
||||
void (* _error_callback) (void*);
|
||||
void * _error_arg;
|
||||
|
||||
void (* _halted_callback) (void*);
|
||||
void * _halted_arg;
|
||||
|
||||
void (* _hw_changed_callback) (void*);
|
||||
void * _hw_changed_arg;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user