All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/12] Audio 20200207 patches
@ 2020-02-07  7:45 Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 01/12] audio/oss: fix buffer pos calculation Gerd Hoffmann
                   ` (12 more replies)
  0 siblings, 13 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, Gerd Hoffmann

The following changes since commit 928173659d6e5dc368284f73f90ea1d129e1f57d:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200130' into staging (2020-01-30 16:19:04 +0000)

are available in the Git repository at:

  git://git.kraxel.org/qemu tags/audio-20200207-pull-request

for you to fetch changes up to ed2a4a794184df3dbd5ee4cc06e86fe220663faf:

  audio: proper support for float samples in mixeng (2020-02-06 14:35:57 +0100)

----------------------------------------------------------------
audio: bugfixes, mostly audio backend rewrite fallout

----------------------------------------------------------------

Gerd Hoffmann (1):
  audio/oss: fix buffer pos calculation

Kővágó, Zoltán (2):
  audio/dsound: fix invalid parameters error
  audio: proper support for float samples in mixeng

Volker Rümelin (9):
  audio: fix audio_generic_write
  audio: fix audio_generic_read
  paaudio: remove unused variables
  audio: prevent SIGSEGV in AUD_get_buffer_size_out
  audio: fix bug 1858488
  ossaudio: prevent SIGSEGV in oss_enable_out
  ossaudio: disable poll mode can't be reached
  audio: audio_generic_get_buffer_in should honor *size
  coreaudio: fix coreaudio playback

 audio/audio_int.h       |   7 +-
 audio/audio_template.h  |  40 +++++++----
 audio/dsound_template.h |   1 +
 audio/mixeng.h          |   5 ++
 audio/alsaaudio.c       |  18 +++++
 audio/audio.c           | 145 ++++++++++++++++++++++------------------
 audio/coreaudio.c       |  34 +++-------
 audio/dsoundaudio.c     |  27 ++++++--
 audio/mixeng.c          |  70 +++++++++++++++++++
 audio/noaudio.c         |   1 +
 audio/ossaudio.c        |  28 +++++---
 audio/paaudio.c         |  15 +++--
 audio/sdlaudio.c        |  35 +++++++++-
 audio/wavaudio.c        |   1 +
 qapi/audio.json         |   2 +-
 15 files changed, 302 insertions(+), 127 deletions(-)

-- 
2.18.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PULL 01/12] audio/oss: fix buffer pos calculation
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 02/12] audio: fix audio_generic_write Gerd Hoffmann
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, Gerd Hoffmann

Fixes: 3ba4066d085f ("ossaudio: port to the new audio backend api")
Reported-by: ziming zhang <ezrakiez@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20200120101804.29578-1-kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 audio/ossaudio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index c43faeeea4aa..94564916fbf0 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -420,7 +420,7 @@ static size_t oss_write(HWVoiceOut *hw, void *buf, size_t len)
             size_t to_copy = MIN(len, hw->size_emul - hw->pos_emul);
             memcpy(hw->buf_emul + hw->pos_emul, buf, to_copy);
 
-            hw->pos_emul = (hw->pos_emul + to_copy) % hw->pos_emul;
+            hw->pos_emul = (hw->pos_emul + to_copy) % hw->size_emul;
             buf += to_copy;
             len -= to_copy;
         }
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 02/12] audio: fix audio_generic_write
  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 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 03/12] audio: fix audio_generic_read Gerd Hoffmann
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

The pcm_ops function put_buffer_out expects the returned pointer
of function get_buffer_out as argument. Fix this.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-1-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/audio/audio.c b/audio/audio.c
index f63f39769a9f..7226aa64ff93 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1476,7 +1476,7 @@ size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
     copy_size = MIN(size, dst_size);
 
     memcpy(dst, buf, copy_size);
-    return hw->pcm_ops->put_buffer_out(hw, buf, copy_size);
+    return hw->pcm_ops->put_buffer_out(hw, dst, copy_size);
 }
 
 size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size)
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 03/12] audio: fix audio_generic_read
  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 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 04/12] paaudio: remove unused variables Gerd Hoffmann
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

It seems the function audio_generic_read started as a copy of
function audio_generic_write and some necessary changes were
forgotten. Fix the mixed up source and destination pointers and
rename misnamed variables.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-2-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 7226aa64ff93..9cd76a331d7a 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1481,12 +1481,12 @@ size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
 
 size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size)
 {
-    size_t dst_size, copy_size;
-    void *dst = hw->pcm_ops->get_buffer_in(hw, &dst_size);
-    copy_size = MIN(size, dst_size);
+    size_t src_size, copy_size;
+    void *src = hw->pcm_ops->get_buffer_in(hw, &src_size);
+    copy_size = MIN(size, src_size);
 
-    memcpy(dst, buf, copy_size);
-    hw->pcm_ops->put_buffer_in(hw, buf, copy_size);
+    memcpy(buf, src, copy_size);
+    hw->pcm_ops->put_buffer_in(hw, src, copy_size);
     return copy_size;
 }
 
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 04/12] paaudio: remove unused variables
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 03/12] audio: fix audio_generic_read Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 05/12] audio: prevent SIGSEGV in AUD_get_buffer_size_out Gerd Hoffmann
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

The unused variables were last used before commit 49ddd7e122
"paaudio: port to the new audio backend api".

Fixes: 49ddd7e122
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-3-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/paaudio.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index dbfe48c03a1d..8f37c6185161 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -32,7 +32,6 @@ typedef struct {
     HWVoiceOut hw;
     pa_stream *stream;
     paaudio *g;
-    size_t samples;
 } PAVoiceOut;
 
 typedef struct {
@@ -41,7 +40,6 @@ typedef struct {
     const void *read_data;
     size_t read_length;
     paaudio *g;
-    size_t samples;
 } PAVoiceIn;
 
 static void qpa_conn_fini(PAConnection *c);
@@ -488,7 +486,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
     }
 
     audio_pcm_init_info (&hw->info, &obt_as);
-    hw->samples = pa->samples = audio_buffer_samples(
+    hw->samples = audio_buffer_samples(
         qapi_AudiodevPaPerDirectionOptions_base(ppdo),
         &obt_as, ppdo->buffer_length);
 
@@ -536,7 +534,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
     }
 
     audio_pcm_init_info (&hw->info, &obt_as);
-    hw->samples = pa->samples = audio_buffer_samples(
+    hw->samples = audio_buffer_samples(
         qapi_AudiodevPaPerDirectionOptions_base(ppdo),
         &obt_as, ppdo->buffer_length);
 
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 05/12] audio: prevent SIGSEGV in AUD_get_buffer_size_out
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 04/12] paaudio: remove unused variables Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 06/12] audio: fix bug 1858488 Gerd Hoffmann
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

With audiodev parameter out.mixing-engine=off hw->mix_buf is
NULL. This leads to a segmentation fault in
AUD_get_buffer_size_out. This patch reverts a small part of
dc88e38fa7 "audio: unify input and output mixeng buffer
management".

To reproduce the problem start qemu with
-soundhw adlib -audiodev pa,id=audio0,out.mixing-engine=off

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-4-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 9cd76a331d7a..12ed318813f4 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -879,9 +879,9 @@ size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size)
     }
 }
 
-int AUD_get_buffer_size_out (SWVoiceOut *sw)
+int AUD_get_buffer_size_out(SWVoiceOut *sw)
 {
-    return sw->hw->mix_buf->size * sw->hw->info.bytes_per_frame;
+    return sw->hw->samples * sw->hw->info.bytes_per_frame;
 }
 
 void AUD_set_active_out (SWVoiceOut *sw, int on)
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 06/12] audio: fix bug 1858488
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 05/12] audio: prevent SIGSEGV in AUD_get_buffer_size_out Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 07/12] ossaudio: prevent SIGSEGV in oss_enable_out Gerd Hoffmann
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

The combined generic buffer management code and buffer run out
code in function audio_generic_put_buffer_out has a problematic
behaviour. A few hundred milliseconds after playback starts the
mixing buffer and the generic buffer are nearly full and the
following pattern can be seen.

On first call of audio_pcm_hw_run_out the buffer run code in
audio_generic_put_buffer_out writes some data to the audio
hardware but the generic buffer will fill faster and is full
when audio_pcm_hw_run_out returns. This is because emulated
audio devices can produce playback data at a higher rate than
the audio backend hardware consumes this data.

On next call of audio_pcm_hw_run_out the buffer run code in
audio_generic_put_buffer_out writes some data to the audio
hardware but no audio data is transferred to the generic buffer
because the buffer is already full.

Then the pattern repeats. For the emulated audio device this
looks like the audio timer period has doubled.

This patch splits the combined generic buffer management code
and buffer run out code and calls the buffer run out code after
buffer management code to break this pattern.

The bug report is for the wav audio backend. But the problem is
not limited to this backend. All audio backends which use the
audio_generic_put_buffer_out function show this problem.

Buglink: https://bugs.launchpad.net/qemu/+bug/1858488
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-5-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio_int.h |  4 +--
 audio/alsaaudio.c |  1 +
 audio/audio.c     | 64 ++++++++++++++++++++++-------------------------
 audio/coreaudio.c |  7 ++++--
 audio/noaudio.c   |  1 +
 audio/ossaudio.c  | 10 ++++++++
 audio/sdlaudio.c  |  7 ++++--
 audio/wavaudio.c  |  1 +
 8 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/audio/audio_int.h b/audio/audio_int.h
index 5ba20783463a..3c8e48b55b1c 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -152,6 +152,7 @@ struct audio_pcm_ops {
     int    (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque);
     void   (*fini_out)(HWVoiceOut *hw);
     size_t (*write)   (HWVoiceOut *hw, void *buf, size_t size);
+    void   (*run_buffer_out)(HWVoiceOut *hw);
     /*
      * get a buffer that after later can be passed to put_buffer_out; optional
      * returns the buffer, and writes it's size to size (in bytes)
@@ -178,10 +179,9 @@ struct audio_pcm_ops {
 
 void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
 void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
+void audio_generic_run_buffer_out(HWVoiceOut *hw);
 void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
 size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size);
-size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
-                                            size_t size);
 size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size);
 size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size);
 
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index f37ce1ce8570..4ef26818be57 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -906,6 +906,7 @@ static struct audio_pcm_ops alsa_pcm_ops = {
     .init_out = alsa_init_out,
     .fini_out = alsa_fini_out,
     .write    = alsa_write,
+    .run_buffer_out = audio_generic_run_buffer_out,
     .enable_out = alsa_enable_out,
 
     .init_in  = alsa_init_in,
diff --git a/audio/audio.c b/audio/audio.c
index 12ed318813f4..b686429203d6 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1097,6 +1097,10 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
         }
     }
 
+    if (hw->pcm_ops->run_buffer_out) {
+        hw->pcm_ops->run_buffer_out(hw);
+    }
+
     return clipped;
 }
 
@@ -1413,40 +1417,12 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
     hw->pending_emul -= size;
 }
 
-void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
+void audio_generic_run_buffer_out(HWVoiceOut *hw)
 {
-    if (unlikely(!hw->buf_emul)) {
-        size_t calc_size = hw->mix_buf->size * hw->info.bytes_per_frame;
-
-        hw->buf_emul = g_malloc(calc_size);
-        hw->size_emul = calc_size;
-        hw->pos_emul = hw->pending_emul = 0;
-    }
-
-    *size = MIN(hw->size_emul - hw->pending_emul,
-                hw->size_emul - hw->pos_emul);
-    return hw->buf_emul + hw->pos_emul;
-}
-
-size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
-                                            size_t size)
-{
-    assert(buf == hw->buf_emul + hw->pos_emul &&
-           size + hw->pending_emul <= hw->size_emul);
-
-    hw->pending_emul += size;
-    hw->pos_emul = (hw->pos_emul + size) % hw->size_emul;
-
-    return size;
-}
-
-size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
-{
-    audio_generic_put_buffer_out_nowrite(hw, buf, size);
-
     while (hw->pending_emul) {
         size_t write_len, written;
         ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul;
+
         if (start < 0) {
             start += hw->size_emul;
         }
@@ -1461,11 +1437,31 @@ size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
             break;
         }
     }
+}
+
+void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
+{
+    if (unlikely(!hw->buf_emul)) {
+        size_t calc_size = hw->mix_buf->size * hw->info.bytes_per_frame;
+
+        hw->buf_emul = g_malloc(calc_size);
+        hw->size_emul = calc_size;
+        hw->pos_emul = hw->pending_emul = 0;
+    }
+
+    *size = MIN(hw->size_emul - hw->pending_emul,
+                hw->size_emul - hw->pos_emul);
+    return hw->buf_emul + hw->pos_emul;
+}
+
+size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
+{
+    assert(buf == hw->buf_emul + hw->pos_emul &&
+           size + hw->pending_emul <= hw->size_emul);
+
+    hw->pending_emul += size;
+    hw->pos_emul = (hw->pos_emul + size) % hw->size_emul;
 
-    /*
-     * fake we have written everything. non-written data remain in pending_emul,
-     * so we do not have to clip them multiple times
-     */
     return size;
 }
 
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 66f0f459cf09..c7a7196c2d53 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -411,7 +411,7 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
     }
 COREAUDIO_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size),
                        (hw, size))
-COREAUDIO_WRAPPER_FUNC(put_buffer_out_nowrite, size_t,
+COREAUDIO_WRAPPER_FUNC(put_buffer_out, size_t,
                        (HWVoiceOut *hw, void *buf, size_t size),
                        (hw, buf, size))
 COREAUDIO_WRAPPER_FUNC(write, size_t, (HWVoiceOut *hw, void *buf, size_t size),
@@ -687,9 +687,12 @@ static void coreaudio_audio_fini (void *opaque)
 static struct audio_pcm_ops coreaudio_pcm_ops = {
     .init_out = coreaudio_init_out,
     .fini_out = coreaudio_fini_out,
+  /* wrapper for audio_generic_write */
     .write    = coreaudio_write,
+  /* wrapper for audio_generic_get_buffer_out */
     .get_buffer_out = coreaudio_get_buffer_out,
-    .put_buffer_out = coreaudio_put_buffer_out_nowrite,
+  /* wrapper for audio_generic_put_buffer_out */
+    .put_buffer_out = coreaudio_put_buffer_out,
     .enable_out = coreaudio_enable_out
 };
 
diff --git a/audio/noaudio.c b/audio/noaudio.c
index ff99b253ff0b..05798ea21032 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -118,6 +118,7 @@ static struct audio_pcm_ops no_pcm_ops = {
     .init_out = no_init_out,
     .fini_out = no_fini_out,
     .write    = no_write,
+    .run_buffer_out = audio_generic_run_buffer_out,
     .enable_out = no_enable_out,
 
     .init_in  = no_init_in,
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 94564916fbf0..576b5b5b2021 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -382,6 +382,15 @@ static size_t oss_get_available_bytes(OSSVoiceOut *oss)
     return audio_ring_dist(cntinfo.ptr, oss->hw.pos_emul, oss->hw.size_emul);
 }
 
+static void oss_run_buffer_out(HWVoiceOut *hw)
+{
+    OSSVoiceOut *oss = (OSSVoiceOut *)hw;
+
+    if (!oss->mmapped) {
+        audio_generic_run_buffer_out(hw);
+    }
+}
+
 static void *oss_get_buffer_out(HWVoiceOut *hw, size_t *size)
 {
     OSSVoiceOut *oss = (OSSVoiceOut *) hw;
@@ -748,6 +757,7 @@ static struct audio_pcm_ops oss_pcm_ops = {
     .init_out = oss_init_out,
     .fini_out = oss_fini_out,
     .write    = oss_write,
+    .run_buffer_out = oss_run_buffer_out,
     .get_buffer_out = oss_get_buffer_out,
     .put_buffer_out = oss_put_buffer_out,
     .enable_out = oss_enable_out,
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index 5c6bcfcb3e9d..c00e7d784523 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -227,7 +227,7 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
 
 SDL_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size),
                  (hw, size), *size = 0, sdl_unlock)
-SDL_WRAPPER_FUNC(put_buffer_out_nowrite, size_t,
+SDL_WRAPPER_FUNC(put_buffer_out, size_t,
                  (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size),
                  /*nothing*/, sdl_unlock_and_post)
 SDL_WRAPPER_FUNC(write, size_t,
@@ -320,9 +320,12 @@ static void sdl_audio_fini (void *opaque)
 static struct audio_pcm_ops sdl_pcm_ops = {
     .init_out = sdl_init_out,
     .fini_out = sdl_fini_out,
+  /* wrapper for audio_generic_write */
     .write    = sdl_write,
+  /* wrapper for audio_generic_get_buffer_out */
     .get_buffer_out = sdl_get_buffer_out,
-    .put_buffer_out = sdl_put_buffer_out_nowrite,
+  /* wrapper for audio_generic_put_buffer_out */
+    .put_buffer_out = sdl_put_buffer_out,
     .enable_out = sdl_enable_out,
 };
 
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index e46d834bd3af..20e6853f8586 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -197,6 +197,7 @@ static struct audio_pcm_ops wav_pcm_ops = {
     .init_out = wav_init_out,
     .fini_out = wav_fini_out,
     .write    = wav_write_out,
+    .run_buffer_out = audio_generic_run_buffer_out,
     .enable_out = wav_enable_out,
 };
 
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 07/12] ossaudio: prevent SIGSEGV in oss_enable_out
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 06/12] audio: fix bug 1858488 Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 08/12] ossaudio: disable poll mode can't be reached Gerd Hoffmann
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

With audiodev parameter out.mixing-engine=off hw->mix_buf is
NULL. This patch reverts a small part of dc88e38fa7 "audio:
unify input and output mixeng buffer management".

To reproduce the problem start qemu with
-audiodev oss,id=audio0,try-mmap=on,out.mixing-engine=off

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-6-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/ossaudio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 576b5b5b2021..39a6fc09e5df 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -592,7 +592,7 @@ static void oss_enable_out(HWVoiceOut *hw, bool enable)
             return;
         }
 
-        audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->mix_buf->size);
+        audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->samples);
         trig = PCM_ENABLE_OUTPUT;
         if (ioctl(oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
             oss_logerr(errno,
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 08/12] ossaudio: disable poll mode can't be reached
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 07/12] ossaudio: prevent SIGSEGV in oss_enable_out Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 09/12] audio: audio_generic_get_buffer_in should honor *size Gerd Hoffmann
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

Currently there is no way to disable poll mode in
oss_enable_out and oss_enable_in when it was enabled before.
The enable code path always resets the poll mode state variable.

Fixes: b027a538c6 "oss: Remove unused error handling of qemu_set_fd_handler"
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-8-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/ossaudio.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 39a6fc09e5df..f88d076ec236 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -579,14 +579,12 @@ static void oss_enable_out(HWVoiceOut *hw, bool enable)
     AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.out;
 
     if (enable) {
-        bool poll_mode = opdo->try_poll;
+        hw->poll_mode = opdo->try_poll;
 
         ldebug("enabling voice\n");
-        if (poll_mode) {
+        if (hw->poll_mode) {
             oss_poll_out(hw);
-            poll_mode = 0;
         }
-        hw->poll_mode = poll_mode;
 
         if (!oss->mmapped) {
             return;
@@ -708,17 +706,15 @@ static void oss_enable_in(HWVoiceIn *hw, bool enable)
     AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.out;
 
     if (enable) {
-        bool poll_mode = opdo->try_poll;
+        hw->poll_mode = opdo->try_poll;
 
-        if (poll_mode) {
+        if (hw->poll_mode) {
             oss_poll_in(hw);
-            poll_mode = 0;
         }
-        hw->poll_mode = poll_mode;
     } else {
         if (hw->poll_mode) {
-            hw->poll_mode = 0;
             qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);
+            hw->poll_mode = 0;
         }
     }
 }
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 09/12] audio: audio_generic_get_buffer_in should honor *size
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 08/12] ossaudio: disable poll mode can't be reached Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 10/12] audio/dsound: fix invalid parameters error Gerd Hoffmann
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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

The function generic_get_buffer_in currently ignores the *size
parameter and may return a buffer larger than *size.

As a result the variable samples in function
audio_pcm_hw_run_in may underflow. The while loop then most
likely will never termiate.

Buglink: http://bugs.debian.org/948658
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20200123074943.6699-9-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/audio/audio.c b/audio/audio.c
index b686429203d6..f9859408f340 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1407,7 +1407,8 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size)
     }
     assert(start >= 0 && start < hw->size_emul);
 
-    *size = MIN(hw->pending_emul, hw->size_emul - start);
+    *size = MIN(*size, hw->pending_emul);
+    *size = MIN(*size, hw->size_emul - start);
     return hw->buf_emul + start;
 }
 
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 10/12] audio/dsound: fix invalid parameters error
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 09/12] audio: audio_generic_get_buffer_in should honor *size Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 11/12] coreaudio: fix coreaudio playback Gerd Hoffmann
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: K=?UTF-8?B?xZE=?=v=?UTF-8?B?w6E=?=g=?UTF-8?B?w7M=?=,
	Zoltán, Markus Armbruster, Gerd Hoffmann

From: Kővágó, Zoltán <dirty.ice.hu@gmail.com>

Windows (unlike wine) bails out when IDirectSoundBuffer8::Lock is called
with zero length.  Also, hw->pos_emul handling was incorrect when
calling this function for the first time.

Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Reported-by: KJ Liew <liewkj@yahoo.com>
Tested-by: Howard Spoelstra <hsp.cat7@gmail.com>
Message-id: fe9744216d9d421a2dbb09bcf5fa0dbd18f77ac5.1580684275.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/dsound_template.h |  1 +
 audio/audio.c           |  6 ++----
 audio/dsoundaudio.c     | 27 +++++++++++++++++++++++----
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 7a15f91ce563..9c5ce625ab91 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -244,6 +244,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
         goto fail0;
     }
 
+    ds->first_time = true;
     obt_as.endianness = 0;
     audio_pcm_init_info (&hw->info, &obt_as);
 
diff --git a/audio/audio.c b/audio/audio.c
index f9859408f340..3bfd808bc6f1 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1076,10 +1076,8 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
     while (live) {
         size_t size, decr, proc;
         void *buf = hw->pcm_ops->get_buffer_out(hw, &size);
-        if (!buf) {
-            /* retrying will likely won't help, drop everything. */
-            hw->mix_buf->pos = (hw->mix_buf->pos + live) % hw->mix_buf->size;
-            return clipped + live;
+        if (!buf || size == 0) {
+            break;
         }
 
         decr = MIN(size / hw->info.bytes_per_frame, live);
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index c265c0094b9f..bd57082a8dce 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -53,12 +53,14 @@ typedef struct {
 typedef struct {
     HWVoiceOut hw;
     LPDIRECTSOUNDBUFFER dsound_buffer;
+    bool first_time;
     dsound *s;
 } DSoundVoiceOut;
 
 typedef struct {
     HWVoiceIn hw;
     LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+    bool first_time;
     dsound *s;
 } DSoundVoiceIn;
 
@@ -414,21 +416,32 @@ static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size)
     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
     LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
     HRESULT hr;
-    DWORD ppos, act_size;
+    DWORD ppos, wpos, act_size;
     size_t req_size;
     int err;
     void *ret;
 
-    hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, NULL);
+    hr = IDirectSoundBuffer_GetCurrentPosition(
+        dsb, &ppos, ds->first_time ? &wpos : NULL);
     if (FAILED(hr)) {
         dsound_logerr(hr, "Could not get playback buffer position\n");
         *size = 0;
         return NULL;
     }
 
+    if (ds->first_time) {
+        hw->pos_emul = wpos;
+        ds->first_time = false;
+    }
+
     req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul);
     req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
 
+    if (req_size == 0) {
+        *size = 0;
+        return NULL;
+    }
+
     err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
                           &act_size, NULL, false, ds->s);
     if (err) {
@@ -508,18 +521,24 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
     LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
     HRESULT hr;
-    DWORD cpos, act_size;
+    DWORD cpos, rpos, act_size;
     size_t req_size;
     int err;
     void *ret;
 
-    hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, &cpos, NULL);
+    hr = IDirectSoundCaptureBuffer_GetCurrentPosition(
+        dscb, &cpos, ds->first_time ? &rpos : NULL);
     if (FAILED(hr)) {
         dsound_logerr(hr, "Could not get capture buffer position\n");
         *size = 0;
         return NULL;
     }
 
+    if (ds->first_time) {
+        hw->pos_emul = rpos;
+        ds->first_time = false;
+    }
+
     req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);
     req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
 
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 11/12] coreaudio: fix coreaudio playback
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 10/12] audio/dsound: fix invalid parameters error Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07  7:45 ` [PULL 12/12] audio: proper support for float samples in mixeng Gerd Hoffmann
  2020-02-07 15:01 ` [PULL 00/12] Audio 20200207 patches Peter Maydell
  12 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Markus Armbruster, Gerd Hoffmann

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



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PULL 12/12] audio: proper support for float samples in mixeng
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 11/12] coreaudio: fix coreaudio playback Gerd Hoffmann
@ 2020-02-07  7:45 ` Gerd Hoffmann
  2020-02-07 13:53   ` Eric Blake
  2020-02-07 15:01 ` [PULL 00/12] Audio 20200207 patches Peter Maydell
  12 siblings, 1 reply; 15+ messages in thread
