shithub: sox

Download patch

ref: 892e60436b7b9d2014d4aa8dc583bc6331c41ad8
parent: 56b927281e4045f05dbfb7deb3dde17af8053540
author: robs <robs>
date: Fri Sep 26 04:50:34 EDT 2008

plot fix/update

--- a/ChangeLog
+++ b/ChangeLog
@@ -39,9 +39,9 @@
 
 File formats:
 
+  o New unfiltered CVSD; supports any bit-rate.  (robs)
   o Fix WAV write on 64-bit arch.  (robs)
   o Fix writing PRC ADPCM files.  (Silas Brown)
-  o Unfiltered CVSD; supports any bit-rate.  (robs)
 
 Effects:
 
@@ -54,10 +54,12 @@
     compensation.  (robs)
   o New -b option for the norm effect; can be used to fix stereo
     imbalance.  (robs)
-  o Fix broken audio pass-through with noiseprof effect.  (robs)
-  o Improved documentation for the `stat' effect.  (robs)
   o New --effects-file option to read effects and arguments from
     a file instead of command line. (cbagwell)
+  o `filter' effect now supports --plot octave.  (robs)
+  o Improved documentation for the `stat' effect.  (robs)
+  o Fix broken audio pass-through with noiseprof effect.  (robs)
+  o Fix graph legend display when using --plot octave.  (robs)
 
 Other new features:
 
@@ -69,6 +71,7 @@
   o New -t option for soxi; to display the detected file type.  (robs)
   o New -b/--bits, -e/--encoding alternative options for specifying
     audio encoding parameters.  (robs)
+  o [FR 1958680] Support more than 32 input files.  (robs)
 
 Other bug fixes:
 
@@ -88,7 +91,7 @@
 
   o Fixed all compiler warnings (with gcc 4.3.1, 64-bit arch.).  (robs)
   o Updates to internal effects chain API.  (cbagwell)
-  o Retire old FFT routines (speeds up noisered effect).  (robs)
+  o Retire old FFT routines (speeds up `noisered' effect).  (robs)
   o Allow effects to use getopt.  (robs)
 
 
--- a/sox.1
+++ b/sox.1
@@ -1223,9 +1223,13 @@
 A typical value is
 .B 0\*d2
 seconds.
+.TS
+center;
+c8 c8 c.
+*	*	*
+.TE
+.DT
 .SP
-This effect supports the \fB\-\-plot\fR global option (for the transfer function).
-.SP
 The following example might be used to make a piece of music with both
 quiet and loud passages suitable for listening to in a noisy environment
 such as a moving vehicle:
@@ -1246,6 +1250,8 @@
 with near silence, and the delay of 0\*d2 (seconds) has the effect of causing
 the compander to react a bit more quickly to sudden volume changes.
 .SP
+This effect supports the \fB\-\-plot\fR global option (for the transfer function).
+.SP
 See also
 .B mcompand
 for a multiple-band companding effect.
@@ -1494,7 +1500,7 @@
 .SP
 The \fIbeta\fR parameter
 determines the type of filter window used.  Any value greater than 2 is
