aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-12-17 11:10:03 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-12-17 11:10:03 +0000
commitfc77eb20d78e303ef11482288e185d856431f02f (patch)
treec444374bd3157b8201a243ede80c882037300830
parentdc337c6e26abe6b9fb4ec654e9d19e123645a198 (diff)
parent2f79a18fdd6e8e75ab9bd4edc90a641ab730824d (diff)
Merge remote-tracking branch 'remotes/kraxel/tags/pull-audio-20151215-1' into staging
coreaudio: use new-in-OSX-10.6 APIs, cleanups. # gpg: Signature made Tue 15 Dec 2015 10:15:24 GMT using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-audio-20151215-1: audio/coreaudio.c: Avoid deprecated AudioDeviceAdd/RemoveIOProc APIs audio/coreaudio.c: Use new-in-OSX-10.6 APIs when available audio/coreaudio.c: Factor out uses of AudioDeviceGet/SetProperty audio/coreaudio.c: Use new-in-OSX-10.6 API for getting default voice audio/coreaudio.c: Factor out use of AudioHardwareGetProperty Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--audio/coreaudio.c314
1 files changed, 252 insertions, 62 deletions
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 6dfd63eb42..7150604c53 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 {
@@ -45,11 +49,233 @@ typedef struct coreaudioVoiceOut {
AudioDeviceID outputDeviceID;
UInt32 audioDevicePropertyBufferFrameSize;
AudioStreamBasicDescription outputStreamBasicDescription;
+ AudioDeviceIOProcID ioprocid;
int live;
int decr;
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);
+}
+
+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 */
+
+static OSStatus coreaudio_get_voice(AudioDeviceID *id)
+{
+ UInt32 size = sizeof(*id);
+
+ return AudioHardwareGetProperty(
+ kAudioHardwarePropertyDefaultOutputDevice,
+ &size,
+ id);
+}
+
+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);
+}
+#endif
+
static void coreaudio_logstatus (OSStatus status)
{
const char *str = "BUG";
@@ -144,10 +370,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");
@@ -288,7 +511,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;
@@ -303,12 +525,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");
@@ -320,14 +537,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");
@@ -347,15 +558,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",
@@ -364,14 +568,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");
@@ -380,14 +578,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");
@@ -397,15 +589,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);
@@ -414,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;
@@ -423,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;
}
@@ -444,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");
}
@@ -475,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");
}
@@ -486,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");
}