From: Gerd Hoffmann @ 2020-02-07  7:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: K=?UTF-8?B?xZE=?=v=?UTF-8?B?w6E=?=g=?UTF-8?B?w7M=?=,
	Zoltán, Markus Armbruster, Gerd Hoffmann

From: Kővágó, Zoltán <dirty.ice.hu@gmail.com>

This adds proper support for float samples in mixeng by adding a new
audio format for it.

Limitations: only native endianness is supported.  None of the virtual
sound cards support float samples (it looks like most of them only
support 8 and 16 bit, only hda supports 32 bit), it is only used for the
audio backends (i.e. host side).

Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Message-id: 8a8b0b5698401b78d3c4c8ec90aef83b95babb06.1580672076.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio_int.h      |  3 +-
 audio/audio_template.h | 41 ++++++++++++--------
 audio/mixeng.h         |  8 ++--
 audio/alsaaudio.c      | 17 ++++++++
 audio/audio.c          | 56 ++++++++++++++++++---------
 audio/coreaudio.c      |  7 +---
 audio/mixeng.c         | 88 ++++++++++++++++++++++++++----------------
 audio/paaudio.c        |  9 +++++
 audio/sdlaudio.c       | 28 ++++++++++++++
 qapi/audio.json        |  2 +-
 10 files changed, 180 insertions(+), 79 deletions(-)

