coreaudio: use new-in-OSX-10.6 APIs, cleanups.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJWb+g8AAoJEEy22O7T6HE4598P+wUYozF1boxpZjoiq5IYcJOg
 vg3m/5RoKjCSh2na/oodu7jK4W8X71K+dph1I5kMI5IAi650NIHqsSYeLb4hZYRP
 Fw1geaQnV9ce4BwnLL1JssC+QfdgyaU1WsXX8sfbWrrCPgO8Jt5kqs0VqkWDAwgF
 8v88TGrNNIwXH9KSMp4ibbqVzTBmgTuHd8rTU6nSQ9gICVuZSV3CTITV0/MzEdex
 R9hSRZ1730muTllxO1Z+PD/h+0eGcr+BF9hBmFLqxueARcofNY/qmIWmfq9sP+Sw
 0ax+/0FsEuS6ZsOr0rv9eyCnTuVGqn1Nye7GLXbIlG9Zz8q0OYRi37z4VJ8CWB1q
 WgaRDjTw9oIpMeDnd4s3xbjqT4VPDrGbo1ZLVkRa3MYTbjR8GTNqXgi292kpd8Sl
 SDQD7BP02iYyNV8jU4BmwcI+kOafI2hAPl+3+fhVsU+fHGZxaWnfaLUp68c+Za4u
 0oF/7M6asBmuzqoZ7KQdDHq/U8ZH/VGZ0quwV2HytmBOjMrlLJQ4I7OaJFD7Ongs
 bW7lFLNKFFmILpRWp1ZgX9qvosXBz/1/x6MEKduH2KopSOodmu2DSZhkSSeA03qG
 siEJRtUwNxZeOFEukBljpkyimLde1k+UcCT+ls2TZN8BylorVDyLvBi/rTYG+C87
 7v12DNb0xZKSpCJ6Rxfw
 =/x9Q
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2015-12-17 11:10:03 +00:00
commit fc77eb20d7

View File

