changeset 2344:fd8271f07747

replaced 6db hard limit with experimental adaptive scaler clip prevention.
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Sun, 03 Feb 2008 00:05:32 +0900
parents f40f4ae3d5eb
children 0405c29fecf7
files src/madplug/configure.c src/madplug/decoder.c src/madplug/plugin.c src/madplug/plugin.h
diffstat 4 files changed, 44 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/src/madplug/configure.c	Thu Jan 31 15:26:50 2008 +0900
+++ b/src/madplug/configure.c	Sun Feb 03 00:05:32 2008 +0900
@@ -71,7 +71,7 @@
     GtkWidget *preamp1 = g_object_get_data(widgets, "preamp1");
     GtkWidget *preamp2 = g_object_get_data(widgets, "preamp2");
     GtkWidget *trackMode = g_object_get_data(widgets, "trackMode");
-    GtkWidget *hard_limit = g_object_get_data(widgets, "hard_limit");
+    GtkWidget *adaptive_scaler = g_object_get_data(widgets, "adaptive_scaler");
     GtkWidget *anti_clip = g_object_get_data(widgets, "anti_clip");
     GtkWidget *title_override = g_object_get_data(widgets, "title_override");
     GtkWidget *title_id3_entry = g_object_get_data(widgets, "title_id3_entry");
@@ -135,8 +135,8 @@
 
     audmad_config->replaygain.anti_clip =
         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(anti_clip));
-    audmad_config->replaygain.hard_limit =
-        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hard_limit));
+    audmad_config->replaygain.adaptive_scaler =
+        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(adaptive_scaler));
 
     //text
     audmad_config->title_override =
@@ -184,8 +184,8 @@
                           audmad_config->replaygain.preamp2_db);
     aud_cfg_db_set_bool(db, "MAD", "RG.anti_clip",
                         audmad_config->replaygain.anti_clip);
-    aud_cfg_db_set_bool(db, "MAD", "RG.hard_limit",
-                        audmad_config->replaygain.hard_limit);
+    aud_cfg_db_set_bool(db, "MAD", "RG.adaptive_scaler",
+                        audmad_config->replaygain.adaptive_scaler);
 
     //text
     aud_cfg_db_set_bool(db, "MAD", "title_override", audmad_config->title_override);
@@ -301,7 +301,7 @@
 
     GtkWidget *fast_playback, *use_xing, *dither, *sjis, *show_avg, *reopen;
     GtkWidget *RG_enable, *type_vbox, *rg_vbox, *preamp0, *preamp1, *preamp2;
-    GtkWidget *trackMode, *albumMode, *hard_limit, *anti_clip;
+    GtkWidget *trackMode, *albumMode, *adaptive_scaler, *anti_clip;
     GtkWidget *title_override, *title_id3_entry;
     GtkWidget *rgtypeFrame, *replaygainFrame, *metadataFrame, *audioFrame, *miscFrame;
     GtkWidget *metadata_vbox, *audio_vbox, *misc_vbox;
@@ -527,7 +527,7 @@
 
 
     // clipping prevention
-    anti_clip = gtk_check_button_new_with_label(_("Enable clip prevention using peak info"));
+    anti_clip = gtk_check_button_new_with_label(_("Enable peak info clip prevention"));
     g_object_set_data(widgets, "anti_clip", anti_clip);
     gtk_box_pack_start(GTK_BOX(rg_vbox), anti_clip, TRUE, TRUE, 0);
 
@@ -548,14 +548,13 @@
     /* end of replaygainFrame */
 
 
-    // 6dB hard limit
-    hard_limit = gtk_check_button_new_with_label(_("Apply 6dB hard limit"));
-    g_object_set_data(widgets, "hard_limit", hard_limit);
-    gtk_box_pack_start(GTK_BOX(vbox2), hard_limit, TRUE, TRUE, 0);
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hard_limit),
-                                 audmad_config->replaygain.hard_limit);
-
-    g_signal_connect(G_OBJECT(hard_limit), "clicked",
+    // adaptive scale
+    adaptive_scaler = gtk_check_button_new_with_label(_("Enable adaptive scaler clip prevention"));
+    g_object_set_data(widgets, "adaptive_scaler", adaptive_scaler);
+    gtk_box_pack_start(GTK_BOX(vbox2), adaptive_scaler, TRUE, TRUE, 0);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(adaptive_scaler),
+                                 audmad_config->replaygain.adaptive_scaler);
+    g_signal_connect(G_OBJECT(adaptive_scaler), "clicked",
                      G_CALLBACK(simple_update_cb), widgets);
 
 