diff --git a/audio/audio_int.h b/audio/audio_int.h
index 3c8e48b55b1c..4775857bf245 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -40,7 +40,8 @@ struct audio_callback {
 
 struct audio_pcm_info {
     int bits;
-    int sign;
+    bool is_signed;
+    bool is_float;
     int freq;
     int nchannels;
     int bytes_per_frame;
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 0336d2670cf6..7013d3041f91 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -153,15 +153,23 @@ static int glue (audio_pcm_sw_init_, TYPE) (
     sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
 #endif
 
+    if (sw->info.is_float) {
 #ifdef DAC
-    sw->conv = mixeng_conv
+        sw->conv = mixeng_conv_float[sw->info.nchannels == 2];
 #else
-    sw->clip = mixeng_clip
+        sw->clip = mixeng_clip_float[sw->info.nchannels == 2];
 #endif
-        [sw->info.nchannels == 2]
-        [sw->info.sign]
-        [sw->info.swap_endianness]
-        [audio_bits_to_index (sw->info.bits)];
+    } else {
+#ifdef DAC
+        sw->conv = mixeng_conv
+#else
+        sw->clip = mixeng_clip
+#endif
+            [sw->info.nchannels == 2]
+            [sw->info.is_signed]
+            [sw->info.swap_endianness]
+            [audio_bits_to_index(sw->info.bits)];
+    }
 
     sw->name = g_strdup (name);
     err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
@@ -276,22 +284,23 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
         goto err1;
     }
 
-    if (s->dev->driver == AUDIODEV_DRIVER_COREAUDIO) {
+    if (hw->info.is_float) {
 #ifdef DAC
-        hw->clip = clip_natural_float_from_stereo;
+        hw->clip = mixeng_clip_float[hw->info.nchannels == 2];
 #else
-        hw->conv = conv_natural_float_to_stereo;
+        hw->conv = mixeng_conv_float[hw->info.nchannels == 2];
 #endif
-    } else
+    } else {
 #ifdef DAC
-    hw->clip = mixeng_clip
+        hw->clip = mixeng_clip
 #else
-    hw->conv = mixeng_conv
+        hw->conv = mixeng_conv
 #endif
-        [hw->info.nchannels == 2]
-        [hw->info.sign]
-        [hw->info.swap_endianness]
-        [audio_bits_to_index (hw->info.bits)];
+            [hw->info.nchannels == 2]
+            [hw->info.is_signed]
+            [hw->info.swap_endianness]
+            [audio_bits_to_index(hw->info.bits)];
+    }
 
     glue(audio_pcm_hw_alloc_resources_, TYPE)(hw);
 
diff --git a/audio/mixeng.h b/audio/mixeng.h
index 7ef61763e8f9..2dcd6df24561 100644
--- a/audio/mixeng.h
+++ b/audio/mixeng.h
@@ -38,13 +38,13 @@ typedef struct st_sample st_sample;
 typedef void (t_sample) (struct st_sample *dst, const void *src, int samples);
 typedef void (f_sample) (void *dst, const struct st_sample *src, int samples);
 
+/* indices: [stereo][signed][swap endiannes][8, 16 or 32-bits] */
 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);
+/* indices: [stereo] */
+extern t_sample *mixeng_conv_float[2];
+extern f_sample *mixeng_clip_float[2];
 
 void *st_rate_start (int inrate, int outrate);
 void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf,
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 4ef26818be57..a23a5a0b60a1 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -307,6 +307,13 @@ static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
             return SND_PCM_FORMAT_U32_LE;
         }
 
