From 3f99c44ff6b2d47fbd67d7b1420228c1bba5d5fe Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 2 Oct 2015 17:28:16 +0200 Subject: [PATCH] improve CoreAudio error reporting --- libs/backends/coreaudio/coreaudio_backend.cc | 64 ++++++++++++++++++-- libs/backends/coreaudio/coreaudio_pcmio.cc | 54 ++++++++--------- 2 files changed, 86 insertions(+), 32 deletions(-) diff --git a/libs/backends/coreaudio/coreaudio_backend.cc b/libs/backends/coreaudio/coreaudio_backend.cc index d125f0486c..7ff97c660b 100644 --- a/libs/backends/coreaudio/coreaudio_backend.cc +++ b/libs/backends/coreaudio/coreaudio_backend.cc @@ -507,6 +507,8 @@ static int process_callback_ptr (void *arg, const uint32_t n_samples, const uint int CoreAudioBackend::_start (bool for_latency_measurement) { + AudioBackend::ErrorCode error_code = NoError; + if ((!_active_ca || !_active_fw) && _run) { // recover from 'halted', reap threads stop(); @@ -541,15 +543,67 @@ CoreAudioBackend::_start (bool for_latency_measurement) _pcmio->set_sample_rate_callback (sample_rate_callback_ptr, this); _pcmio->pcm_start (device1, device2, _samplerate, _samples_per_period, process_callback_ptr, this); +#ifndef NDEBUG printf("STATE: %d\n", _pcmio->state ()); - +#endif switch (_pcmio->state ()) { - case 0: /* OK */ break; - case -1: PBD::error << _("CoreAudioBackend: failed to open device.") << endmsg; break; - default: PBD::error << _("CoreAudioBackend: initialization failed.") << endmsg; break; + case 0: /* OK */ + break; + case -1: + PBD::error << _("CoreAudioBackend: Invalid Device ID.") << endmsg; + error_code = BackendInitializationError; // XXX + break; + case -2: + PBD::error << _("CoreAudioBackend: Failed to resolve Device-Component by ID.") << endmsg; + error_code = BackendInitializationError; // XXX + break; + case -3: + PBD::error << _("CoreAudioBackend: failed to open device.") << endmsg; + error_code = AudioDeviceOpenError; + break; + case -4: + PBD::error << _("CoreAudioBackend: cannot set requested sample rate.") << endmsg; + error_code = SampleRateNotSupportedError; + break; + case -5: + PBD::error << _("CoreAudioBackend: cannot configure requested buffer size.") << endmsg; + error_code = PeriodSizeNotSupportedError; + break; + case -6: + PBD::error << _("CoreAudioBackend: unsupported sample format.") << endmsg; + error_code = SampleFormatNotSupportedError; + break; + case -7: + PBD::error << _("CoreAudioBackend: Failed to enable Device.") << endmsg; + error_code = BackendInitializationError; // XXX + break; + case -8: + PBD::error << _("CoreAudioBackend: Cannot allocate buffers, out-of-memory.") << endmsg; + error_code = BackendInitializationError; // XXX + break; + case -9: + PBD::error << _("CoreAudioBackend: Failed to set device-property listeners.") << endmsg; + error_code = BackendInitializationError; // XXX + break; + case -10: + PBD::error << _("CoreAudioBackend: Setting Process Callback failed.") << endmsg; + error_code = BackendInitializationError; // XXX + break; + case -11: + PBD::error << _("CoreAudioBackend: cannot use requested period size.") << endmsg; + error_code = PeriodSizeNotSupportedError; + break; + case -12: + PBD::error << _("CoreAudioBackend: cannot create aggregate device.") << endmsg; + error_code = DeviceConfigurationNotSupportedError; + break; + default: + PBD::error << _("CoreAudioBackend: initialization failure.") << endmsg; + error_code = BackendInitializationError; + break; } if (_pcmio->state ()) { - return -1; + return error_code; } if (_n_outputs != _pcmio->n_playback_channels ()) { diff --git a/libs/backends/coreaudio/coreaudio_pcmio.cc b/libs/backends/coreaudio/coreaudio_pcmio.cc index 5be717b1f3..59c054a74a 100644 --- a/libs/backends/coreaudio/coreaudio_pcmio.cc +++ b/libs/backends/coreaudio/coreaudio_pcmio.cc @@ -794,7 +794,7 @@ CoreAudioPCM::pcm_start ( assert(_device_ids); std::string errorMsg; - _state = -2; + _state = -99; // "None" = UINT32_MAX if (device_id_out >= _n_devices && device_id_in >= _n_devices) { @@ -825,36 +825,36 @@ CoreAudioPCM::pcm_start ( #ifndef COREAUDIO_108 ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; Component HALOutput = FindNextComponent(NULL, &cd); - if (!HALOutput) { errorMsg="FindNextComponent"; goto error; } + if (!HALOutput) { errorMsg="FindNextComponent"; _state = -2; goto error; } err = OpenAComponent(HALOutput, &_auhal); - if (err != noErr) { errorMsg="OpenAComponent"; goto error; } + if (err != noErr) { errorMsg="OpenAComponent"; _state = -2; goto error; } #else AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd); - if (!HALOutput) { errorMsg="AudioComponentFindNext"; goto error; } + if (!HALOutput) { errorMsg="AudioComponentFindNext"; _state = -2; goto error; } err = AudioComponentInstanceNew(HALOutput, &_auhal); - if (err != noErr) { errorMsg="AudioComponentInstanceNew"; goto error; } + if (err != noErr) { errorMsg="AudioComponentInstanceNew"; _state = -2; goto error; } #endif err = AudioUnitInitialize(_auhal); - if (err != noErr) { errorMsg="AudioUnitInitialize"; goto error; } + if (err != noErr) { errorMsg="AudioUnitInitialize"; _state = -3; goto error; } // explicitly change samplerate of the devices, TODO allow separate rates with aggregates if (set_device_sample_rate(device_id_in, sample_rate, true)) { - errorMsg="Failed to set SampleRate, Capture Device"; goto error; + errorMsg="Failed to set SampleRate, Capture Device"; _state = -4; goto error; } if (set_device_sample_rate(device_id_out, sample_rate, false)) { - errorMsg="Failed to set SampleRate, Playback Device"; goto error; + errorMsg="Failed to set SampleRate, Playback Device"; _state = -4; goto error; } // explicitly request device buffer size if (device_id_in < _n_devices && set_device_buffer_size_id(_device_ids[device_id_in], samples_per_period)) { - errorMsg="kAudioDevicePropertyBufferFrameSize, Input"; goto error; + errorMsg="kAudioDevicePropertyBufferFrameSize, Input"; _state = -5; goto error; } if (device_id_out < _n_devices && set_device_buffer_size_id(_device_ids[device_id_out], samples_per_period)) { - errorMsg="kAudioDevicePropertyBufferFrameSize, Output"; goto error; + errorMsg="kAudioDevicePropertyBufferFrameSize, Output"; _state = -5; goto error; } // create aggregate device.. @@ -864,7 +864,7 @@ CoreAudioPCM::pcm_start ( } else { _aggregate_device_id = 0; _aggregate_plugin_id = 0; - errorMsg="Cannot create Aggregate Device"; goto error; + errorMsg="Cannot create Aggregate Device"; _state = -12; goto error; } } else if (device_id_out < _n_devices) { device_id = _device_ids[device_id_out]; @@ -880,14 +880,14 @@ CoreAudioPCM::pcm_start ( // enableIO to progress further uint32val = (chn_in > 0) ? 1 : 0; err = AudioUnitSetProperty(_auhal, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, AUHAL_INPUT_ELEMENT, &uint32val, sizeof(UInt32)); - if (err != noErr) { errorMsg="kAudioOutputUnitProperty_EnableIO, Input"; goto error; } + if (err != noErr) { errorMsg="kAudioOutputUnitProperty_EnableIO, Input"; _state = -7; goto error; } uint32val = (chn_out > 0) ? 1 : 0; err = AudioUnitSetProperty(_auhal, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, AUHAL_OUTPUT_ELEMENT, &uint32val, sizeof(UInt32)); - if (err != noErr) { errorMsg="kAudioOutputUnitProperty_EnableIO, Output"; goto error; } + if (err != noErr) { errorMsg="kAudioOutputUnitProperty_EnableIO, Output"; _state = -7; goto error; } err = AudioUnitSetProperty(_auhal, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &device_id, sizeof(AudioDeviceID)); - if (err != noErr) { errorMsg="kAudioOutputUnitProperty_CurrentDevice, Input"; goto error; } + if (err != noErr) { errorMsg="kAudioOutputUnitProperty_CurrentDevice, Input"; _state = -7; goto error; } if (chn_in > 0) { // set sample format @@ -901,10 +901,10 @@ CoreAudioPCM::pcm_start ( srcFormat.mBitsPerChannel = 32; err = AudioUnitSetProperty(_auhal, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, AUHAL_INPUT_ELEMENT, &srcFormat, sizeof(AudioStreamBasicDescription)); - if (err != noErr) { errorMsg="kAudioUnitProperty_StreamFormat, Output"; goto error; } + if (err != noErr) { errorMsg="kAudioUnitProperty_StreamFormat, Output"; _state = -6; goto error; } err = AudioUnitSetProperty(_auhal, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, AUHAL_INPUT_ELEMENT, (UInt32*)&_samples_per_period, sizeof(UInt32)); - if (err != noErr) { errorMsg="kAudioUnitProperty_MaximumFramesPerSlice, Input"; goto error; } + if (err != noErr) { errorMsg="kAudioUnitProperty_MaximumFramesPerSlice, Input"; _state = -6; goto error; } } if (chn_out > 0) { @@ -918,17 +918,17 @@ CoreAudioPCM::pcm_start ( dstFormat.mBitsPerChannel = 32; err = AudioUnitSetProperty(_auhal, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, AUHAL_OUTPUT_ELEMENT, &dstFormat, sizeof(AudioStreamBasicDescription)); - if (err != noErr) { errorMsg="kAudioUnitProperty_StreamFormat Input"; goto error; } + if (err != noErr) { errorMsg="kAudioUnitProperty_StreamFormat Input"; _state = -5; goto error; } err = AudioUnitSetProperty(_auhal, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, AUHAL_OUTPUT_ELEMENT, (UInt32*)&_samples_per_period, sizeof(UInt32)); - if (err != noErr) { errorMsg="kAudioUnitProperty_MaximumFramesPerSlice, Output"; goto error; } + if (err != noErr) { errorMsg="kAudioUnitProperty_MaximumFramesPerSlice, Output"; _state = -5; goto error; } } /* read back stream descriptions */ if (chn_in > 0) { size = sizeof(AudioStreamBasicDescription); err = AudioUnitGetProperty(_auhal, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, AUHAL_INPUT_ELEMENT, &srcFormat, &size); - if (err != noErr) { errorMsg="Get kAudioUnitProperty_StreamFormat, Output"; goto error; } + if (err != noErr) { errorMsg="Get kAudioUnitProperty_StreamFormat, Output"; _state = -5; goto error; } _capture_channels = srcFormat.mChannelsPerFrame; #ifndef NDEBUG PrintStreamDesc(&srcFormat); @@ -938,7 +938,7 @@ CoreAudioPCM::pcm_start ( if (chn_out > 0) { size = sizeof(AudioStreamBasicDescription); err = AudioUnitGetProperty(_auhal, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, AUHAL_OUTPUT_ELEMENT, &dstFormat, &size); - if (err != noErr) { errorMsg="Get kAudioUnitProperty_StreamFormat, Input"; goto error; } + if (err != noErr) { errorMsg="Get kAudioUnitProperty_StreamFormat, Input"; _state = -5; goto error; } _playback_channels = dstFormat.mChannelsPerFrame; #ifndef NDEBUG @@ -950,20 +950,20 @@ CoreAudioPCM::pcm_start ( if (_capture_channels > 0) { _input_audio_buffer_list = (AudioBufferList*)malloc(sizeof(AudioBufferList) + (_capture_channels - 1) * sizeof(AudioBuffer)); assert(_input_audio_buffer_list); - if (!_input_audio_buffer_list) { errorMsg="Out of Memory."; goto error; } + if (!_input_audio_buffer_list) { errorMsg="Out of Memory."; _state = -8; goto error; } } _active_device_id = device_id; // add Listeners err = add_listener (_active_device_id, kAudioDeviceProcessorOverload, this); - if (err != noErr) { errorMsg="kAudioDeviceProcessorOverload, Listen"; goto error; } + if (err != noErr) { errorMsg="kAudioDeviceProcessorOverload, Listen"; _state = -9; goto error; } err = add_listener (_active_device_id, kAudioDevicePropertyBufferFrameSize, this); - if (err != noErr) { errorMsg="kAudioDevicePropertyBufferFrameSize, Listen"; goto error; } + if (err != noErr) { errorMsg="kAudioDevicePropertyBufferFrameSize, Listen"; _state = -9; goto error; } err = add_listener (_active_device_id, kAudioDevicePropertyNominalSampleRate, this); - if (err != noErr) { errorMsg="kAudioDevicePropertyBufferFrameSize, Listen"; goto error; } + if (err != noErr) { errorMsg="kAudioDevicePropertyNominalSampleRate, Listen"; _state = -9; goto error; } _samples_per_period = current_buffer_size_id(_active_device_id); @@ -984,7 +984,7 @@ CoreAudioPCM::pcm_start ( &renderCallback, sizeof (renderCallback)); } - if (err != noErr) { errorMsg="kAudioUnitProperty_SetRenderCallback"; goto error; } + if (err != noErr) { errorMsg="kAudioUnitProperty_SetRenderCallback"; _state = -10; goto error; } /* setup complete, now get going.. */ if (AudioOutputUnitStart(_auhal) == noErr) { @@ -997,17 +997,17 @@ CoreAudioPCM::pcm_start ( // kick device if (set_device_buffer_size_id(_active_device_id, samples_per_period)) { - errorMsg="kAudioDevicePropertyBufferFrameSize"; goto error; + errorMsg="kAudioDevicePropertyBufferFrameSize"; _state = -11; goto error; } return 0; } error: + assert (_state != 0); char *rv = (char*)&err; fprintf(stderr, "CoreaudioPCM Error: %c%c%c%c %s\n", rv[0], rv[1], rv[2], rv[3], errorMsg.c_str()); pcm_stop(); - _state = -3; _active_device_id = 0; pthread_mutex_unlock (&_discovery_lock); return -1;