--- a/src/madplug/decoder.c	Thu Jan 31 15:26:50 2008 +0900
+++ b/src/madplug/decoder.c	Sun Feb 03 00:05:32 2008 +0900
@@ -45,9 +45,8 @@
 scale(mad_fixed_t sample, struct mad_info_t *file_info)
 {
     gdouble scale = -1;
-#ifdef AUD_DEBUG
-    static int i = 0;
-#endif
+    static double a_scale = -1;
+    static int iter = 0;
 
     if (audmad_config->replaygain.enable) {
         if (file_info->has_replaygain) {
@@ -66,7 +65,7 @@
 
             if (audmad_config->replaygain.anti_clip) {
 #ifdef AUD_DEBUG
-                if(i%100000 == 0)
+                if(iter % 100000 == 0)
                     AUDDBG("track_peak = %f\n", file_info->replaygain_track_peak);
 #endif
                 if(scale * file_info->replaygain_track_peak >= 1.0)
@@ -86,44 +85,37 @@
     if (audmad_config->replaygain.preamp0_scale != 1)
         scale = scale * audmad_config->replaygain.preamp0_scale;
 
-#ifdef AUD_DEBUG
-    if(i%100000 == 0) {
-        AUDDBG("scale = %f\n", scale);
-    }
-#endif
+    // adaptive scaler clip prevention
+    if (audmad_config->replaygain.adaptive_scaler) {
+        double x;
+        double a = 0.1;
+        int interval = 10000;
 
-    /* hard-limit (clipping-prevention) */
-    if (audmad_config->replaygain.hard_limit) {
+        if(a_scale == -1.0)
+            a_scale = scale;
+
+        x = mad_f_todouble(sample) * a_scale;
 
-#ifdef AUD_DEBUG
-        if(i%100000 == 0) {
-            AUDDBG("hard_limit\n");
+        // clippling avoidance
+        if(x > 1.0) {
+            a_scale = a_scale + a * (1.0 - x);
+            AUDDBG("down: x = %f a_scale = %f\n", x, a_scale);
         }
-#endif
-        /* convert to double before computation, to avoid mad_fixed_t wrapping */
-        double x = mad_f_todouble(sample) * scale;
-        static const double k = 0.5;    // -6dBFS
-        if (x > k) {
-            x = tanh((x - k) / (1 - k)) * (1 - k) + k;
+        // slowly go back to defined scale
+        else if(iter % interval == 0 && a_scale < scale){
+            a_scale = a_scale + 1.0e-4;
+            AUDDBG("up: a_scale = %f\n", a_scale);
         }
-        else if (x < -k) {
-            x = tanh((x + k) / (1 - k)) * (1 - k) - k;
-        }
-        sample = x * (MAD_F_ONE);
 
-#ifdef AUD_DEBUG
-        if(i%100000 == 0) {
-            AUDDBG("x = %f sample = %d\n", x, sample);
-        }
-#endif
-
+        x = mad_f_todouble(sample) * a_scale;
+        sample = x * (MAD_F_ONE);
     }
-    else
+    else {
+        a_scale = scale;
         sample *= scale;
+    }
 
-#ifdef AUD_DEBUG
-    i++;
-#endif
+    iter++;
 
     int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16;
 
--- a/src/madplug/plugin.c	Thu Jan 31 15:26:50 2008 +0900
+++ b/src/madplug/plugin.c	Sun Feb 03 00:05:32 2008 +0900
@@ -143,7 +143,7 @@
     audmad_config->replaygain.enable = TRUE;
     audmad_config->replaygain.track_mode = FALSE;
     audmad_config->replaygain.anti_clip = FALSE;
-    audmad_config->replaygain.hard_limit = FALSE;
+    audmad_config->replaygain.adaptive_scaler = FALSE;
     audmad_config->title_override = FALSE;
 
 
@@ -178,8 +178,8 @@
                               &audmad_config->replaygain.preamp2_db);
         aud_cfg_db_get_bool(db, "MAD", "RG.anti_clip",
                             &audmad_config->replaygain.anti_clip);
-        aud_cfg_db_get_bool(db, "MAD", "RG.hard_limit",
-                            &audmad_config->replaygain.hard_limit);
+        aud_cfg_db_get_bool(db, "MAD", "RG.adaptive_scaler",
+                            &audmad_config->replaygain.adaptive_scaler);
 
         //text
         aud_cfg_db_get_bool(db, "MAD", "title_override",
--- a/src/madplug/plugin.h	Thu Jan 31 15:26:50 2008 +0900
+++ b/src/madplug/plugin.h	Sun Feb 03 00:05:32 2008 +0900
@@ -120,8 +120,8 @@
         gdouble preamp1_scale;
         gchar *preamp2_db;      // preamp used without RG info.
         gdouble preamp2_scale;
-        gboolean hard_limit;
         gboolean anti_clip;
+        gboolean adaptive_scaler;
     } replaygain;
 
     gboolean title_override;