+    case AUDIO_FORMAT_F32:
+        if (endianness) {
+            return SND_PCM_FORMAT_FLOAT_BE;
+        } else {
+            return SND_PCM_FORMAT_FLOAT_LE;
+        }
+
     default:
         dolog ("Internal logic error: Bad audio format %d\n", fmt);
 #ifdef DEBUG_AUDIO
@@ -370,6 +377,16 @@ static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt,
         *fmt = AUDIO_FORMAT_U32;
         break;
 
+    case SND_PCM_FORMAT_FLOAT_LE:
+        *endianness = 0;
+        *fmt = AUDIO_FORMAT_F32;
+        break;
+
+    case SND_PCM_FORMAT_FLOAT_BE:
+        *endianness = 1;
+        *fmt = AUDIO_FORMAT_F32;
+        break;
+
     default:
         dolog ("Unrecognized audio format %d\n", alsafmt);
         return -1;
diff --git a/audio/audio.c b/audio/audio.c
index 3bfd808bc6f1..9ac9a20c41ba 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -218,6 +218,9 @@ static void audio_print_settings (struct audsettings *as)
     case AUDIO_FORMAT_U32:
         AUD_log (NULL, "U32");
         break;
+    case AUDIO_FORMAT_F32:
+        AUD_log (NULL, "F32");
+        break;
     default:
         AUD_log (NULL, "invalid(%d)", as->fmt);
         break;
