All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] more audio fixes and improvements
@ 2020-01-23  7:41 Volker Rümelin
  2020-01-23  7:49 ` [PATCH 1/9] audio: fix audio_generic_write Volker Rümelin
                   ` (9 more replies)
  0 siblings, 10 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:41 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

The first two patches "audio: fix audio_generic_write" and
"audio: fix audio_generic_read" are only compile tested. The
code is only reachable from the DirectSound backend with the
mixing-engine off. I don't know if it is reachable at all.
I can't test because I don't have a Windows computer.

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: prevent SIGPFE in oss_write
  ossaudio: disable poll mode can't be reached
  audio: audio_generic_get_buffer_in should honor *size

 audio/alsaaudio.c |  1 +
 audio/audio.c     | 77 ++++++++++++++++++++++++++-----------------------------
 audio/audio_int.h |  4 +--
 audio/coreaudio.c |  7 +++--
 audio/noaudio.c   |  1 +
 audio/ossaudio.c  | 28 ++++++++++++--------
 audio/paaudio.c   |  6 ++---
 audio/sdlaudio.c  |  7 +++--
 audio/wavaudio.c  |  1 +
 9 files changed, 71 insertions(+), 61 deletions(-)

-- 
2.16.4



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

* [PATCH 1/9] audio: fix audio_generic_write
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 2/9] audio: fix audio_generic_read Volker Rümelin
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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>
---
 audio/audio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/audio/audio.c b/audio/audio.c
index abea027fdf..db44482342 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1475,7 +1475,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.16.4



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

