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",