@@ -252,6 +255,7 @@ static int audio_validate_settings (struct audsettings *as)
     case AUDIO_FORMAT_U16:
     case AUDIO_FORMAT_S32:
     case AUDIO_FORMAT_U32:
+    case AUDIO_FORMAT_F32:
         break;
     default:
         invalid = 1;
@@ -264,24 +268,28 @@ static int audio_validate_settings (struct audsettings *as)
 
 static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *as)
 {
-    int bits = 8, sign = 0;
+    int bits = 8;
+    bool is_signed = false, is_float = false;
 
     switch (as->fmt) {
     case AUDIO_FORMAT_S8:
-        sign = 1;
+        is_signed = true;
         /* fall through */
     case AUDIO_FORMAT_U8:
         break;
 
     case AUDIO_FORMAT_S16:
-        sign = 1;
+        is_signed = true;
         /* fall through */
     case AUDIO_FORMAT_U16:
         bits = 16;
         break;
 
+    case AUDIO_FORMAT_F32:
+        is_float = true;
+        /* fall through */
     case AUDIO_FORMAT_S32:
-        sign = 1;
+        is_signed = true;
         /* fall through */
     case AUDIO_FORMAT_U32:
         bits = 32;
@@ -292,33 +300,38 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *a
     }
     return info->freq == as->freq
         && info->nchannels == as->nchannels
-        && info->sign == sign
+        && info->is_signed == is_signed
+        && info->is_float == is_float
         && info->bits == bits
         && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
 }
 
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as)
 {
-    int bits = 8, sign = 0, mul;
+    int bits = 8, mul;
+    bool is_signed = false, is_float = false;
 
     switch (as->fmt) {
     case AUDIO_FORMAT_S8:
-        sign = 1;
+        is_signed = true;
         /* fall through */
     case AUDIO_FORMAT_U8:
         mul = 1;
         break;
 
     case AUDIO_FORMAT_S16:
-        sign = 1;
+        is_signed = true;
         /* fall through */
     case AUDIO_FORMAT_U16:
         bits = 16;
         mul = 2;
         break;
 
+    case AUDIO_FORMAT_F32:
+        is_float = true;
+        /* fall through */
     case AUDIO_FORMAT_S32:
-        sign = 1;
+        is_signed = true;
         /* fall through */
     case AUDIO_FORMAT_U32:
         bits = 32;
@@ -331,7 +344,8 @@ void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as)
 
     info->freq = as->freq;
     info->bits = bits;
-    info->sign = sign;
+    info->is_signed = is_signed;
+    info->is_float = is_float;
     info->nchannels = as->nchannels;
     info->bytes_per_frame = as->nchannels * mul;
     info->bytes_per_second = info->freq * info->bytes_per_frame;
@@ -344,7 +358,7 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
         return;
     }
 
