From patchwork Sun Feb 2 14:06:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1232397 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=t-online.de Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 489Xp40D4qz9s29 for ; Mon, 3 Feb 2020 01:07:08 +1100 (AEDT) Received: from localhost ([::1]:56566 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iyFtx-0004CE-Va for incoming@patchwork.ozlabs.org; Sun, 02 Feb 2020 09:07:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:57280) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iyFth-0004C5-0v for qemu-devel@nongnu.org; Sun, 02 Feb 2020 09:06:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iyFtf-0005dX-EB for qemu-devel@nongnu.org; Sun, 02 Feb 2020 09:06:48 -0500 Received: from mailout10.t-online.de ([194.25.134.21]:59780) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iyFtf-0005aP-4Z for qemu-devel@nongnu.org; Sun, 02 Feb 2020 09:06:47 -0500 Received: from fwd18.aul.t-online.de (fwd18.aul.t-online.de [172.20.26.244]) by mailout10.t-online.de (Postfix) with SMTP id 8464341A7B68; Sun, 2 Feb 2020 15:06:45 +0100 (CET) Received: from linpower.localnet (X7U0oGZLohwsko9f04fZu69nFPHZxsegQjw56Kgmer3Gsbe5823GxpOk43zYqUDgZ7@[93.236.154.40]) by fwd18.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1iyFta-3ch9kG0; Sun, 2 Feb 2020 15:06:42 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id F17E32000A0; Sun, 2 Feb 2020 15:06:41 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann , =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= , Howard Spoelstra , Programmingkid , Mark Cave-Ayland Subject: [PATCH] coreaudio: fix coreaudio playback Date: Sun, 2 Feb 2020 15:06:41 +0100 Message-Id: <20200202140641.4737-1-vr_qemu@t-online.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <30c8b9e6-484c-5785-b178-bef01628db49@t-online.de> References: <30c8b9e6-484c-5785-b178-bef01628db49@t-online.de> MIME-Version: 1.0 X-ID: X7U0oGZLohwsko9f04fZu69nFPHZxsegQjw56Kgmer3Gsbe5823GxpOk43zYqUDgZ7 X-TOI-MSGID: dc913e5d-277b-471e-a3f7-818cec686527 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 194.25.134.21 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu Developers Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" There are reports that since commit 2ceb8240fa "coreaudio: port to the new audio backend api" audio playback with CoreAudio is broken. This patch reverts some parts the commit. Because of changes in the audio subsystem the audio clip function in v4.1.0 of coreaudio.c had to be moved to mixeng.c and the generic buffer management code needed a hint about the size of the float type. This patch is based on a patch from Zoltán Kővágó found at https://lists.nongnu.org/archive/html/qemu-devel/2020-01/msg02142.html. Fixes: 2ceb8240fa "coreaudio: port to the new audio backend api" Signed-off-by: Volker Rümelin --- audio/audio_template.h | 7 +++++++ audio/coreaudio.c | 32 +++++++++----------------------- audio/mixeng.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ audio/mixeng.h | 5 +++++ 4 files changed, 69 insertions(+), 23 deletions(-) diff --git a/audio/audio_template.h b/audio/audio_template.h index 3287d7075e..0336d2670c 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -276,6 +276,13 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, goto err1; } + if (s->dev->driver == AUDIODEV_DRIVER_COREAUDIO) { +#ifdef DAC + hw->clip = clip_natural_float_from_stereo; +#else + hw->conv = conv_natural_float_to_stereo; +#endif + } else #ifdef DAC hw->clip = mixeng_clip #else diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 66f0f459cf..0049db97fa 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -471,20 +471,6 @@ static OSStatus audioDeviceIOProc( return 0; } -static UInt32 coreaudio_get_flags(struct audio_pcm_info *info, - struct audsettings *as) -{ - UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger : 0; - if (as->endianness) { /* 0 = little, 1 = big */ - flags |= kAudioFormatFlagIsBigEndian; - } - - if (flags == 0) { /* must not be 0 */ - flags = kAudioFormatFlagsAreAllClear; - } - return flags; -} - static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { @@ -496,6 +482,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, Audiodev *dev = drv_opaque; AudiodevCoreaudioPerDirectionOptions *cpdo = dev->u.coreaudio.out; int frames; + struct audsettings fake_as; /* create mutex */ err = pthread_mutex_init(&core->mutex, NULL); @@ -504,6 +491,14 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, return -1; } + /* + * The canonical audio format for CoreAudio on macOS is float. Currently + * there is no generic code for AUDIO_FORMAT_F32 in qemu. Here we select + * AUDIO_FORMAT_S32 instead because only the sample size has to match. + */ + fake_as = *as; + as = &fake_as; + as->fmt = AUDIO_FORMAT_S32; audio_pcm_init_info (&hw->info, as); status = coreaudio_get_voice(&core->outputDeviceID); @@ -572,15 +567,6 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, /* set Samplerate */ core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq; - core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM; - core->outputStreamBasicDescription.mFormatFlags = - coreaudio_get_flags(&hw->info, as); - core->outputStreamBasicDescription.mBytesPerPacket = - core->outputStreamBasicDescription.mBytesPerFrame = - hw->info.nchannels * hw->info.bits / 8; - core->outputStreamBasicDescription.mFramesPerPacket = 1; - core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels; - core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits; status = coreaudio_set_streamformat(core->outputDeviceID, &core->outputStreamBasicDescription); diff --git a/audio/mixeng.c b/audio/mixeng.c index 2f5ba71381..16b646d48c 100644 --- a/audio/mixeng.c +++ b/audio/mixeng.c @@ -267,6 +267,54 @@ f_sample *mixeng_clip[2][2][2][3] = { } }; +void conv_natural_float_to_stereo(struct st_sample *dst, const void *src, + int samples) +{ + float *in = (float *)src; +#ifndef FLOAT_MIXENG + const float scale = UINT_MAX; +#endif + + while (samples--) { +#ifdef FLOAT_MIXENG + dst->l = *in++; + dst->r = *in++; +#else + dst->l = *in++ * scale; + dst->r = *in++ * scale; +#endif + dst++; + } +} + +void clip_natural_float_from_stereo(void *dst, const struct st_sample *src, + int samples) +{ + float *out = (float *)dst; +#ifndef FLOAT_MIXENG +#ifdef RECIPROCAL + const float scale = 1.f / UINT_MAX; +#else + const float scale = UINT_MAX; +#endif +#endif + + while (samples--) { +#ifdef FLOAT_MIXENG + *out++ = src->l; + *out++ = src->r; +#else +#ifdef RECIPROCAL + *out++ = src->l * scale; + *out++ = src->r * scale; +#else + *out++ = src->l / scale; + *out++ = src->r / scale; +#endif +#endif + src++; + } +} void audio_sample_to_uint64(void *samples, int pos, uint64_t *left, uint64_t *right) diff --git a/audio/mixeng.h b/audio/mixeng.h index 18e62c7c49..7ef61763e8 100644 --- a/audio/mixeng.h +++ b/audio/mixeng.h @@ -41,6 +41,11 @@ typedef void (f_sample) (void *dst, const struct st_sample *src, int samples); extern t_sample *mixeng_conv[2][2][2][3]; extern f_sample *mixeng_clip[2][2][2][3]; +void conv_natural_float_to_stereo(struct st_sample *dst, const void *src, + int samples); +void clip_natural_float_from_stereo(void *dst, const struct st_sample *src, + int samples); + void *st_rate_start (int inrate, int outrate); void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf, size_t *isamp, size_t *osamp);