shithub: sox

Download patch

ref: 1c64d8c6e40dfcef48b795fd4825bc3fe9defccd
parent: b0a4cc8d85abac7d743ccf80a6da80c9c9a72c96
author: Ulrich Klauer <ulrich@chirlu.de>
date: Sat Sep 24 18:34:05 EDT 2011

dither effect: allow overriding the target precision

Add a new -p <precision> option to the dither effect that allows to
specify a desired target precision, overriding the default that is
based on the output resolution.

--- a/sox.1
+++ b/sox.1
@@ -812,7 +812,7 @@
 combining methods.
 .TP
 \fB\-D\fR, \fB\-\-no\-dither\fR
-Disable automatic dither\*msee `Dither' above.  An example of why this
+Disable automatic dither\*msee `Dithering' above.  An example of why this
 might occasionally be useful is if a file has been converted from 16 to
 24 bit with the intention of doing some processing on it, but in fact
 no processing is needed after all and the original 16 bit file has
@@ -1923,7 +1923,7 @@
 	delay 0 .05 .1 .15 .2 .25 remix \- fade 0 4 .1 norm \-1
 .EE
 .TP
-\fBdither\fR [\fB\-a\fR] [\fB\-S\fR\^|\^\fB\-s\fR\^|\^\fB\-f \fIfilter\fR]
+\fBdither\fR [\fB\-S\fR\^|\^\fB\-s\fR\^|\^\fB\-f \fIfilter\fR] [\fB\-a\fR] [\fB\-p \fIprecision\fR]
 Apply dithering to the audio.
 Dithering deliberately adds a small amount of noise to the signal in
 order to mask audible quantization effects that can occur if the output
@@ -1964,6 +1964,10 @@
 .BR fade ,
 and concatencate.
 .SP
+The
+.B \-p
+option allows overriding the target precision.
+.SP
 If the SoX global option
 .B \-R
 option is not given, then the pseudo-random number generator used to
@@ -1973,7 +1977,7 @@
 This effect should not be followed by any other effect that
 affects the audio.
 .SP
-See also the `Dither' section above.
+See also the `Dithering' section above.
 .TP
 \fBearwax\fR
 Makes audio easier to listen to on headphones.
--- a/src/dither.c
+++ b/src/dither.c
@@ -329,7 +329,7 @@
   priv_t * p = (priv_t *)effp->priv;
   int c;
   lsx_getopt_t optstate;
-  lsx_getopt_init(argc, argv, "+aSsf:rt", NULL, lsx_getopt_flag_none, 1, &optstate);
+  lsx_getopt_init(argc, argv, "+aSsf:p:rt", NULL, lsx_getopt_flag_none, 1, &optstate);
 
   while ((c = lsx_getopt(&optstate)) != -1) switch (c) {
     case 'a': p->auto_detect = sox_true; break;
@@ -341,6 +341,7 @@
       if (p->filter_name == INT_MAX)
         return SOX_EOF;
       break;
+    GETOPT_NUMERIC(optstate, 'p', prec, 1, 24)
     default: lsx_fail("invalid option `-%c'", optstate.opt); return lsx_usage(effp);
   }
   argc -= optstate.ind, argv += optstate.ind;
@@ -353,7 +354,9 @@
   priv_t * p = (priv_t *)effp->priv;
   double mult = 1; /* Amount the noise shaping multiplies up the TPDF (+/-1) */
 
-  p->prec = effp->out_signal.precision;
+  if (p->prec == 0)
+    p->prec = effp->out_signal.precision;
+
   if (effp->in_signal.precision <= p->prec || p->prec > 24)
     return SOX_EFF_NULL;   /* Dithering not needed at this resolution */
   effp->out_signal.precision = effp->in_signal.precision;
@@ -404,14 +407,15 @@
 sox_effect_handler_t const * lsx_dither_effect_fn(void)
 {
   static sox_effect_handler_t handler = {
-    "dither", "[-a] [-S|-s|-f filter]"
+    "dither", "[-S|-s|-f filter] [-a] [-p precision]"
     "\n  (none)   Use TPDF"
-    "\n  -a       Automatically turn on & off dithering as needed (use with caution!)"
     "\n  -S       Use sloped TPDF (without noise shaping)"
     "\n  -s       Shape noise (with shibata filter)"
     "\n  -f name  Set shaping filter to one of: lipshitz, f-weighted,"
     "\n           modified-e-weighted, improved-e-weighted, gesemann,"
-    "\n           shibata, low-shibata, high-shibata.",
+    "\n           shibata, low-shibata, high-shibata."
+    "\n  -a       Automatically turn on & off dithering as needed (use with caution!)"
+    "\n  -p bits  Override the target sample precision",
     SOX_EFF_PREC, getopts, start, flow, 0, 0, 0, sizeof(priv_t)
   };
   return &handler;