-    if (info->sign) {
+    if (info->is_signed || info->is_float) {
         memset(buf, 0x00, len * info->bytes_per_frame);
     }
     else {
@@ -770,8 +784,9 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
 #ifdef DEBUG_AUDIO
 static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
 {
-    dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
-           cap, info->bits, info->sign, info->freq, info->nchannels);
+    dolog("%s: bits %d, sign %d, float %d, freq %d, nchan %d\n",
+          cap, info->bits, info->is_signed, info->is_float, info->freq,
+          info->nchannels);
 }
 #endif
 
@@ -1832,11 +1847,15 @@ CaptureVoiceOut *AUD_add_capture(
 
         cap->buf = g_malloc0_n(hw->mix_buf->size, hw->info.bytes_per_frame);
 
-        hw->clip = mixeng_clip
-            [hw->info.nchannels == 2]
-            [hw->info.sign]
-            [hw->info.swap_endianness]
-            [audio_bits_to_index (hw->info.bits)];
+        if (hw->info.is_float) {
+            hw->clip = mixeng_clip_float[hw->info.nchannels == 2];
+        } else {
+            hw->clip = mixeng_clip
+                [hw->info.nchannels == 2]
+                [hw->info.is_signed]
+                [hw->info.swap_endianness]
+                [audio_bits_to_index(hw->info.bits)];
+        }
 
         QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
         QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
@@ -2075,6 +2094,7 @@ int audioformat_bytes_per_sample(AudioFormat fmt)
 
     case AUDIO_FORMAT_U32:
     case AUDIO_FORMAT_S32:
+    case AUDIO_FORMAT_F32:
         return 4;
 
     case AUDIO_FORMAT__MAX:
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index e3620b274bd6..4b4365660fcf 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -491,14 +491,9 @@ 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;
+    as->fmt = AUDIO_FORMAT_F32;
     audio_pcm_init_info (&hw->info, as);
 
     status = coreaudio_get_voice(&core->outputDeviceID);
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 16b646d48cdf..c14b0d874ce5 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -267,55 +267,77 @@ f_sample *mixeng_clip[2][2][2][3] = {
     }
 };
 
-void conv_natural_float_to_stereo(struct st_sample *dst, const void *src,
-                                  int samples)
+#ifdef FLOAT_MIXENG
+#define FLOAT_CONV_TO(x) (x)
+#define FLOAT_CONV_FROM(x) (x)
+#else
+static const float float_scale = UINT_MAX;
+#define FLOAT_CONV_TO(x) ((x) * float_scale)
+
+#ifdef RECIPROCAL
+static const float float_scale_reciprocal = 1.f / UINT_MAX;
+#define FLOAT_CONV_FROM(x) ((x) * float_scale_reciprocal)
+#else
+#define FLOAT_CONV_FROM(x) ((x) / float_scale)
+#endif
+#endif
+
+static void conv_natural_float_to_mono(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->r = dst->l = FLOAT_CONV_TO(*in++);
+        dst++;
+    }
+}
+
+static void conv_natural_float_to_stereo(struct st_sample *dst, const void *src,
+                                         int samples)
+{
+    float *in = (float *)src;
+
+    while (samples--) {
+        dst->l = FLOAT_CONV_TO(*in++);
+        dst->r = FLOAT_CONV_TO(*in++);
         dst++;
     }
 }
 