@ -32,6 +32,10 @@
#define AUDIO_CAP "coreaudio" #define AUDIO_CAP "coreaudio"
#include "audio_int.h" #include "audio_int.h"
#ifndef MAC_OS_X_VERSION_10_6
#define MAC_OS_X_VERSION_10_6 1060
#endif
static int isAtexit; static int isAtexit;
typedef struct { typedef struct {
@ -45,11 +49,233 @@ typedef struct coreaudioVoiceOut {
AudioDeviceID outputDeviceID; AudioDeviceID outputDeviceID;
UInt32 audioDevicePropertyBufferFrameSize; UInt32 audioDevicePropertyBufferFrameSize;
AudioStreamBasicDescription outputStreamBasicDescription; AudioStreamBasicDescription outputStreamBasicDescription;
AudioDeviceIOProcID ioprocid;
int live; int live;
int decr; int decr;
int rpos; int rpos;
} coreaudioVoiceOut; } 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) static void coreaudio_logstatus (OSStatus status)
{ {
const char *str = "BUG"; const char *str = "BUG";
@ -144,10 +370,7 @@ static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
{ {
OSStatus status; OSStatus status;
UInt32 result = 0; UInt32 result = 0;
UInt32 propertySize = sizeof(outputDeviceID); status = coreaudio_get_isrunning(outputDeviceID, &result);
status = AudioDeviceGetProperty(
outputDeviceID, 0, 0,
kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr(status, coreaudio_logerr(status,
"Could not determine whether Device is playing\n"); "Could not determine whether Device is playing\n");
@ -288,7 +511,6 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
{ {
OSStatus status; OSStatus status;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
UInt32 propertySize;
int err; int err;
const char *typ = "playback"; const char *typ = "playback";
AudioValueRange frameRange; AudioValueRange frameRange;
@ -303,12 +525,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
audio_pcm_init_info (&hw->info, as); audio_pcm_init_info (&hw->info, as);
/* open default output device */ status = coreaudio_get_voice(&core->outputDeviceID);
propertySize = sizeof(core->outputDeviceID);
status = AudioHardwareGetProperty(
kAudioHardwarePropertyDefaultOutputDevice,
&propertySize,
&core->outputDeviceID);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Could not get default output Device\n"); "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 */ /* get minimum and maximum buffer frame sizes */
propertySize = sizeof(frameRange); status = coreaudio_get_framesizerange(core->outputDeviceID,
status = AudioDeviceGetProperty( &frameRange);
core->outputDeviceID,
0,
0,
kAudioDevicePropertyBufferFrameSizeRange,
&propertySize,
&frameRange);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Could not get device buffer frame range\n"); "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 */ /* set Buffer Frame Size */
propertySize = sizeof(core->audioDevicePropertyBufferFrameSize); status = coreaudio_set_framesize(core->outputDeviceID,
status = AudioDeviceSetProperty( &core->audioDevicePropertyBufferFrameSize);
core->outputDeviceID,
NULL,
0,
false,
kAudioDevicePropertyBufferFrameSize,
propertySize,
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Could not set device buffer frame size %" PRIu32 "\n", "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 */ /* get Buffer Frame Size */
propertySize = sizeof(core->audioDevicePropertyBufferFrameSize); status = coreaudio_get_framesize(core->outputDeviceID,
status = AudioDeviceGetProperty( &core->audioDevicePropertyBufferFrameSize);
core->outputDeviceID,
0,
false,
kAudioDevicePropertyBufferFrameSize,
&propertySize,
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Could not get device buffer frame size\n"); "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; hw->samples = conf->nbuffers * core->audioDevicePropertyBufferFrameSize;
/* get StreamFormat */ /* get StreamFormat */
propertySize = sizeof(core->outputStreamBasicDescription); status = coreaudio_get_streamformat(core->outputDeviceID,
status = AudioDeviceGetProperty( &core->outputStreamBasicDescription);
core->outputDeviceID,
0,
false,
kAudioDevicePropertyStreamFormat,
&propertySize,
&core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, coreaudio_logerr2 (status, typ,
"Could not get Device Stream properties\n"); "Could not get Device Stream properties\n");
@ -397,15 +589,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
/* set Samplerate */ /* set Samplerate */
core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq; core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
propertySize = sizeof(core->outputStreamBasicDescription); status = coreaudio_set_streamformat(core->outputDeviceID,
status = AudioDeviceSetProperty( &core->outputStreamBasicDescription);
core->outputDeviceID,
0,
0,
0,
kAudioDevicePropertyStreamFormat,
propertySize,
&core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n", coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
as->freq); as->freq);
@ -414,8 +599,12 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
} }
/* set Callback */ /* set Callback */
status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw); core->ioprocid = NULL;
if (status != kAudioHardwareNoError) { status = AudioDeviceCreateIOProcID(core->outputDeviceID,
audioDeviceIOProc,
hw,
&core->ioprocid);
if (status != kAudioHardwareNoError || core->ioprocid == NULL) {
coreaudio_logerr2 (status, typ, "Could not set IOProc\n"); coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
core->outputDeviceID = kAudioDeviceUnknown; core->outputDeviceID = kAudioDeviceUnknown;
return -1; return -1;
@ -423,10 +612,10 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
/* start Playback */ /* start Playback */
if (!isPlaying(core->outputDeviceID)) { if (!isPlaying(core->outputDeviceID)) {
status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStart(core->outputDeviceID, core->ioprocid);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ, "Could not start playback\n"); coreaudio_logerr2 (status, typ, "Could not start playback\n");
AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc); AudioDeviceDestroyIOProcID(core->outputDeviceID, core->ioprocid);
core->outputDeviceID = kAudioDeviceUnknown; core->outputDeviceID = kAudioDeviceUnknown;
return -1; return -1;
} }
@ -444,15 +633,15 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
if (!isAtexit) { if (!isAtexit) {
/* stop playback */ /* stop playback */
if (isPlaying(core->outputDeviceID)) { if (isPlaying(core->outputDeviceID)) {
status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStop(core->outputDeviceID, core->ioprocid);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not stop playback\n"); coreaudio_logerr (status, "Could not stop playback\n");
} }
} }
/* remove callback */ /* remove callback */
status = AudioDeviceRemoveIOProc(core->outputDeviceID, status = AudioDeviceDestroyIOProcID(core->outputDeviceID,
audioDeviceIOProc); core->ioprocid);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not remove IOProc\n"); coreaudio_logerr (status, "Could not remove IOProc\n");
} }
@ -475,7 +664,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
case VOICE_ENABLE: case VOICE_ENABLE:
/* start playback */ /* start playback */
if (!isPlaying(core->outputDeviceID)) { if (!isPlaying(core->outputDeviceID)) {
status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStart(core->outputDeviceID, core->ioprocid);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not resume playback\n"); coreaudio_logerr (status, "Could not resume playback\n");
} }
@ -486,7 +675,8 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
/* stop playback */ /* stop playback */
if (!isAtexit) { if (!isAtexit) {
if (isPlaying(core->outputDeviceID)) { if (isPlaying(core->outputDeviceID)) {
status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc); status = AudioDeviceStop(core->outputDeviceID,
core->ioprocid);
if (status != kAudioHardwareNoError) { if (status != kAudioHardwareNoError) {
coreaudio_logerr (status, "Could not pause playback\n"); coreaudio_logerr (status, "Could not pause playback\n");
} }