瀏覽代碼

audio: change mixing engine float range to [-1.f, 1.f]

Currently the internal float range of the mixing engine is
[-.5f, .5f]. PulseAudio, SDL2 and libasound use a [-1.f, 1.f]
range. This means with float samples the audio playback volume
is 6dB too low and audio recording signals will be clipped in
most cases.

To avoid another scaling factor in the conv_natural_float_* and
clip_natural_float_* functions with FLOAT_MIXENG defined this
patch changes the mixing engine float range to [-1.f, 1.f].

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 20200308193321.20668-4-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Volker Rümelin 5 年之前
父節點
當前提交
4218fdd77f
共有 2 個文件被更改,包括 10 次插入11 次删除
  1. 2 2
      audio/mixeng.c
  2. 8 9
      audio/mixeng_template.h

+ 2 - 2
audio/mixeng.c

@@ -271,11 +271,11 @@ f_sample *mixeng_clip[2][2][2][3] = {
 #define CONV_NATURAL_FLOAT(x) (x)
 #define CONV_NATURAL_FLOAT(x) (x)
 #define CLIP_NATURAL_FLOAT(x) (x)
 #define CLIP_NATURAL_FLOAT(x) (x)
 #else
 #else
-static const float float_scale = UINT_MAX;
+static const float float_scale = UINT_MAX / 2.f;
 #define CONV_NATURAL_FLOAT(x) ((x) * float_scale)
 #define CONV_NATURAL_FLOAT(x) ((x) * float_scale)
 
 
 #ifdef RECIPROCAL
 #ifdef RECIPROCAL
-static const float float_scale_reciprocal = 1.f / UINT_MAX;
+static const float float_scale_reciprocal = 2.f / UINT_MAX;
 #define CLIP_NATURAL_FLOAT(x) ((x) * float_scale_reciprocal)
 #define CLIP_NATURAL_FLOAT(x) ((x) * float_scale_reciprocal)
 #else
 #else
 #define CLIP_NATURAL_FLOAT(x) ((x) / float_scale)
 #define CLIP_NATURAL_FLOAT(x) ((x) / float_scale)

+ 8 - 9
audio/mixeng_template.h

@@ -41,32 +41,31 @@ static inline mixeng_real glue (conv_, ET) (IN_T v)
 
 
 #ifdef RECIPROCAL
 #ifdef RECIPROCAL
 #ifdef SIGNED
 #ifdef SIGNED
-    return nv * (1.f / (mixeng_real) (IN_MAX - IN_MIN));
+    return nv * (2.f / ((mixeng_real)IN_MAX - IN_MIN));
 #else
 #else
-    return (nv - HALF) * (1.f / (mixeng_real) IN_MAX);
+    return (nv - HALF) * (2.f / (mixeng_real)IN_MAX);
 #endif
 #endif
 #else  /* !RECIPROCAL */
 #else  /* !RECIPROCAL */
 #ifdef SIGNED
 #ifdef SIGNED
-    return nv / (mixeng_real) ((mixeng_real) IN_MAX - IN_MIN);
+    return nv / (((mixeng_real)IN_MAX - IN_MIN) / 2.f);
 #else
 #else
-    return (nv - HALF) / (mixeng_real) IN_MAX;
+    return (nv - HALF) / ((mixeng_real)IN_MAX / 2.f);
 #endif
 #endif
 #endif
 #endif
 }
 }
 
 
 static inline IN_T glue (clip_, ET) (mixeng_real v)
 static inline IN_T glue (clip_, ET) (mixeng_real v)
 {
 {
-    if (v >= 0.5) {
+    if (v >= 1.f) {
         return IN_MAX;
         return IN_MAX;
-    }
-    else if (v < -0.5) {
+    } else if (v < -1.f) {
         return IN_MIN;
         return IN_MIN;
     }
     }
 
 
 #ifdef SIGNED
 #ifdef SIGNED
-    return ENDIAN_CONVERT ((IN_T) (v * ((mixeng_real) IN_MAX - IN_MIN)));
+    return ENDIAN_CONVERT((IN_T)(v * (((mixeng_real)IN_MAX - IN_MIN) / 2.f)));
 #else
 #else
-    return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
+    return ENDIAN_CONVERT((IN_T)((v * ((mixeng_real)IN_MAX / 2.f)) + HALF));
 #endif
 #endif
 }
 }