-void clip_natural_float_from_stereo(void *dst, const struct st_sample *src,
-                                    int samples)
+t_sample *mixeng_conv_float[2] = {
+    conv_natural_float_to_mono,
+    conv_natural_float_to_stereo,
+};
+
+static void clip_natural_float_from_mono(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
+        *out++ = FLOAT_CONV_FROM(src->l) + FLOAT_CONV_FROM(src->r);
+        src++;
+    }
+}
+
+static void clip_natural_float_from_stereo(
+    void *dst, const struct st_sample *src, int samples)
+{
+    float *out = (float *)dst;
+
+    while (samples--) {
+        *out++ = FLOAT_CONV_FROM(src->l);
+        *out++ = FLOAT_CONV_FROM(src->r);
         src++;
     }
 }
 
+f_sample *mixeng_clip_float[2] = {
+    clip_natural_float_from_mono,
+    clip_natural_float_from_stereo,
+};
+
 void audio_sample_to_uint64(void *samples, int pos,
                             uint64_t *left, uint64_t *right)
 {
diff --git a/audio/paaudio.c b/audio/paaudio.c
index 8f37c6185161..b05208469831 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -277,6 +277,9 @@ static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness)
     case AUDIO_FORMAT_U32:
         format = endianness ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
         break;
+    case AUDIO_FORMAT_F32:
+        format = endianness ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE;
+        break;
     default:
         dolog ("Internal logic error: Bad audio format %d\n", afmt);
         format = PA_SAMPLE_U8;
