From 88a0f8300b7478d4b9cf3d6679e9f8f7f0db4b0d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sat, 28 Nov 2015 21:55:20 +0000 Subject: [PATCH 1/5] audio/coreaudio.c: Factor out use of AudioHardwareGetProperty The CoreAudio function AudioHardwareGetProperty has been deprecated starting with OSX 10.6, so factor out our call to it so we can provide an equivalent with the new APIs when they exist. Signed-off-by: Peter Maydell Message-id: 1448747724-15572-2-git-send-email-peter.maydell@linaro.org Signed-off-by: Gerd Hoffmann --- audio/coreaudio.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 6dfd63eb42..433e009db5 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -50,6 +50,16 @@ typedef struct coreaudioVoiceOut { int rpos; } coreaudioVoiceOut; +static OSStatus coreaudio_get_voice(AudioDeviceID *id) +{ + UInt32 size = sizeof(*id); + + return AudioHardwareGetProperty( + kAudioHardwarePropertyDefaultOutputDevice, + &size, + id); +} + static void coreaudio_logstatus (OSStatus status) { const char *str = "BUG"; @@ -303,12 +313,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, audio_pcm_init_info (&hw->info, as); - /* open default output device */ - propertySize = sizeof(core->outputDeviceID); - status = AudioHardwareGetProperty( - kAudioHardwarePropertyDefaultOutputDevice, - &propertySize, - &core->outputDeviceID); + status = coreaudio_get_voice(&core->outputDeviceID); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, "Could not get default output Device\n"); From 624d1fc30fd64e082880ca21cae5fadb67d05c64 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sat, 28 Nov 2015 21:55:21 +0000 Subject: [PATCH 2/5] audio/coreaudio.c: Use new-in-OSX-10.6 API for getting default voice If we're building for OSX 10.6 or better, use the new API AudioObjectGetPropertyData for getting the default voice. Signed-off-by: Peter Maydell Message-id: 1448747724-15572-3-git-send-email-peter.maydell@linaro.org Signed-off-by: Gerd Hoffmann --- audio/coreaudio.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 433e009db5..2211e17998 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -32,6 +32,10 @@ #define AUDIO_CAP "coreaudio" #include "audio_int.h" +#ifndef MAC_OS_X_VERSION_10_6 +#define MAC_OS_X_VERSION_10_6 1060 +#endif + static int isAtexit; typedef struct { @@ -50,6 +54,28 @@ typedef struct coreaudioVoiceOut { int rpos; } coreaudioVoiceOut; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +/* The APIs used here only become available from 10.6 */ + +static OSStatus coreaudio_get_voice(AudioDeviceID *id) +{ + UInt32 size = sizeof(*id); + AudioObjectPropertyAddress addr = { + kAudioHardwarePropertyDefaultOutputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; + + return AudioObjectGetPropertyData(kAudioObjectSystemObject, + &addr, + 0, + NULL, + &size, + id); +} +#else +/* Legacy versions of functions using deprecated APIs */ + static OSStatus coreaudio_get_voice(AudioDeviceID *id) { UInt32 size = sizeof(*id); @@ -59,6 +85,7 @@ static OSStatus coreaudio_get_voice(AudioDeviceID *id) &size, id); } +#endif static void coreaudio_logstatus (OSStatus status) { From 95a860f62e185d4100e980d43d348482a6419514 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sat, 28 Nov 2015 21:55:22 +0000 Subject: [PATCH 3/5] audio/coreaudio.c: Factor out uses of AudioDeviceGet/SetProperty The CoreAudio APIs AudioDeviceGetProperty and AudioDeviceSetProperty are deprecated from OSX 10.6, so factor out our calls to them so we can provide versions which use the replacement APIs on OSX newer than 10.5. Signed-off-by: Peter Maydell Message-id: 1448747724-15572-4-git-send-email-peter.maydell@linaro.org Signed-off-by: Gerd Hoffmann --- audio/coreaudio.c | 141 ++++++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 47 deletions(-) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 2211e17998..c7e31eac0f 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -87,6 +87,89 @@ static OSStatus coreaudio_get_voice(AudioDeviceID *id) } #endif +static OSStatus coreaudio_get_framesizerange(AudioDeviceID id, + AudioValueRange *framerange) +{ + UInt32 size = sizeof(*framerange); + + return AudioDeviceGetProperty( + id, + 0, + 0, + kAudioDevicePropertyBufferFrameSizeRange, + &size, + framerange); +} + +static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize) +{ + UInt32 size = sizeof(*framesize); + + return AudioDeviceGetProperty( + id, + 0, + false, + kAudioDevicePropertyBufferFrameSize, + &size, + framesize); +} + +static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize) +{ + UInt32 size = sizeof(*framesize); + + return AudioDeviceSetProperty( + id, + NULL, + 0, + false, + kAudioDevicePropertyBufferFrameSize, + size, + framesize); +} + +static OSStatus coreaudio_get_streamformat(AudioDeviceID id, + AudioStreamBasicDescription *d) +{ + UInt32 size = sizeof(*d); + + return AudioDeviceGetProperty( + id, + 0, + false, + kAudioDevicePropertyStreamFormat, + &size, + d); +} + +static OSStatus coreaudio_set_streamformat(AudioDeviceID id, + AudioStreamBasicDescription *d) +{ + UInt32 size = sizeof(*d); + + return AudioDeviceSetProperty( + id, + 0, + 0, + 0, + kAudioDevicePropertyStreamFormat, + size, + d); +} + +static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result) +{ + UInt32 size = sizeof(*result); + + return AudioDeviceGetProperty( + id, + 0, + 0, + kAudioDevicePropertyDeviceIsRunning, + &size, + result); +} + static void coreaudio_logstatus (OSStatus status) { const char *str = "BUG"; @@ -181,10 +264,7 @@ static inline UInt32 isPlaying (AudioDeviceID outputDeviceID) { OSStatus status; UInt32 result = 0; - UInt32 propertySize = sizeof(outputDeviceID); - status = AudioDeviceGetProperty( - outputDeviceID, 0, 0, - kAudioDevicePropertyDeviceIsRunning, &propertySize, &result); + status = coreaudio_get_isrunning(outputDeviceID, &result); if (status != kAudioHardwareNoError) { coreaudio_logerr(status, "Could not determine whether Device is playing\n"); @@ -325,7 +405,6 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, { OSStatus status; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; - UInt32 propertySize; int err; const char *typ = "playback"; AudioValueRange frameRange; @@ -352,14 +431,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, } /* get minimum and maximum buffer frame sizes */ - propertySize = sizeof(frameRange); - status = AudioDeviceGetProperty( - core->outputDeviceID, - 0, - 0, - kAudioDevicePropertyBufferFrameSizeRange, - &propertySize, - &frameRange); + status = coreaudio_get_framesizerange(core->outputDeviceID, + &frameRange); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, "Could not get device buffer frame range\n"); @@ -379,15 +452,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, } /* set Buffer Frame Size */ - propertySize = sizeof(core->audioDevicePropertyBufferFrameSize); - status = AudioDeviceSetProperty( - core->outputDeviceID, - NULL, - 0, - false, - kAudioDevicePropertyBufferFrameSize, - propertySize, - &core->audioDevicePropertyBufferFrameSize); + status = coreaudio_set_framesize(core->outputDeviceID, + &core->audioDevicePropertyBufferFrameSize); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, "Could not set device buffer frame size %" PRIu32 "\n", @@ -396,14 +462,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, } /* get Buffer Frame Size */ - propertySize = sizeof(core->audioDevicePropertyBufferFrameSize); - status = AudioDeviceGetProperty( - core->outputDeviceID, - 0, - false, - kAudioDevicePropertyBufferFrameSize, - &propertySize, - &core->audioDevicePropertyBufferFrameSize); + status = coreaudio_get_framesize(core->outputDeviceID, + &core->audioDevicePropertyBufferFrameSize); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, "Could not get device buffer frame size\n"); @@ -412,14 +472,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, hw->samples = conf->nbuffers * core->audioDevicePropertyBufferFrameSize; /* get StreamFormat */ - propertySize = sizeof(core->outputStreamBasicDescription); - status = AudioDeviceGetProperty( - core->outputDeviceID, - 0, - false, - kAudioDevicePropertyStreamFormat, - &propertySize, - &core->outputStreamBasicDescription); + status = coreaudio_get_streamformat(core->outputDeviceID, + &core->outputStreamBasicDescription); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, "Could not get Device Stream properties\n"); @@ -429,15 +483,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, /* set Samplerate */ core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq; - propertySize = sizeof(core->outputStreamBasicDescription); - status = AudioDeviceSetProperty( - core->outputDeviceID, - 0, - 0, - 0, - kAudioDevicePropertyStreamFormat, - propertySize, - &core->outputStreamBasicDescription); + status = coreaudio_set_streamformat(core->outputDeviceID, + &core->outputStreamBasicDescription); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n", as->freq); From 2d99f6299bb98e4e87aa71996a44439f2c62969d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sat, 28 Nov 2015 21:55:23 +0000 Subject: [PATCH 4/5] audio/coreaudio.c: Use new-in-OSX-10.6 APIs when available Use the new-in-OSX 10.6 API AudioObjectGetPropertyData() instead of the deprecated AudioDeviceGetProperty() and AudioDeviceSetProperty() functions when possible. Signed-off-by: Peter Maydell Message-id: 1448747724-15572-5-git-send-email-peter.maydell@linaro.org Signed-off-by: Gerd Hoffmann --- audio/coreaudio.c | 107 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index c7e31eac0f..32a997b936 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -73,6 +73,111 @@ static OSStatus coreaudio_get_voice(AudioDeviceID *id) &size, id); } + +static OSStatus coreaudio_get_framesizerange(AudioDeviceID id, + AudioValueRange *framerange) +{ + UInt32 size = sizeof(*framerange); + AudioObjectPropertyAddress addr = { + kAudioDevicePropertyBufferFrameSizeRange, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + return AudioObjectGetPropertyData(id, + &addr, + 0, + NULL, + &size, + framerange); +} + +static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize) +{ + UInt32 size = sizeof(*framesize); + AudioObjectPropertyAddress addr = { + kAudioDevicePropertyBufferFrameSize, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + return AudioObjectGetPropertyData(id, + &addr, + 0, + NULL, + &size, + framesize); +} + +static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize) +{ + UInt32 size = sizeof(*framesize); + AudioObjectPropertyAddress addr = { + kAudioDevicePropertyBufferFrameSize, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + return AudioObjectSetPropertyData(id, + &addr, + 0, + NULL, + size, + framesize); +} + +static OSStatus coreaudio_get_streamformat(AudioDeviceID id, + AudioStreamBasicDescription *d) +{ + UInt32 size = sizeof(*d); + AudioObjectPropertyAddress addr = { + kAudioDevicePropertyStreamFormat, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + return AudioObjectGetPropertyData(id, + &addr, + 0, + NULL, + &size, + d); +} + +static OSStatus coreaudio_set_streamformat(AudioDeviceID id, + AudioStreamBasicDescription *d) +{ + UInt32 size = sizeof(*d); + AudioObjectPropertyAddress addr = { + kAudioDevicePropertyStreamFormat, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + return AudioObjectSetPropertyData(id, + &addr, + 0, + NULL, + size, + d); +} + +static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result) +{ + UInt32 size = sizeof(*result); + AudioObjectPropertyAddress addr = { + kAudioDevicePropertyDeviceIsRunning, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + return AudioObjectGetPropertyData(id, + &addr, + 0, + NULL, + &size, + result); +} #else /* Legacy versions of functions using deprecated APIs */ @@ -85,7 +190,6 @@ static OSStatus coreaudio_get_voice(AudioDeviceID *id) &size, id); } -#endif static OSStatus coreaudio_get_framesizerange(AudioDeviceID id, AudioValueRange *framerange) @@ -169,6 +273,7 @@ static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result) &size, result); } +#endif static void coreaudio_logstatus (OSStatus status) { From 2f79a18fdd6e8e75ab9bd4edc90a641ab730824d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sat, 28 Nov 2015 21:55:24 +0000 Subject: [PATCH 5/5] audio/coreaudio.c: Avoid deprecated AudioDeviceAdd/RemoveIOProc APIs The AudioDeviceAddIOProc() and AudioDeviceRemoveIOProc() functions were deprecated in OSX 10.5. Since we don't support any earlier versions of OSX, we can simply replace them with the new APIs AudioDeviceCreateIOProcID() and AudioDeviceRemoveIOProcID(). Signed-off-by: Peter Maydell Message-id: 1448747724-15572-6-git-send-email-peter.maydell@linaro.org Signed-off-by: Gerd Hoffmann --- audio/coreaudio.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 32a997b936..7150604c53 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -49,6 +49,7 @@ typedef struct coreaudioVoiceOut { AudioDeviceID outputDeviceID; UInt32 audioDevicePropertyBufferFrameSize; AudioStreamBasicDescription outputStreamBasicDescription; + AudioDeviceIOProcID ioprocid; int live; int decr; int rpos; @@ -598,8 +599,12 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, } /* set Callback */ - status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw); - if (status != kAudioHardwareNoError) { + core->ioprocid = NULL; + status = AudioDeviceCreateIOProcID(core->outputDeviceID, + audioDeviceIOProc, + hw, + &core->ioprocid); + if (status != kAudioHardwareNoError || core->ioprocid == NULL) { coreaudio_logerr2 (status, typ, "Could not set IOProc\n"); core->outputDeviceID = kAudioDeviceUnknown; return -1; @@ -607,10 +612,10 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, /* start Playback */ if (!isPlaying(core->outputDeviceID)) { - status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc); + status = AudioDeviceStart(core->outputDeviceID, core->ioprocid); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, "Could not start playback\n"); - AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc); + AudioDeviceDestroyIOProcID(core->outputDeviceID, core->ioprocid); core->outputDeviceID = kAudioDeviceUnknown; return -1; } @@ -628,15 +633,15 @@ static void coreaudio_fini_out (HWVoiceOut *hw) if (!isAtexit) { /* stop playback */ if (isPlaying(core->outputDeviceID)) { - status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc); + status = AudioDeviceStop(core->outputDeviceID, core->ioprocid); if (status != kAudioHardwareNoError) { coreaudio_logerr (status, "Could not stop playback\n"); } } /* remove callback */ - status = AudioDeviceRemoveIOProc(core->outputDeviceID, - audioDeviceIOProc); + status = AudioDeviceDestroyIOProcID(core->outputDeviceID, + core->ioprocid); if (status != kAudioHardwareNoError) { coreaudio_logerr (status, "Could not remove IOProc\n"); } @@ -659,7 +664,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) case VOICE_ENABLE: /* start playback */ if (!isPlaying(core->outputDeviceID)) { - status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc); + status = AudioDeviceStart(core->outputDeviceID, core->ioprocid); if (status != kAudioHardwareNoError) { coreaudio_logerr (status, "Could not resume playback\n"); } @@ -670,7 +675,8 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) /* stop playback */ if (!isAtexit) { if (isPlaying(core->outputDeviceID)) { - status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc); + status = AudioDeviceStop(core->outputDeviceID, + core->ioprocid); if (status != kAudioHardwareNoError) { coreaudio_logerr (status, "Could not pause playback\n"); }