[PATCH] audio/mixeng: fix sw/hw mixup in audio_pcm_sw_init_

marcandre.lureau@redhat.com posted 1 patch 2 weeks, 5 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260318084301.653383-1-marcandre.lureau@redhat.com
Maintainers: Gerd Hoffmann <kraxel@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>
audio/audio_template.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
[PATCH] audio/mixeng: fix sw/hw mixup in audio_pcm_sw_init_
Posted by marcandre.lureau@redhat.com 2 weeks, 5 days ago
From: Marc-André Lureau <marcandre.lureau@redhat.com>

Commit 42061a14358 ("audio/mixeng: replace redundant pcm_info fields
with AudioFormat") accidentally changed the conv/clip function selection
in audio_pcm_sw_init_ to use hw->info.af (the hardware voice format)
instead of sw->info.af (the software voice format). This causes audio
distortion when the software and hardware voices use different formats,
as the wrong conversion functions are applied to the audio data.

Fix by using sw->info.af, restoring the original behavior.

Fixes: 42061a14358c ("audio/mixeng: replace redundant pcm_info fields with AudioFormat")
Reported-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 audio/audio_template.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/audio/audio_template.h b/audio/audio_template.h
index 228369cf9a1..f0b2458996a 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -172,7 +172,7 @@ static int glue (audio_pcm_sw_init_, TYPE) (
     sw->empty = true;
 #endif
 
-    if (audio_format_is_float(hw->info.af)) {
+    if (audio_format_is_float(sw->info.af)) {
 #ifdef DAC
         sw->conv = mixeng_conv_float[sw->info.nchannels == 2]
             [sw->info.swap_endianness];
@@ -187,9 +187,9 @@ static int glue (audio_pcm_sw_init_, TYPE) (
         sw->clip = mixeng_clip
 #endif
             [sw->info.nchannels == 2]
-            [audio_format_is_signed(hw->info.af)]
+            [audio_format_is_signed(sw->info.af)]
             [sw->info.swap_endianness]
-            [audio_format_to_index(hw->info.af)];
+            [audio_format_to_index(sw->info.af)];
     }
 
     sw->name = g_strdup (name);
-- 
2.53.0


Re: [PATCH] audio/mixeng: fix sw/hw mixup in audio_pcm_sw_init_
Posted by Dmitry Osipenko 2 weeks, 5 days ago
On 3/18/26 11:43, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Commit 42061a14358 ("audio/mixeng: replace redundant pcm_info fields
> with AudioFormat") accidentally changed the conv/clip function selection
> in audio_pcm_sw_init_ to use hw->info.af (the hardware voice format)
> instead of sw->info.af (the software voice format). This causes audio
> distortion when the software and hardware voices use different formats,
> as the wrong conversion functions are applied to the audio data.
> 
> Fix by using sw->info.af, restoring the original behavior.
> 
> Fixes: 42061a14358c ("audio/mixeng: replace redundant pcm_info fields with AudioFormat")
> Reported-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  audio/audio_template.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/audio/audio_template.h b/audio/audio_template.h
> index 228369cf9a1..f0b2458996a 100644
> --- a/audio/audio_template.h
> +++ b/audio/audio_template.h
> @@ -172,7 +172,7 @@ static int glue (audio_pcm_sw_init_, TYPE) (
>      sw->empty = true;
>  #endif
>  
> -    if (audio_format_is_float(hw->info.af)) {
> +    if (audio_format_is_float(sw->info.af)) {
>  #ifdef DAC
>          sw->conv = mixeng_conv_float[sw->info.nchannels == 2]
>              [sw->info.swap_endianness];
> @@ -187,9 +187,9 @@ static int glue (audio_pcm_sw_init_, TYPE) (
>          sw->clip = mixeng_clip
>  #endif
>              [sw->info.nchannels == 2]
> -            [audio_format_is_signed(hw->info.af)]
> +            [audio_format_is_signed(sw->info.af)]
>              [sw->info.swap_endianness]
> -            [audio_format_to_index(hw->info.af)];
> +            [audio_format_to_index(sw->info.af)];
>      }
>  
>      sw->name = g_strdup (name);

Thanks a lot for the fix!

-- 
Best regards,
Dmitry

Re: [PATCH] audio/mixeng: fix sw/hw mixup in audio_pcm_sw_init_
Posted by Christian Schoenebeck 2 weeks, 5 days ago
On Wednesday, 18 March 2026 09:43:01 CET marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Commit 42061a14358 ("audio/mixeng: replace redundant pcm_info fields
> with AudioFormat") accidentally changed the conv/clip function selection
> in audio_pcm_sw_init_ to use hw->info.af (the hardware voice format)
> instead of sw->info.af (the software voice format). This causes audio
> distortion when the software and hardware voices use different formats,
> as the wrong conversion functions are applied to the audio data.
> 
> Fix by using sw->info.af, restoring the original behavior.
> 
> Fixes: 42061a14358c ("audio/mixeng: replace redundant pcm_info fields with
> AudioFormat") Reported-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  audio/audio_template.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Haven't tested this, but those changes (hw instead of sw) were definitely
wrong and are likely to cause misbehaviours like the reported one. I also
haven't found further similar issues, so:

Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>

> 
> diff --git a/audio/audio_template.h b/audio/audio_template.h
> index 228369cf9a1..f0b2458996a 100644
> --- a/audio/audio_template.h
> +++ b/audio/audio_template.h
> @@ -172,7 +172,7 @@ static int glue (audio_pcm_sw_init_, TYPE) (
>      sw->empty = true;
>  #endif
> 
> -    if (audio_format_is_float(hw->info.af)) {
> +    if (audio_format_is_float(sw->info.af)) {
>  #ifdef DAC
>          sw->conv = mixeng_conv_float[sw->info.nchannels == 2]
>              [sw->info.swap_endianness];
> @@ -187,9 +187,9 @@ static int glue (audio_pcm_sw_init_, TYPE) (
>          sw->clip = mixeng_clip
>  #endif
>              [sw->info.nchannels == 2]
> -            [audio_format_is_signed(hw->info.af)]
> +            [audio_format_is_signed(sw->info.af)]
>              [sw->info.swap_endianness]
> -            [audio_format_to_index(hw->info.af)];
> +            [audio_format_to_index(sw->info.af)];
>      }
> 
>      sw->name = g_strdup (name);