* [PATCH 2/9] audio: fix audio_generic_read
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
  2020-01-23  7:49 ` [PATCH 1/9] audio: fix audio_generic_write Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 3/9] paaudio: remove unused variables Volker Rümelin
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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>
---
 audio/audio.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index db44482342..bf0f01e17f 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1480,12 +1480,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.16.4



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

* [PATCH 3/9] paaudio: remove unused variables
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
  2020-01-23  7:49 ` [PATCH 1/9] audio: fix audio_generic_write Volker Rümelin
  2020-01-23  7:49 ` [PATCH 2/9] audio: fix audio_generic_read Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 4/9] audio: prevent SIGSEGV in AUD_get_buffer_size_out Volker Rümelin
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
---
 audio/paaudio.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index dbfe48c03a..8f37c61851 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.16.4



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

* [PATCH 4/9] audio: prevent SIGSEGV in AUD_get_buffer_size_out
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
                   ` (2 preceding siblings ...)
  2020-01-23  7:49 ` [PATCH 3/9] paaudio: remove unused variables Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 5/9] audio: fix bug 1858488 Volker Rümelin
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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>
---
 audio/audio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index bf0f01e17f..922e95011c 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -878,9 +878,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.16.4



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

* [PATCH 5/9] audio: fix bug 1858488
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
                   ` (3 preceding siblings ...)
  2020-01-23  7:49 ` [PATCH 4/9] audio: prevent SIGSEGV in AUD_get_buffer_size_out Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 6/9] ossaudio: prevent SIGSEGV in oss_enable_out Volker Rümelin
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
---
 audio/alsaaudio.c |  1 +
 audio/audio.c     | 58 ++++++++++++++++++++++++++-----------------------------
 audio/audio_int.h |  4 ++--
 audio/coreaudio.c |  7 +++++--
 audio/noaudio.c   |  1 +
 audio/ossaudio.c  | 10 ++++++++++
 audio/sdlaudio.c  |  7 +++++--
 audio/wavaudio.c  |  1 +
 8 files changed, 52 insertions(+), 37 deletions(-)

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index f37ce1ce85..4ef26818be 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 922e95011c..81822bfec9 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1096,6 +1096,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;
 }
 
@@ -1412,6 +1416,28 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
     hw->pending_emul -= size;
 }
 
+void audio_generic_run_buffer_out(HWVoiceOut *hw)
+{
+    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;
+        }
+        assert(start >= 0 && start < hw->size_emul);
+
+        write_len = MIN(hw->pending_emul, hw->size_emul - start);
+
+        written = hw->pcm_ops->write(hw, hw->buf_emul + start, write_len);
+        hw->pending_emul -= written;
+
+        if (written < write_len) {
+            break;
+        }
+    }
+}
+
 void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
 {
     if (unlikely(!hw->buf_emul)) {
@@ -1427,8 +1453,7 @@ void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
     return hw->buf_emul + hw->pos_emul;
 }
 
-size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
-                                            size_t size)
+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);
@@ -1439,35 +1464,6 @@ size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf,
     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;
-        }
-        assert(start >= 0 && start < hw->size_emul);
-
-        write_len = MIN(hw->pending_emul, hw->size_emul - start);
-
-        written = hw->pcm_ops->write(hw, hw->buf_emul + start, write_len);
-        hw->pending_emul -= written;
-
-        if (written < write_len) {
-            break;
-        }
-    }
-
-    /*
-     * fake we have written everything. non-written data remain in pending_emul,
-     * so we do not have to clip them multiple times
-     */
-    return size;
-}
-
 size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
 {
     size_t dst_size, copy_size;
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 5ba2078346..3c8e48b55b 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/coreaudio.c b/audio/coreaudio.c
index 66f0f459cf..c7a7196c2d 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 ff99b253ff..05798ea210 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 c43faeeea4..4965084a5a 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 5c6bcfcb3e..c00e7d7845 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 e46d834bd3..20e6853f85 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.16.4



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

* [PATCH 6/9] ossaudio: prevent SIGSEGV in oss_enable_out
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
                   ` (4 preceding siblings ...)
  2020-01-23  7:49 ` [PATCH 5/9] audio: fix bug 1858488 Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 7/9] ossaudio: prevent SIGPFE in oss_write Volker Rümelin
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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>
---
 audio/ossaudio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 4965084a5a..6a3b78b381 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.16.4



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

* [PATCH 7/9] ossaudio: prevent SIGPFE in oss_write
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
                   ` (5 preceding siblings ...)
  2020-01-23  7:49 ` [PATCH 6/9] ossaudio: prevent SIGSEGV in oss_enable_out Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 8/9] ossaudio: disable poll mode can't be reached Volker Rümelin
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

The new buffer write position is modulo the buffer size.

To reproduce 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>
---
 audio/ossaudio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 6a3b78b381..39a6fc09e5 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -429,7 +429,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.16.4



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

* [PATCH 8/9] ossaudio: disable poll mode can't be reached
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
                   ` (6 preceding siblings ...)
  2020-01-23  7:49 ` [PATCH 7/9] ossaudio: prevent SIGPFE in oss_write Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-23  7:49 ` [PATCH 9/9] audio: audio_generic_get_buffer_in should honor *size Volker Rümelin
  2020-01-27  6:45 ` [PATCH 0/9] more audio fixes and improvements Mark Cave-Ayland
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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>
---
 audio/ossaudio.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 39a6fc09e5..f88d076ec2 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.16.4



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

* [PATCH 9/9] audio: audio_generic_get_buffer_in should honor *size
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
                   ` (7 preceding siblings ...)
  2020-01-23  7:49 ` [PATCH 8/9] ossaudio: disable poll mode can't be reached Volker Rümelin
@ 2020-01-23  7:49 ` Volker Rümelin
  2020-01-27  6:45 ` [PATCH 0/9] more audio fixes and improvements Mark Cave-Ayland
  9 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-23  7:49 UTC (permalink / raw
  To: Gerd Hoffmann; +Cc: QEMU, Zoltán Kővágó

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.

This bug was reported at http://bugs.debian.org/948658.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
---
 audio/audio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/audio/audio.c b/audio/audio.c
index 81822bfec9..f5fb6cbf53 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1406,7 +1406,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.16.4



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

* Re: [PATCH 0/9] more audio fixes and improvements
  2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
                   ` (8 preceding siblings ...)
  2020-01-23  7:49 ` [PATCH 9/9] audio: audio_generic_get_buffer_in should honor *size Volker Rümelin
@ 2020-01-27  6:45 ` Mark Cave-Ayland
  2020-01-27 20:40   ` Volker Rümelin
  9 siblings, 1 reply; 12+ messages in thread
From: Mark Cave-Ayland @ 2020-01-27  6:45 UTC (permalink / raw
  To: Volker Rümelin, Gerd Hoffmann
  Cc: Howard Spoelstra, QEMU, Zoltán Kővágó

On 23/01/2020 07:41, Volker Rümelin wrote:

> The first two patches "audio: fix audio_generic_write" and
> "audio: fix audio_generic_read" are only compile tested. The
> code is only reachable from the DirectSound backend with the
> mixing-engine off. I don't know if it is reachable at all.
> I can't test because I don't have a Windows computer.
> 
> 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: prevent SIGPFE in oss_write
>   ossaudio: disable poll mode can't be reached
>   audio: audio_generic_get_buffer_in should honor *size
> 
>  audio/alsaaudio.c |  1 +
>  audio/audio.c     | 77 ++++++++++++++++++++++++++-----------------------------
>  audio/audio_int.h |  4 +--
>  audio/coreaudio.c |  7 +++--
>  audio/noaudio.c   |  1 +
>  audio/ossaudio.c  | 28 ++++++++++++--------
>  audio/paaudio.c   |  6 ++---
>  audio/sdlaudio.c  |  7 +++--
>  audio/wavaudio.c  |  1 +
>  9 files changed, 71 insertions(+), 61 deletions(-)

Thanks for your patches! I've had reports from some of the PPC emulation guys that
the switch to the new audio API broke the coreaudio backend on Macs (see
https://bugs.launchpad.net/qemu/+bug/1859916) and I've pointed them towards this
patchset, but sadly it still doesn't appear to fix the issue.

Have you seen any issues with the coreaudio backend during your testing?


ATB,

Mark.


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

* Re: [PATCH 0/9] more audio fixes and improvements
  2020-01-27  6:45 ` [PATCH 0/9] more audio fixes and improvements Mark Cave-Ayland