@@ -302,6 +305,12 @@ static AudioFormat pa_to_audfmt (pa_sample_format_t fmt, int *endianness)
     case PA_SAMPLE_S32LE:
         *endianness = 0;
         return AUDIO_FORMAT_S32;
+    case PA_SAMPLE_FLOAT32BE:
+        *endianness = 1;
+        return AUDIO_FORMAT_F32;
+    case PA_SAMPLE_FLOAT32LE:
+        *endianness = 0;
+        return AUDIO_FORMAT_F32;
     default:
         dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt);
         return AUDIO_FORMAT_U8;
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index c00e7d784523..21b7a0484bec 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -77,6 +77,14 @@ static int aud_to_sdlfmt (AudioFormat fmt)
     case AUDIO_FORMAT_U16:
         return AUDIO_U16LSB;
 
+    case AUDIO_FORMAT_S32:
+        return AUDIO_S32LSB;
+
+    /* no unsigned 32-bit support in SDL */
+
+    case AUDIO_FORMAT_F32:
+        return AUDIO_F32LSB;
+
     default:
         dolog ("Internal logic error: Bad audio format %d\n", fmt);
 #ifdef DEBUG_AUDIO
@@ -119,6 +127,26 @@ static int sdl_to_audfmt(int sdlfmt, AudioFormat *fmt, int *endianness)
         *fmt = AUDIO_FORMAT_U16;
         break;
 
+    case AUDIO_S32LSB:
+        *endianness = 0;
+        *fmt = AUDIO_FORMAT_S32;
+        break;
+
+    case AUDIO_S32MSB:
+        *endianness = 1;
+        *fmt = AUDIO_FORMAT_S32;
+        break;
+
+    case AUDIO_F32LSB:
+        *endianness = 0;
+        *fmt = AUDIO_FORMAT_F32;
+        break;
+
+    case AUDIO_F32MSB:
+        *endianness = 1;
+        *fmt = AUDIO_FORMAT_F32;
+        break;
+
     default:
         dolog ("Unrecognized SDL audio format %d\n", sdlfmt);
         return -1;
diff --git a/qapi/audio.json b/qapi/audio.json
index 83312b23391e..d8c507ccedae 100644
--- a/qapi/audio.json
+++ b/qapi/audio.json
@@ -276,7 +276,7 @@
 # Since: 4.0
 ##
 { 'enum': 'AudioFormat',
-  'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32' ] }
+  'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32', 'f32' ] }
 
 ##
 # @AudiodevDriver:
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PULL 12/12] audio: proper support for float samples in mixeng
  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
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Blake @ 2020-02-07 13:53 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel
  Cc: Markus Armbruster, Kővágó, Zoltán

On 2/7/20 1:45 AM, Gerd Hoffmann wrote:
> From: Kővágó, Zoltán <dirty.ice.hu@gmail.com>
> 
> This adds proper support for float samples in mixeng by adding a new
> audio format for it.
> 
> Limitations: only native endianness is supported.  None of the virtual
> sound cards support float samples (it looks like most of them only
> support 8 and 16 bit, only hda supports 32 bit), it is only used for the
> audio backends (i.e. host side).
> 
> Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
> Acked-by: Markus Armbruster <armbru@redhat.com>
> Message-id: 8a8b0b5698401b78d3c4c8ec90aef83b95babb06.1580672076.git.DirtY.iCE.hu@gmail.com
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---

> +++ b/qapi/audio.json
> @@ -276,7 +276,7 @@
>   # Since: 4.0
>   ##
>   { 'enum': 'AudioFormat',
> -  'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32' ] }
> +  'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32', 'f32' ] }

Review suggested that this should add documentation including a since 
tag; that would now need to be a separate patch (unless this pull 
request is resun for other reasons)

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PULL 00/12] Audio 20200207 patches
  2020-02-07  7:45 [PULL 00/12] Audio 20200207 patches Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2020-02-07  7:45 ` [PULL 12/12] audio: proper support for float samples in mixeng Gerd Hoffmann
@ 2020-02-07 15:01 ` Peter Maydell
  12 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2020-02-07 15:01 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: QEMU Developers, Markus Armbruster

On Fri, 7 Feb 2020 at 07:47, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> The following changes since commit 928173659d6e5dc368284f73f90ea1d129e1f57d:
>
>   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200130' into staging (2020-01-30 16:19:04 +0000)
>
> are available in the Git repository at:
>
>   git://git.kraxel.org/qemu tags/audio-20200207-pull-request
>
> for you to fetch changes up to ed2a4a794184df3dbd5ee4cc06e86fe220663faf:
>
>   audio: proper support for float samples in mixeng (2020-02-06 14:35:57 +0100)
>
> ----------------------------------------------------------------
> audio: bugfixes, mostly audio backend rewrite fallout
>
> ---------------------------------------------------------------


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2020-02-07 15:14 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PULL 11/12] coreaudio: fix coreaudio playback Gerd Hoffmann
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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.