qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Volker Rümelin" <vr_qemu@t-online.de>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Gerd Hoffmann" <kraxel@redhat.com>
Subject: [PULL 11/12] coreaudio: fix coreaudio playback
Date: Fri,  7 Feb 2020 08:45:56 +0100	[thread overview]
Message-ID: <20200207074557.26073-12-kraxel@redhat.com> (raw)
In-Reply-To: <20200207074557.26073-1-kraxel@redhat.com>

From: Volker Rümelin <vr_qemu@t-online.de>

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 <vr_qemu@t-online.de>
Message-id: 20200202140641.4737-1-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio_template.h |  7 ++++++
 audio/mixeng.h         |  5 +++++
 audio/coreaudio.c      | 32 ++++++++--------------------
 audio/mixeng.c         | 48 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 23 deletions(-)

diff --git a/audio/audio_template.h b/audio/audio_template.h
index 3287d7075e6a..0336d2670cf6 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/mixeng.h b/audio/mixeng.h
index 18e62c7c49e7..7ef61763e8f9 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);
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index c7a7196c2d53..e3620b274bd6 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 2f5ba71381d4..16b646d48cdf 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)
-- 
2.18.1



  parent reply	other threads:[~2020-02-07  7:56 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
2020-02-07  7:45 ` [PULL 01/12] audio/oss: fix buffer pos calculation Gerd Hoffmann
2020-02-07  7:45 ` [PULL 02/12] audio: fix audio_generic_write Gerd Hoffmann
2020-02-07  7:45 ` [PULL 03/12] audio: fix audio_generic_read Gerd Hoffmann
2020-02-07  7:45 ` [PULL 04/12] paaudio: remove unused variables Gerd Hoffmann
2020-02-07  7:45 ` [PULL 05/12] audio: prevent SIGSEGV in AUD_get_buffer_size_out Gerd Hoffmann
2020-02-07  7:45 ` [PULL 06/12] audio: fix bug 1858488 Gerd Hoffmann
2020-02-07  7:45 ` [PULL 07/12] ossaudio: prevent SIGSEGV in oss_enable_out Gerd Hoffmann
2020-02-07  7:45 ` [PULL 08/12] ossaudio: disable poll mode can't be reached Gerd Hoffmann
2020-02-07  7:45 ` [PULL 09/12] audio: audio_generic_get_buffer_in should honor *size Gerd Hoffmann
2020-02-07  7:45 ` [PULL 10/12] audio/dsound: fix invalid parameters error Gerd Hoffmann
2020-02-07  7:45 ` Gerd Hoffmann [this message]
2020-02-07  7:45 ` [PULL 12/12] audio: proper support for float samples in mixeng Gerd Hoffmann
2020-02-07 13:53   ` Eric Blake
2020-02-07 15:01 ` [PULL 00/12] Audio 20200207 patches 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=20200207074557.26073-12-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=armbru@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=vr_qemu@t-online.de \
    /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).