1 /* libSoX effect: Hilbert transform filter
3 * First version of this effect written 11/2011 by Ulrich Klauer, using maths
4 * from "Understanding digital signal processing" by Richard G. Lyons.
6 * Copyright 2011 Chris Bagwell and SoX Contributors
8 * This library is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or (at
11 * your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
16 * General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "dft_filter.h"
27 dft_filter_priv_t base
;
32 static int getopts(sox_effect_t
*effp
, int argc
, char **argv
)
34 lsx_getopt_t optstate
;
36 priv_t
*p
= (priv_t
*)effp
->priv
;
37 dft_filter_priv_t
*b
= &p
->base
;
39 b
->filter_ptr
= &b
->filter
;
41 lsx_getopt_init(argc
, argv
, "+n:", NULL
, lsx_getopt_flag_none
, 1, &optstate
);
43 while ((c
= lsx_getopt(&optstate
)) != -1) switch (c
) {
44 GETOPT_NUMERIC(optstate
, 'n', taps
, 3, 32767)
45 default: lsx_fail("invalid option `-%c'", optstate
.opt
); return lsx_usage(effp
);
47 if (p
->taps
&& p
->taps
%2 == 0) {
48 lsx_fail("only filters with an odd number of taps are supported");
51 return optstate
.ind
!= argc
? lsx_usage(effp
) : SOX_SUCCESS
;
54 static int start(sox_effect_t
*effp
)
56 priv_t
*p
= (priv_t
*)effp
->priv
;
57 dft_filter_t
*f
= p
->base
.filter_ptr
;
62 p
->taps
= effp
->in_signal
.rate
/76.5 + 2;
63 p
->taps
+= 1 - (p
->taps
%2);
64 /* results in a cutoff frequency of about 75 Hz with a Blackman window */
65 lsx_debug("choosing number of taps = %d (override with -n)", p
->taps
);
67 lsx_valloc(p
->h
, p
->taps
);
68 for (i
= 0; i
< p
->taps
; i
++) {
69 int k
= -(p
->taps
/2) + i
;
74 p
->h
[i
] = (1 - cos(pk
))/pk
;
77 lsx_apply_blackman(p
->h
, p
->taps
, .16);
79 if (effp
->global_info
->plot
!= sox_plot_off
) {
81 sprintf(title
, "SoX effect: hilbert (%d taps)", p
->taps
);
82 lsx_plot_fir(p
->h
, p
->taps
, effp
->in_signal
.rate
,
83 effp
->global_info
->plot
, title
, -20., 5.);
87 lsx_set_dft_filter(f
, p
->h
, p
->taps
, p
->taps
/2);
89 return lsx_dft_filter_effect_fn()->start(effp
);
92 sox_effect_handler_t
const *lsx_hilbert_effect_fn(void)
94 static sox_effect_handler_t handler
;
95 handler
= *lsx_dft_filter_effect_fn();
96 handler
.name
= "hilbert";
97 handler
.usage
= "[-n taps]";
98 handler
.getopts
= getopts
;
99 handler
.start
= start
;
100 handler
.priv_size
= sizeof(priv_t
);