From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>,
Akihiko Odaki <akihiko.odaki@gmail.com>
Subject: [PULL 2/3] coreaudio: Extract device operations
Date: Tue, 16 Mar 2021 11:47:44 +0100 [thread overview]
Message-ID: <20210316104745.2196286-3-kraxel@redhat.com> (raw)
In-Reply-To: <20210316104745.2196286-1-kraxel@redhat.com>
From: Akihiko Odaki <akihiko.odaki@gmail.com>
This change prepare to support dynamic device changes, which requires to
perform device initialization/deinitialization multiple times.
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Message-Id: <20210311151512.22096-2-akihiko.odaki@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
audio/coreaudio.c | 137 +++++++++++++++++++++++++++-------------------
1 file changed, 80 insertions(+), 57 deletions(-)
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index c5f0b615d643..ab43cdcac199 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -36,6 +36,8 @@ typedef struct coreaudioVoiceOut {
HWVoiceOut hw;
pthread_mutex_t mutex;
AudioDeviceID outputDeviceID;
+ int frameSizeSetting;
+ uint32_t bufferCount;
UInt32 audioDevicePropertyBufferFrameSize;
AudioStreamBasicDescription outputStreamBasicDescription;
AudioDeviceIOProcID ioprocid;
@@ -253,6 +255,9 @@ static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
coreaudio_logstatus (status);
}
+#define coreaudio_playback_logerr(status, ...) \
+ coreaudio_logerr2(status, "playback", __VA_ARGS__)
+
static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
{
OSStatus status;
@@ -368,126 +373,100 @@ static OSStatus audioDeviceIOProc(
return 0;
}
-static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
+static OSStatus init_out_device(coreaudioVoiceOut *core)
{
OSStatus status;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
- int err;
- const char *typ = "playback";
AudioValueRange frameRange;
- Audiodev *dev = drv_opaque;
- AudiodevCoreaudioPerDirectionOptions *cpdo = dev->u.coreaudio.out;
- int frames;
- struct audsettings obt_as;
-
- /* create mutex */
- err = pthread_mutex_init(&core->mutex, NULL);
- if (err) {
- dolog("Could not create mutex\nReason: %s\n", strerror (err));
- return -1;
- }
-
- obt_as = *as;
- as = &obt_as;
- as->fmt = AUDIO_FORMAT_F32;
- audio_pcm_init_info (&hw->info, as);
status = coreaudio_get_voice(&core->outputDeviceID);
if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get default output Device\n");
- return -1;
+ coreaudio_playback_logerr (status,
+ "Could not get default output Device\n");
+ return status;
}
if (core->outputDeviceID == kAudioDeviceUnknown) {
- dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
- return -1;
+ dolog ("Could not initialize playback - Unknown Audiodevice\n");
+ return status;
}
/* get minimum and maximum buffer frame sizes */
status = coreaudio_get_framesizerange(core->outputDeviceID,
&frameRange);
if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame range\n");
- return -1;
+ coreaudio_playback_logerr (status,
+ "Could not get device buffer frame range\n");
+ return status;
}
- frames = audio_buffer_frames(
- qapi_AudiodevCoreaudioPerDirectionOptions_base(cpdo), as, 11610);
- if (frameRange.mMinimum > frames) {
+ if (frameRange.mMinimum > core->frameSizeSetting) {
core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum;
dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum);
- } else if (frameRange.mMaximum < frames) {
+ } else if (frameRange.mMaximum < core->frameSizeSetting) {
core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum;
dolog ("warning: Downsizing Buffer Frames to %f\n", frameRange.mMaximum);
} else {
- core->audioDevicePropertyBufferFrameSize = frames;
+ core->audioDevicePropertyBufferFrameSize = core->frameSizeSetting;
}
/* set Buffer Frame Size */
status = coreaudio_set_framesize(core->outputDeviceID,
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not set device buffer frame size %" PRIu32 "\n",
- (uint32_t)core->audioDevicePropertyBufferFrameSize);
- return -1;
+ coreaudio_playback_logerr (status,
+ "Could not set device buffer frame size %" PRIu32 "\n",
+ (uint32_t)core->audioDevicePropertyBufferFrameSize);
+ return status;
}
/* get Buffer Frame Size */
status = coreaudio_get_framesize(core->outputDeviceID,
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame size\n");
- return -1;
+ coreaudio_playback_logerr (status,
+ "Could not get device buffer frame size\n");
+ return status;
}
- hw->samples = (cpdo->has_buffer_count ? cpdo->buffer_count : 4) *
- core->audioDevicePropertyBufferFrameSize;
+ core->hw.samples = core->bufferCount * core->audioDevicePropertyBufferFrameSize;
/* get StreamFormat */
status = coreaudio_get_streamformat(core->outputDeviceID,
&core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get Device Stream properties\n");
+ coreaudio_playback_logerr (status,
+ "Could not get Device Stream properties\n");
core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
+ return status;
}
/* set Samplerate */
- core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
-
status = coreaudio_set_streamformat(core->outputDeviceID,
&core->outputStreamBasicDescription);
if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
- as->freq);
+ coreaudio_playback_logerr (status,
+ "Could not set samplerate %lf\n",
+ core->outputStreamBasicDescription.mSampleRate);
core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
+ return status;
}
/* set Callback */
core->ioprocid = NULL;
status = AudioDeviceCreateIOProcID(core->outputDeviceID,
audioDeviceIOProc,
- hw,
+ &core->hw,
&core->ioprocid);
if (status != kAudioHardwareNoError || core->ioprocid == NULL) {
- coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
+ coreaudio_playback_logerr (status, "Could not set IOProc\n");
core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
+ return status;
}
return 0;
}
-static void coreaudio_fini_out (HWVoiceOut *hw)
+static void fini_out_device(coreaudioVoiceOut *core)
{
OSStatus status;
- int err;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
/* stop playback */
if (isPlaying(core->outputDeviceID)) {
@@ -504,6 +483,50 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
coreaudio_logerr(status, "Could not remove IOProc\n");
}
core->outputDeviceID = kAudioDeviceUnknown;
+}
+
+static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
+ void *drv_opaque)
+{
+ OSStatus status;
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
+ int err;
+ Audiodev *dev = drv_opaque;
+ AudiodevCoreaudioPerDirectionOptions *cpdo = dev->u.coreaudio.out;
+ struct audsettings obt_as;
+
+ /* create mutex */
+ err = pthread_mutex_init(&core->mutex, NULL);
+ if (err) {
+ dolog("Could not create mutex\nReason: %s\n", strerror (err));
+ return -1;
+ }
+
+ obt_as = *as;
+ as = &obt_as;
+ as->fmt = AUDIO_FORMAT_F32;
+ audio_pcm_init_info (&hw->info, as);
+
+ core->frameSizeSetting = audio_buffer_frames(
+ qapi_AudiodevCoreaudioPerDirectionOptions_base(cpdo), as, 11610);
+
+ core->bufferCount = cpdo->has_buffer_count ? cpdo->buffer_count : 4;
+ core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
+
+ if (init_out_device(core)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static void coreaudio_fini_out (HWVoiceOut *hw)
+{
+ OSStatus status;
+ int err;
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
+
+ fini_out_device(core);
/* destroy mutex */
err = pthread_mutex_destroy(&core->mutex);
--
2.30.2
next prev parent reply other threads:[~2021-03-16 10:49 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-16 10:47 [PULL 0/3] Audio 20210316 patches Gerd Hoffmann
2021-03-16 10:47 ` [PULL 1/3] coreaudio: Drop support for macOS older than 10.6 Gerd Hoffmann
2021-03-16 10:47 ` Gerd Hoffmann [this message]
2021-03-16 10:47 ` [PULL 3/3] coreaudio: Handle output device change Gerd Hoffmann
2021-03-16 10:54 ` [PULL 0/3] Audio 20210316 patches no-reply
2021-03-17 18:27 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210316104745.2196286-3-kraxel@redhat.com \
--to=kraxel@redhat.com \
--cc=akihiko.odaki@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).