@ 2020-01-27 20:40   ` Volker Rümelin
  0 siblings, 0 replies; 12+ messages in thread
From: Volker Rümelin @ 2020-01-27 20:40 UTC (permalink / raw
  To: Mark Cave-Ayland, Gerd Hoffmann
  Cc: Howard Spoelstra, QEMU, Zoltán Kővágó

> On 23/01/2020 07:41, Volker Rümelin wrote:
>
>> The first two patches "audio: fix audio_generic_write" and
>> "audio: fix audio_generic_read" are only compile tested. The
>> code is only reachable from the DirectSound backend with the
>> mixing-engine off. I don't know if it is reachable at all.
>> I can't test because I don't have a Windows computer.
>>
>> 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: prevent SIGPFE in oss_write
>>   ossaudio: disable poll mode can't be reached
>>   audio: audio_generic_get_buffer_in should honor *size
>>
>>  audio/alsaaudio.c |  1 +
>>  audio/audio.c     | 77 ++++++++++++++++++++++++++-----------------------------
>>  audio/audio_int.h |  4 +--
>>  audio/coreaudio.c |  7 +++--
>>  audio/noaudio.c   |  1 +
>>  audio/ossaudio.c  | 28 ++++++++++++--------
>>  audio/paaudio.c   |  6 ++---
>>  audio/sdlaudio.c  |  7 +++--
>>  audio/wavaudio.c  |  1 +
>>  9 files changed, 71 insertions(+), 61 deletions(-)
> Thanks for your patches! I've had reports from some of the PPC emulation guys that
> the switch to the new audio API broke the coreaudio backend on Macs (see
> https://bugs.launchpad.net/qemu/+bug/1859916) and I've pointed them towards this
> patchset, but sadly it still doesn't appear to fix the issue.
>
> Have you seen any issues with the coreaudio backend during your testing?

Hi Mark,

I didn't test coreaudio. I don't have a Mac. One of my patches changes coreaudio.c 
because I renamed a function.

With best regards,
Volker

> ATB,
>
> Mark.



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

end of thread, other threads:[~2020-01-27 20:41 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-23  7:41 [PATCH 0/9] more audio fixes and improvements Volker Rümelin
2020-01-23  7:49 ` [PATCH 1/9] audio: fix audio_generic_write Volker Rümelin
2020-01-23  7:49 ` [PATCH 2/9] audio: fix audio_generic_read Volker Rümelin
2020-01-23  7:49 ` [PATCH 3/9] paaudio: remove unused variables Volker Rümelin
2020-01-23  7:49 ` [PATCH 4/9] audio: prevent SIGSEGV in AUD_get_buffer_size_out Volker Rümelin
2020-01-23  7:49 ` [PATCH 5/9] audio: fix bug 1858488 Volker Rümelin
2020-01-23  7:49 ` [PATCH 6/9] ossaudio: prevent SIGSEGV in oss_enable_out Volker Rümelin
2020-01-23  7:49 ` [PATCH 7/9] ossaudio: prevent SIGPFE in oss_write Volker Rümelin
2020-01-23  7:49 ` [PATCH 8/9] ossaudio: disable poll mode can't be reached Volker Rümelin
2020-01-23  7:49 ` [PATCH 9/9] audio: audio_generic_get_buffer_in should honor *size Volker Rümelin
2020-01-27  6:45 ` [PATCH 0/9] more audio fixes and improvements Mark Cave-Ayland
2020-01-27 20:40   ` Volker Rümelin

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.