1 /* libSoX effect: Overdrive (c) 2008 robs@users.sourceforge.net
2 *
3 * This library is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation; either version 2.1 of the License, or (at
6 * your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #include "sox_i.h"
19
20 typedef struct {
21 double gain, colour, last_in, last_out, b0, b1, a1;
22 } priv_t;
23
create(sox_effect_t * effp,int argc,char ** argv)24 static int create(sox_effect_t * effp, int argc, char * * argv)
25 {
26 priv_t * p = (priv_t *)effp->priv;
27 --argc, ++argv;
28 p->gain = p->colour = 20;
29 do {
30 NUMERIC_PARAMETER(gain, 0, 100)
31 NUMERIC_PARAMETER(colour, 0, 100)
32 } while (0);
33 p->gain = dB_to_linear(p->gain);
34 p->colour /= 200;
35 return argc? lsx_usage(effp) : SOX_SUCCESS;
36 }
37
start(sox_effect_t * effp)38 static int start(sox_effect_t * effp)
39 {
40 priv_t * p = (priv_t *)effp->priv;
41
42 if (p->gain == 1)
43 return SOX_EFF_NULL;
44
45 return SOX_SUCCESS;
46 }
47
flow(sox_effect_t * effp,const sox_sample_t * ibuf,sox_sample_t * obuf,size_t * isamp,size_t * osamp)48 static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
49 sox_sample_t * obuf, size_t * isamp, size_t * osamp)
50 {
51 priv_t * p = (priv_t *)effp->priv;
52 size_t dummy = 0, len = *isamp = *osamp = min(*isamp, *osamp);
53 while (len--) {
54 SOX_SAMPLE_LOCALS;
55 double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, dummy), d0 = d;
56 d *= p->gain;
57 d += p->colour;
58 d = d < -1? -2./3 : d > 1? 2./3 : d - d * d * d * (1./3);
59 p->last_out = d - p->last_in + .995 * p->last_out;
60 p->last_in = d;
61 *obuf++ = SOX_FLOAT_64BIT_TO_SAMPLE(d0 * .5 + p->last_out * .75, dummy);
62 }
63 return SOX_SUCCESS;
64 }
65
lsx_overdrive_effect_fn(void)66 sox_effect_handler_t const * lsx_overdrive_effect_fn(void)
67 {
68 static sox_effect_handler_t handler = {"overdrive", "[gain [colour]]",
69 SOX_EFF_GAIN, create, start, flow, NULL, NULL, NULL, sizeof(priv_t)};
70 return &handler;
71 }
72