shithub: sox

Download patch

ref: a6be594c819dc408e2f72425b7de2b5c4590c1eb
parent: 5fb5573e26bdac46be6953e0e0399d1a2aaeb350
author: Rob Sykes <rob@rob-Ideapad-S205.(none)>
date: Mon May 27 14:35:40 EDT 2013

add Dolph window for spectrogram effect

--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,7 @@
   o 'Deemph' can now also be used at 48kHz sample rate.  (robs)
   o 'Rate' now much faster in many cases.  (robs)
   o Allow sending spectrograms to stdout. (Ulrich Klauer)
+  o Allow use of Dolph window with spectrograms. (robs)
   o Allow mixing time and sample-count arguments for the delay
     effect, and for spectrogram -S and -d. (Ulrich Klauer)
   o Support multi-channel LADSPA plugins. (Eric Wong)
--- a/sox.1
+++ b/sox.1
@@ -3239,7 +3239,7 @@
 colours to use inside the Z-axis range; two colours are reserved to
 represent out-of-range values.
 .IP \fB\-w\ \fIname\fR
-Window: Hann (default), Hamming, Bartlett, Rectangular or Kaiser.  The
+Window: Hann (default), Hamming, Bartlett, Rectangular, Kaiser or Dolph.  The
 spectrogram is produced using the Discrete Fourier Transform (DFT)
 algorithm.  A significant parameter to this algorithm is the choice of
 `window function'.  By default, SoX uses the Hann window which has good
@@ -3246,10 +3246,10 @@
 all-round frequency-resolution and dynamic-range properties.  For better
 frequency resolution (but lower dynamic-range), select a Hamming window;
 for higher dynamic-range (but poorer frequency-resolution), select a
-Kaiser window.  Bartlett and Rectangular windows are also available.
+Dolph window.  Kaiser, Bartlett and Rectangular windows are also available.
 .IP \fB\-W\ \fInum\fR
 Window adjustment parameter.  This can be used to make small
-adjustments to the Kaiser window shape.  A positive number (up to
+adjustments to the Kaiser or Dolph window shape.  A positive number (up to
 ten) increases its dynamic range, a negative number decreases it.
 .IP \fB\-s\fR
 Allow slack overlapping of DFT windows.
--- a/src/effects_i_dsp.c
+++ b/src/effects_i_dsp.c
@@ -341,6 +341,18 @@
   }
 }
 
+void lsx_apply_dolph(double h[], const int N, double att)
+{
+  double b = cosh(acosh(pow(10., att / 20)) / (N - 1)), sum, t, v, c, norm = 0;
+  int i, j;
+  for (c = 1 - 1 / (b * b), i = (N - 1) / 2; i >= 0; --i) {
+    for (sum = !i, b=v=t=j=1; j <= i && sum != t; b = b * (i - j) * (1./j), ++j)
+      t = sum, sum += b * (v *= c * (N - i - j) * (1./j));
+    sum /= (N - 1 - i), sum /= (norm = norm? norm : sum);
+    h[i] *= sum, h[N - 1 - i] *= sum;
+  }
+}
+
 double * lsx_make_lpf(int num_taps, double Fc, double beta, double rho,
     double scale, sox_bool dc_norm)
 {
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -102,6 +102,7 @@
 void lsx_apply_blackman_nutall(double h[], const int num_points);
 double lsx_kaiser_beta(double att, double tr_bw);
 void lsx_apply_kaiser(double h[], const int num_points, double beta);
+void lsx_apply_dolph(double h[], const int num_points, double att);
 double * lsx_make_lpf(int num_taps, double Fc, double beta, double rho,
     double scale, sox_bool dc_norm);
 void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps);
--- a/src/spectrogram.c
+++ b/src/spectrogram.c
@@ -41,7 +41,7 @@
 
 #define MAX_X_SIZE 200000
 
-typedef enum {Window_Hann, Window_Hamming, Window_Bartlett, Window_Rectangular, Window_Kaiser} win_type_t;
+typedef enum {Window_Hann, Window_Hamming, Window_Bartlett, Window_Rectangular, Window_Kaiser, Window_Dolph} win_type_t;
 static lsx_enum_item const window_options[] = {
   LSX_ENUM_ITEM(Window_,Hann)
   LSX_ENUM_ITEM(Window_,Hamming)
@@ -48,6 +48,7 @@
   LSX_ENUM_ITEM(Window_,Bartlett)
   LSX_ENUM_ITEM(Window_,Rectangular)
   LSX_ENUM_ITEM(Window_,Kaiser)
+  LSX_ENUM_ITEM(Window_,Dolph)
   {0, 0}};
 
 typedef struct {
@@ -178,8 +179,10 @@
     case Window_Hamming: lsx_apply_hamming(w, n); break;
     case Window_Bartlett: lsx_apply_bartlett(w, n); break;
     case Window_Rectangular: break;
-    default: lsx_apply_kaiser(w, n, lsx_kaiser_beta(
-        (p->dB_range + p->gain) * (1.1 + p->window_adjust / 50), .1));
+    case Window_Kaiser: lsx_apply_kaiser(w, n, lsx_kaiser_beta(
+        (p->dB_range + p->gain) * (1.1 + p->window_adjust / 50), .1)); break;
+    default: lsx_apply_dolph(w, n,
+        (p->dB_range + p->gain) * (1.005 + p->window_adjust / 50) + 6);
   }
   for (i = 0; i < p->dft_size; ++i) sum += p->window[i];
   for (i = 0; i < p->dft_size; ++i) p->window[i] *= 2 / sum
@@ -673,8 +676,8 @@
     "\t-z num\tZ-axis range in dB; default 120",
     "\t-Z num\tZ-axis maximum in dBFS; default 0",
     "\t-q num\tZ-axis quantisation (0 - 249); default 249",
-    "\t-w name\tWindow: Hann (default), Hamming, Bartlett, Rectangular, Kaiser",
-    "\t-W num\tWindow adjust parameter (-10 - 10); applies only to Kaiser",
+    "\t-w name\tWindow: Hann(default)/Hamming/Bartlett/Rectangular/Kaiser/Dolph",
+    "\t-W num\tWindow adjust parameter (-10 - 10); applies only to Kaiser/Dolph",
     "\t-s\tSlack overlap of windows",
     "\t-a\tSuppress axis lines",
     "\t-r\tRaw spectrogram; no axes or legends",