changeset 4272:32bb5ea701ed

- software volume switched to floating point and placed _after_ resampling - js: i was mistaken: all of DSP stuff currently done after resampling (except vis, it doesn't change anything). RG processing done inside libSAD, i.e. after resampling too, just before dithering.
author Eugene Zagidullin <e.asphyx@gmail.com>
date Sun, 10 Feb 2008 21:50:46 +0300
parents 90282d9e4bec
children 9fe8b073a05e
files src/audacious/output.c src/audacious/volumecontrol.c
diffstat 2 files changed, 30 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/src/audacious/output.c	Sun Feb 10 16:13:30 2008 +0300
+++ b/src/audacious/output.c	Sun Feb 10 21:50:46 2008 +0300
@@ -509,7 +509,6 @@
         legacy_flow = flow_new();
         flow_link_element(legacy_flow, iir_flow);
         flow_link_element(legacy_flow, effect_flow);
-        flow_link_element(legacy_flow, volumecontrol_flow);
     }
     
     if (postproc_flow == NULL)
@@ -519,6 +518,7 @@
 #ifdef USE_SRC
         flow_link_element(postproc_flow, src_flow);
 #endif
+        flow_link_element(postproc_flow, volumecontrol_flow);
     }
 
     int frames = length / nch / FMT_SIZEOF(fmt);
--- a/src/audacious/volumecontrol.c	Sun Feb 10 16:13:30 2008 +0300
+++ b/src/audacious/volumecontrol.c	Sun Feb 10 21:50:46 2008 +0300
@@ -43,119 +43,41 @@
 
 static volumecontrol_req_t vc_state_ = { 100, 100 };
 
-#define STEREO_ADJUST(type, type2, endian)                                      \
-do {                                                                            \
-        type *ptr = data;                                                       \
-        for (i = 0; i < length; i += 4)                                         \
-        {                                                                       \
-                *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) *       \
-                                           lvol / 256);                         \
-                ptr++;                                                          \
-                *ptr = type2##_TO_##endian(type2##_FROM_##endian(*ptr) *        \
-                                           rvol / 256);                         \
-                ptr++;                                                          \
-        }                                                                       \
-} while (0)
-
-#define MONO_ADJUST(type, type2, endian)                                        \
-do {                                                                            \
-        type *ptr = data;                                                       \
-        for (i = 0; i < length; i += 2)                                         \
-        {                                                                       \
-                *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) *       \
-                                           vol / 256);                          \
-                ptr++;                                                          \
-        }                                                                       \
-} while (0)
-
-#define VOLUME_ADJUST(type, type2, endian)              \
-do {                                                    \
-        if (channels == 2)                              \
-                STEREO_ADJUST(type, type2, endian);     \
-        else                                            \
-                MONO_ADJUST(type, type2, endian);       \
-} while (0)
-
-#define STEREO_ADJUST8(type)                            \
-do {                                                    \
-        type *ptr = data;                               \
-        for (i = 0; i < length; i += 2)                 \
-        {                                               \
-                *ptr = *ptr * lvol / 256;               \
-                ptr++;                                  \
-                *ptr = *ptr * rvol / 256;               \
-                ptr++;                                  \
-        }                                               \
-} while (0)
-
-#define MONO_ADJUST8(type)                      \
-do {                                            \
-        type *ptr = data;                       \
-        for (i = 0; i < length; i++)            \
-        {                                       \
-                *ptr = *ptr * vol / 256;        \
-                ptr++;                          \
-        }                                       \
-} while (0)
-
-#define VOLUME_ADJUST8(type)                    \
-do {                                            \
-        if (channels == 2)                      \
-                STEREO_ADJUST8(type);           \
-        else                                    \
-                MONO_ADJUST8(type);             \
-} while (0)
+#define GAIN -50.0 /* dB */
 
 void volumecontrol_pad_audio(gpointer data, gint length, AFormat fmt,
     gint channels)
 {
-    gint i, vol, lvol, rvol;
+    gint i, k, samples;
+    float vol, lvol, rvol;
+    float lgain, rgain;
 
     if (vc_state_.left == 100 && vc_state_.right == 100)
         return;
 
-    if (channels == 1 && (vc_state_.left == 100 || vc_state_.right == 100))
+    if (channels != 2 && (vc_state_.left == 100 || vc_state_.right == 100))
         return;
 
-    lvol = pow(10, (vc_state_.left - 100) / 40.0) * 256;
-    rvol = pow(10, (vc_state_.right - 100) / 40.0) * 256;
+    lgain = (float)(100 - vc_state_.left) * GAIN / 100.0;
+    rgain = (float)(100 - vc_state_.right) * GAIN / 100.0;
+
+    lvol = pow(10.0, lgain / 20.0);
+    rvol = pow(10.0, rgain / 20.0);
     vol = MAX(lvol, rvol);
 
-    switch (fmt)
-    {
-        case FMT_S16_NE:
-            fmt = G_BYTE_ORDER == G_LITTLE_ENDIAN ? FMT_S16_LE : FMT_S16_LE;
-            break;
-        case FMT_U16_NE:
-            fmt = G_BYTE_ORDER == G_LITTLE_ENDIAN ? FMT_U16_LE : FMT_U16_BE;
-            break;
-        default:
-            break;
-    }
-
-    switch (fmt)
-    {
-        case FMT_S16_LE:
-            VOLUME_ADJUST(gint16, GINT16, LE);
-            break;
-        case FMT_U16_LE:
-            VOLUME_ADJUST(guint16, GUINT16, LE);
-            break;
-        case FMT_S16_BE:
-            VOLUME_ADJUST(gint16, GINT16, LE);
-            break;
-        case FMT_U16_BE:
-            VOLUME_ADJUST(guint16, GUINT16, LE);
-            break;
-        case FMT_S8:
-            VOLUME_ADJUST8(gint8);
-            break;
-        case FMT_U8:
-            VOLUME_ADJUST8(guint8);
-            break;
-        default:
-            g_warning("unhandled format %d.", fmt);
-            break;
+    float *ptr = data;
+    samples = length / sizeof(float);
+    for (k = 0; k < samples; k++) {
+        if (channels == 2) {
+            *ptr *= lvol;
+            ptr++;
+            *ptr *= rvol;
+            ptr++;
+        } else { /* for mono and other channels number */
+            for (i = 0; i < channels; i++) {
+                *ptr *= vol; ptr++;
+            }
+        }
     }
 }
 
@@ -179,5 +101,11 @@
     if (!cfg.software_volume_control)
         return;
 
+    if (context->fmt != FMT_FLOAT) {
+        g_warning("volumecontrol_flow(): unhandled format %d.", context->fmt);
+        context->error = TRUE;
+        return;
+    }
+
     volumecontrol_pad_audio(context->data, context->len, context->fmt, context->channels);
 }