-the beta for a Kaiser window.  Beta \(<= 2 selects a Nuttall window.
+the beta for a Kaiser window.  Beta \(<= 2 selects a Blackman-Nuttall window.
 If unspecified, the default is a Kaiser window with beta 16.
 .SP
 In the case of Kaiser window (beta > 2), lower betas produce a
@@ -1501,11 +1507,13 @@
 somewhat faster transition from pass-band to stop-band, at the cost of
 noticeable artifacts. A beta of 16 is the default, beta less than 10
 is not recommended. If you want a sharper cut-off, don't use low
-beta's, use a longer sample window. A Nuttall window is selected by
-specifying any `beta' \(<= 2, and the Nuttall window has somewhat
+beta's, use a longer sample window. A Blackman-Nuttall window is selected by
+specifying any `beta' \(<= 2, and the Blackman-Nuttall window has somewhat
 steeper cut-off than the default Kaiser window. You will probably not
 need to use the beta parameter at all, unless you are just curious
-about comparing the effects of Nuttall vs. Kaiser windows.
+about comparing the effects of Blackman-Nuttall vs. Kaiser windows.
+.SP
+This effect supports the \fB\-\-plot octave\fR global option.
 .TP
 \fBflanger\fR [\fIdelay depth regen width speed shape phase interp\fR]
 Apply a flanging effect to the audio.
@@ -2941,9 +2949,9 @@
 and, compared with the \fBrate\fR effect, is generally slow, memory intensive,
 and has poorer stop-band rejection.
 .SP
-If the \fB\-w\fR parameter is \fBnut\fR, then a Nuttall (~90 dB
+If the \fB\-w\fR parameter is \fBnut\fR, then a Blackman-Nuttall (~90 dB
 stop-band) window will be used; \fBham\fR selects a Hamming (~43
-dB stop-band) window.  The default is Nuttall.
+dB stop-band) window.  The default is Blackman-Nuttall.
 .SP
 The \fB\-width\fR parameter specifies the (approximate) width of the filter. The default is 1024 samples, which produces reasonable results.
 .SP
@@ -3049,7 +3057,7 @@
 these artifacts, with closer also being better.
 .SP
 The \fIbeta\fR, if unspecified, defaults to 16.  This selects a Kaiser window.
-You can select a Nuttall window by specifying anything \(<= 2 here.
+You can select a Blackman-Nuttall window by specifying anything \(<= 2 here.
 For more discussion of beta, look under the \fBfilter\fR effect.
 .SP
 Default parameters are, as indicated above, Kaiser window of length 45,
--- a/src/biquad.c
+++ b/src/biquad.c
@@ -70,20 +70,20 @@
   if (effp->global_info->plot == sox_plot_octave) {
     printf(
       "%% GNU Octave file (may also work with MATLAB(R) )\n"
+      "Fs=%g;minF=10;maxF=Fs/2;\n"
+      "sweepF=logspace(log10(minF),log10(maxF),200);\n"
+      "[h,w]=freqz([%g %g %g],[1 %g %g],sweepF,Fs);\n"
+      "semilogx(w,20*log10(h))\n"
       "title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)')\n"
       "xlabel('Frequency (Hz)')\n"
       "ylabel('Amplitude Response (dB)')\n"
-      "Fs=%g;minF=10;maxF=Fs/2;\n"
       "axis([minF maxF -35 25])\n"
-      "sweepF=logspace(log10(minF),log10(maxF),200);\n"
       "grid on\n"
-      "[h,w]=freqz([%g %g %g],[1 %g %g],sweepF,Fs);\n"
-      "semilogx(w,20*log10(h))\n"
       "disp('Hit return to continue')\n"
       "pause\n"
+      , effp->in_signal.rate, p->b0, p->b1, p->b2, p->a1, p->a2
       , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
-      , effp->in_signal.rate, effp->in_signal.rate
-      , p->b0, p->b1, p->b2, p->a1, p->a2);
+      , effp->in_signal.rate);
     return SOX_EOF;
   }
   if (effp->global_info->plot == sox_plot_gnuplot) {
--- a/src/compandt.c
+++ b/src/compandt.c
@@ -36,11 +36,7 @@
   if (plot == sox_plot_octave) {
     printf(
       "%% GNU Octave file (may also work with MATLAB(R) )\n"
-      "title('SoX effect: compand')\n"
-      "xlabel('Input level (dB)')\n"
-      "ylabel('Output level (dB)')\n"
       "in=linspace(-99.5,0,200);\n"
-      "grid on\n"
       "out=[");
     for (i = -199; i <= 0; ++i) {
       double in = i/2.;
@@ -49,8 +45,12 @@
     }
     printf(
       "];\n"
-      "%%plot(in,out) %% hmm.. doesn't work :(\n"
-      "semilogx(exp(in),out)\n"
+      "plot(in,out)\n"
+      "title('SoX effect: compand')\n"
+      "xlabel('Input level (dB)')\n"
+      "ylabel('Output level (dB)')\n"
+      "grid on\n"
+      "disp('Hit return to continue')\n"
       "pause\n");
     return sox_false;
   }
--- a/src/filter.c
+++ b/src/filter.c
@@ -35,8 +35,8 @@
 /* Private data for Lerp via LCM file */
 typedef struct {
         sox_rate_t rate;
-        sox_sample_t freq0;/* low  corner freq */
-        sox_sample_t freq1;/* high corner freq */
+        double freq0;/* low  corner freq */
+        double freq1;/* high corner freq */
         double beta;/* >2 is kaiser window beta, <=2 selects nuttall window */
         long Nwin;
         double *Fp;/* [Xh+1] Filter coefficients */
@@ -53,9 +53,6 @@
  * reference: "Digital Filters, 2nd edition"
  *            R.W. Hamming, pp. 178-179
  *
- * Izero() computes the 0th order modified bessel function of the first kind.
- *    (Needed to compute Kaiser window).
- *
  * LpFilter() computes the coeffs of a Kaiser-windowed low pass filter with
  *    the following characteristics:
  *
@@ -86,25 +83,6 @@
  */
 
 
-#define IzeroEPSILON 1E-21               /* Max error acceptable in Izero */
-
-static double Izero(double x)
-{
-   double sum, u, halfx, temp;
-   long n;
-
-   sum = u = n = 1;
-   halfx = x/2.0;
-   do {
-      temp = halfx/(double)n;
-      n += 1;
-      temp *= temp;
-      u *= temp;
-      sum += u;
-   } while (u >= IzeroEPSILON*sum);
-   return(sum);
-}
-
 static void LpFilter(double *c, long N, double frq, double Beta, long Num)
 {
    long i;
@@ -117,15 +95,15 @@
    }
 
    if (Beta>2) { /* Apply Kaiser window to filter coeffs: */
-      double IBeta = 1.0/Izero(Beta);
+      double IBeta = 1.0/lsx_bessel_I_0(Beta);
       for (i=1; i<N; i++) {
          double x = (double)i / (double)(N);
-         c[i] *= Izero(Beta*sqrt(1.0-x*x)) * IBeta;
+         c[i] *= lsx_bessel_I_0(Beta*sqrt(1.0-x*x)) * IBeta;
       }
    } else { /* Apply Nuttall window: */
       for(i = 0; i < N; i++) {
          double x = M_PI*i / N;
-         c[i] *= 0.36335819 + 0.4891775*cos(x) + 0.1365995*cos(2*x) + 0.0106411*cos(3*x);
+         c[i] *= 0.3635819 + 0.4891775*cos(x) + 0.1365995*cos(2*x) + 0.0106411*cos(3*x);
       }
    }
 }
@@ -203,7 +181,7 @@
                 }
                 if (*p) f->freq1 = f->freq0 = 0;
         }
-        sox_debug("freq: %d-%d", f->freq0, f->freq1);
+        sox_debug("freq: %g-%g", f->freq0, f->freq1);
         if (f->freq0 == 0 && f->freq1 == 0)
           return lsx_usage(effp);
 
@@ -217,7 +195,7 @@
         if ((n >= 3) && !sscanf(argv[2], "%lf", &f->beta))
           return lsx_usage(effp);
 
-        sox_debug("filter opts: %d-%d, window-len %ld, beta %f", f->freq0, f->freq1, f->Nwin, f->beta);
+        sox_debug("filter opts: %g-%g, window-len %ld, beta %f", f->freq0, f->freq1, f->Nwin, f->beta);
         return (SOX_SUCCESS);
 }
 
@@ -239,7 +217,7 @@
 
         if ((f->freq0 < 0) || (f->freq0 > f->freq1))
         {
-                sox_fail("filter: low(%d),high(%d) parameters must satisfy 0 <= low <= high <= %g",
+                sox_fail("filter: low(%g),high(%g) parameters must satisfy 0 <= low <= high <= %g",
                                         f->freq0, f->freq1, f->rate/2);
                 return (SOX_EOF);
         }
@@ -285,11 +263,30 @@
 
         Xh -= 1;       /* Xh = 0 can only happen if filter was identity 0-Nyquist */
         if (Xh<=0)
-                sox_warn("filter: adjusted freq %d-%d is identity", f->freq0, f->freq1);
+                sox_warn("filter: adjusted freq %g-%g is identity", f->freq0, f->freq1);
 
         f->Nwin = 2*Xh + 1;  /* not really used afterwards */
         f->Xh = Xh;
         f->Xt = Xh;
+
+   if (effp->global_info->plot == sox_plot_octave) {
+     printf("%% GNU Octave file (may also work with MATLAB(R) )\nb=[");
+     for (i = 1; i < Xh + 1; ++i)
+       printf("%24.16e\n", f->Fp[Xh + 1 - i]);
+     for (i = 0; i < Xh + 1; ++i)
+       printf("%24.16e\n", f->Fp[i]);
+     printf("];\n"
+       "[h,w]=freqz(b);\n"
+       "plot(%g*w/pi,20*log10(h))\n"
+       "title('SoX effect: filter frequency=%g-%g')\n"
+       "xlabel('Frequency (Hz)')\n"
+       "ylabel('Amplitude Response (dB)')\n"
+       "grid on\n"
+       "disp('Hit return to continue')\n"
+       "pause\n"
+       , effp->in_signal.rate / 2, f->freq0, f->freq1);
+     return SOX_EOF;
+   }
 
         f->X = lsx_malloc(sizeof(double) * (2*BUFFSIZE + 2*Xh));
         f->Y = f->X + BUFFSIZE + 2*Xh;