shithub: sox

Download patch

ref: 836eb61b9c5fc186465ff4a9d2a4d097c7339a8d
parent: 6257b1b873d24ff2192d86f6efa4817eb433480c
author: Ulrich Klauer <ulrich@chirlu.de>
date: Thu Jan 12 14:36:00 EST 2012

Optional target level argument to --norm

Let the --norm global option accept a target dB level as an optional
argument that is passed on to the gain effect; e.g.,
  sox --norm=-3.5 infile outfile
will normalize to -3.5 dBFS instead of 0 dBFS.

This resolves feature request 3418124.

--- a/sox.1
+++ b/sox.1
@@ -903,7 +903,7 @@
 alias, script, or batch file may be an appropriate way of permanently
 enabling it.
 .TP
-\fB\-\-norm\fR
+\fB\-\-norm\fR[\fB=\fIdB-level\fR]
 Automatically invoke the
 .B gain
 effect to guard against clipping and to normalise the audio. E.g.
@@ -914,6 +914,12 @@
 .EX
    sox infile \-b 16 outfile gain \-h rate 44100 gain \-nh dither \-s
 .EE
+Optionally, the audio can be normalized to a given level (usually)
+below 0 dBFS:
+.EX
+   sox \-\-norm=\-3 infile outfile
+.EE
+.SP
 See also
 .BR \-V,
 .BR \-G,
@@ -1016,7 +1022,7 @@
 .TP
 \fB\-\-version\fR
 Show SoX's version number and exit.
-.IP \fB\-V\fB[\fIlevel\fB]\fP
+.IP \fB\-V\fR[\fIlevel\fR]
 Set verbosity. This is particularly useful for seeing how any automatic
 effects have been invoked by SoX.
 .SP
--- a/src/sox.c
+++ b/src/sox.c
@@ -183,6 +183,7 @@
 static int eff_chain_count = 0;
 static char *effects_filename = NULL;
 static char * play_rate_arg = NULL;
+static char *norm_level = NULL;
 
 /* Flowing */
 
@@ -256,6 +257,7 @@
 
   free(play_rate_arg);
   free(effects_filename);
+  free(norm_level);
 
   sox_quit();
 }
@@ -1069,9 +1071,11 @@
     auto_effect(chain, "rate", rate_arg != NULL, &rate_arg, &signal, &guard);
 
   if (is_guarded && (do_guarded_norm || !(signal.mult && *signal.mult == 1))) {
-    char * arg = do_guarded_norm? "-nh" : guard? "-rh" : "-h";
+    char *args[2];
     int no_guard = -1;
-    auto_effect(chain, "gain", 1, &arg, &signal, &no_guard);
+    args[0] = do_guarded_norm? "-nh" : guard? "-rh" : "-h";
+    args[1] = norm_level;
+    auto_effect(chain, "gain", norm_level ? 2 : 1, args, &signal, &no_guard);
     guard = 1;
   }
 
@@ -2155,7 +2159,7 @@
   {"temp"            , lsx_option_arg_required, NULL, 0},
   {"single-threaded" , lsx_option_arg_none    , NULL, 0},
   {"ignore-length"   , lsx_option_arg_none    , NULL, 0},
-  {"norm"            , lsx_option_arg_none    , NULL, 0},
+  {"norm"            , lsx_option_arg_optional, NULL, 0},
   {"magic"           , lsx_option_arg_none    , NULL, 0},
   {"play-rate-arg"   , lsx_option_arg_required, NULL, 0},
   {"clobber"         , lsx_option_arg_none    , NULL, 0},
@@ -2333,7 +2337,9 @@
       case 16: sox_globals.tmp_path = lsx_strdup(optstate.arg); break;
       case 17: sox_globals.use_threads = sox_false; break;
       case 18: f->signal.length = SOX_IGNORE_LENGTH; break;
-      case 19: do_guarded_norm = is_guarded = sox_true; break;
+      case 19: do_guarded_norm = is_guarded = sox_true;
+        norm_level = lsx_strdup(optstate.arg);
+        break;
       case 20:
         if (info->flags & sox_version_have_magic)
           sox_globals.use_magic = sox_true;