3
* $Id: distortion.c,v 1.9 2001/11/19 10:04:50 richi Exp $
5
* Copyright (C) 2001 Alexander Ehlert
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#include <sys/types.h>
37
static int distortion_f(filter_t *n)
39
filter_pipe_t *in, *out;
41
filter_param_t *param, *preg_param, *fxg_param, *clip_param, *asym_param;
45
float pregain, pos_clip, neg_clip, asym, clip, sign, gain, fxgain;
47
in = filterport_get_pipe(filterportdb_get_port(filter_portdb(n), PORTNAME_IN));
48
out = filterport_get_pipe(filterportdb_get_port(filter_portdb(n), PORTNAME_OUT));
50
FILTER_ERROR_RETURN("no in/output connected");
52
preg_param = filterparamdb_get_param(filter_paramdb(n), "pregain");
54
fxg_param = filterparamdb_get_param(filter_paramdb(n), "fxgain");
56
clip_param = filterparamdb_get_param(filter_paramdb(n), "clip");
58
asym_param = filterparamdb_get_param(filter_paramdb(n), "asym");
60
param=filterparamdb_get_param(filter_paramdb(n), "mode");
62
pos_clip = asym + clip;
63
neg_clip = asym - clip;
65
gain = 1.0 / (1.0 + fxgain);
69
switch (filterparam_val_int(param))
87
asym = filterparam_val_float(asym_param);
88
clip = filterparam_val_float(clip_param);
90
pregain = filterparam_val_float(preg_param);
92
pos_clip = asym + clip;
93
neg_clip = asym - clip;
94
fxgain = filterparam_val_float(fxg_param);
95
gain = 1.0 / (1.0 + fxgain);
97
/* got an input buffer */
98
s = &sbuf_buf(buf)[0];
99
for(i=0; i < sbuf_size(buf); i++) {
101
sign = (w >= 0.0 ? 1.0 : -1.0);
105
w = (w > pos_clip ? pos_clip :
106
( w < neg_clip ? neg_clip : w));
111
sbuf_queue(out, buf);
113
switch (filterparam_val_int(param))
128
buf = sbuf_make_private(sbuf_get(in));
133
/* Here starts the full wave rectifier distortion */
137
asym = filterparam_val_float(asym_param);
138
clip = filterparam_val_float(clip_param);
140
pregain = filterparam_val_float(preg_param);
142
pos_clip = asym + clip;
143
neg_clip = asym - clip;
144
fxgain = filterparam_val_float(fxg_param);
145
gain = 1.0 / (1.0 + fxgain);
147
/* got an input buffer */
148
s = &sbuf_buf(buf)[0];
149
for(i=0; i < sbuf_size(buf); i++) {
152
w = (w > clip ? clip : w);
157
sbuf_queue(out, buf);
159
switch (filterparam_val_int(param))
174
buf = sbuf_make_private(sbuf_get(in));
179
/* Simple sinusoider */
185
pregain = filterparam_val_float(preg_param);
186
fxgain = filterparam_val_float(fxg_param);
187
clip = filterparam_val_float(clip_param);
188
asym = filterparam_val_float(asym_param);
190
pos_clip = asym + clip;
191
neg_clip = asym - clip;
194
if (pregain < M_PI*0.5)
195
fxgain *= 1.0/sinf(clip);
197
gain = 1.0 / (1.0 + fxgain);
199
/* got an input buffer */
200
s = &sbuf_buf(buf)[0];
201
for(i=0; i < sbuf_size(buf); i++) {
202
*s = gain * (*s + fxgain * sinf(*s * pregain));
205
else if (*s < neg_clip)
210
sbuf_queue(out, buf);
212
switch (filterparam_val_int(param))
227
buf = sbuf_make_private(sbuf_get(in));
231
sbuf_queue(out, buf);
233
FILTER_BEFORE_STOPCLEANUP;
234
FILTER_BEFORE_CLEANUP;
239
int distortion_register(plugin_t *p)
242
filter_paramdb_t *param;
244
if (!(f = filter_creat(NULL)))
248
filterportdb_add_port(filter_portdb(f), PORTNAME_IN,
249
FILTER_PORTTYPE_SAMPLE,
250
FILTER_PORTFLAG_INPUT,
251
FILTERPORT_DESCRIPTION, "audio stream in",
253
filterportdb_add_port(filter_portdb(f), PORTNAME_OUT,
254
FILTER_PORTTYPE_SAMPLE,
255
FILTER_PORTFLAG_OUTPUT,
256
FILTERPORT_DESCRIPTION, "audio stream out",
259
param = filter_paramdb(f);
260
filterparamdb_add_param_float(param, "pregain", FILTER_PARAMTYPE_FLOAT, 10.0,
261
FILTERPARAM_DESCRIPTION, "gain before distortion",
264
filterparamdb_add_param_float(param, "fxgain", FILTER_PARAMTYPE_FLOAT, 1.0,
265
FILTERPARAM_DESCRIPTION, "distortion effect gain",
268
filterparamdb_add_param_float(param, "clip", FILTER_PARAMTYPE_FLOAT, 0.8,
269
FILTERPARAM_DESCRIPTION, "clip range",
272
filterparamdb_add_param_float(param, "asym", FILTER_PARAMTYPE_FLOAT, 0.0,
273
FILTERPARAM_DESCRIPTION,
274
"midpoint for asymmetrical clipping",
277
filterparamdb_add_param_int(param,"mode",
278
FILTER_PARAMTYPE_INT, 0,
279
FILTERPARAM_DESCRIPTION,
280
"(0) halfwave/asymmetrical"
281
"(1) fullwave rectifier"
283
FILTERPARAM_GLADEXML,
284
"<?xml version=\"1.0\"?><GTK-Interface><widget>
285
<class>GtkOptionMenu</class>
287
<can_focus>True</can_focus>
288
<items>Half wave rectifier
291
<initial_choice>0</initial_choice>
292
</widget></GTK-Interface>",
296
plugin_set(p, PLUGIN_DESCRIPTION, "distortion effect");
297
plugin_set(p, PLUGIN_PIXMAP, "distortion.png");
298
plugin_set(p, PLUGIN_CATEGORY, "Effects");
299
plugin_set(p, PLUGIN_GUI_HELP_PATH, "Distortion");
301
return filter_register(f, p);