Added entries to TODO.
[ahxm.git] / effect.c
blobfe0ab6cd13897858c7700b0705eae37c01bea44a
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003 Angel Ortega <angel@triptico.com>
6 effect.c - Digital audio filters and effects
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
26 #include "config.h"
28 #include <stdlib.h>
29 #include <math.h>
31 #include "core.h"
32 #include "effect.h"
34 /*******************
35 Data
36 ********************/
38 /*******************
39 Code
40 ********************/
42 static void _init_effect(struct effect * e, double size,
43 float (* func)(struct effect *, float))
45 if(size)
47 int n;
49 e->wave=(float *) malloc((int)size * sizeof(float));
51 for(n=0;n < (int)size;n++)
52 e->wave[n]=0;
54 else
55 e->wave=NULL;
57 e->size=size;
58 e->func=func;
60 e->cursor=0;
64 static void _set_effect_lfo(struct effect * e, double freq, double phase)
66 e->lfo=phase * 6.28;
67 e->lfo_inc=(freq * 6.28) / (double) _frequency;
71 /**
72 * process_effect - Processes an effect.
73 * @e: the effect
74 * input: an input sample
76 * Processes an effect. @input is the input sample.
78 * Returns the filtered sample.
80 float process_effect(struct effect * e, float input)
82 float output;
84 if(e->func == NULL)
85 return(0);
87 output=e->func(e, input);
89 if(++e->cursor == e->size)
90 e->cursor=0;
92 return(output);
96 /**
97 * effect_off - Switches off an effect.
98 * @e: the effect
100 * Switches off an effect.
102 void effect_off(struct effect * e)
104 if(e->wave != NULL)
106 free(e->wave);
107 e->wave=NULL;
110 e->func=NULL;
114 /* effects */
116 /* delay */
118 static float _process_delay(struct effect * e, float input)
120 float s;
122 s=get_sample(e->wave, e->size, e->cursor);
123 e->wave[(int) e->cursor]=input;
125 return(s);
130 * effect_delay - Sets a delay effect.
131 * @e: the effect structure
132 * @size: delay in samples
134 * Sets a delay effect. On output, this effect will simply
135 * delay the output of the samples fed to it in @size
136 * frames. No further filtering is done.
138 int effect_delay(struct effect * e, double size)
140 if(size == 0)
141 return(0);
143 _init_effect(e, size, _process_delay);
144 return(1);
148 /* echo */
150 static float _process_echo(struct effect * e, float input)
152 float s;
154 s=get_sample(e->wave, e->size, e->cursor) * e->gain;
155 e->wave[(int) e->cursor]=input;
157 return(input + s);
162 * effect_echo - Sets an echo effect.
163 * @e: the effect structure
164 * @size: delay in sample
165 * @gain: echo gain
167 * Sets an echo effect. Outputs the current sample mixed
168 * with the product of the sample sent @size frames ago
169 * multiplied by the specified @gain.
171 int effect_echo(struct effect * e, double size, float gain)
173 if(size == 0)
174 return(0);
176 _init_effect(e, size, _process_echo);
177 e->gain=gain;
179 return(1);
183 /* comb */
185 static float _process_comb(struct effect * e, float input)
187 float s;
189 s=get_sample(e->wave, e->size, e->cursor);
190 e->wave[(int) e->cursor]=input + (s * e->gain);
192 return(input + s);
197 * effect_comb - Sets a comb filter.
198 * @e: the effect structure
199 * @size: delay in samples
200 * @gain: filter gain
202 * Sets a comb filter, being @size the number of samples to
203 * delay and @gain the feedback output. Comb filters are
204 * used in reverbs.
206 int effect_comb(struct effect * e, double size, float gain)
208 if(size == 0)
209 return(0);
211 _init_effect(e, size, _process_comb);
212 e->gain=gain;
214 return(1);
218 static float _process_allpass(struct effect * e, float input)
220 float s,t;
222 if(e->wave == NULL) return(0);
224 t=get_sample(e->wave, e->size, e->cursor);
225 e->wave[(int) e->cursor]=input + (t * e->gain);
226 s=t - (e->gain * e->wave[(int) e->cursor]);
228 return(s);
233 * effect_allpass - Sets an allpass filter.
234 * @e: the effect structure
235 * @size: delay in samples
236 * @gain: filter gain
238 * Sets an allpass filter, being @size the number of samples to
239 * delay and @gain the feedback output. Allpass filters are
240 * used in reverbs.
242 int effect_allpass(struct effect * e, double size, float gain)
244 if(size == 0)
245 return(0);
247 _init_effect(e, size, _process_allpass);
248 e->gain=gain;
250 return(1);
254 /* flanger */
256 static float _process_flanger(struct effect * e, float input)
258 double c;
259 float s;
261 c=e->cursor - e->lfo_depth - (e->lfo_depth * sin(e->lfo));
262 e->lfo += e->lfo_inc;
263 if(c < 0) c += e->size;
265 s=get_sample(e->wave, e->size, c) * e->gain;
267 e->wave[(int) e->cursor]=input;
269 return(input + s);
275 * effect_flanger: Sets a flanger effect.
276 * @e: the effect structure
277 * @size: delay in samples
278 * @gain: output gain
279 * @depth: flanger depth
280 * @freq: LFO frequency in Hz
281 * @phase: initial phase
283 * Sets a flanger effect, being @size the number of samples
284 * to delay, @gain the output gain, @depth the number of samples
285 * the output will be 'flanged' (bigger values mean bigger
286 * fluctuations in the final frequency), @freq the frequency of
287 * the LFO in Hz and @phase the initial LFO value as a
288 * fractional part of a period, being 0 the start of the period,
289 * 0.5 half a period and so on. The LFO is sinusoidal.
291 int effect_flanger(struct effect * e, double size, float gain,
292 double depth, double freq, double phase)
294 if(size == 0)
295 return(0);
297 _init_effect(e, size, _process_flanger);
299 e->gain=gain;
300 e->lfo_depth=depth;
302 _set_effect_lfo(e, freq, phase);
304 return(1);
308 /* wobble */
310 static float _process_wobble(struct effect * e, float input)
312 float s;
314 s=input * sin(e->lfo);
315 e->lfo += e->lfo_inc;
317 return(s);
322 * effect_wobble - Sets a wobble effect.
323 * @e: the effect structure
324 * @freq: frequency in Hz
325 * @phase: initial phase
327 * Sets a wobble effect, where the sample amplitudes are
328 * multiplied by an LFO, so sound volume wobbles from full
329 * volume to silence twice a period. @freq is the LFO frequency
330 * in Hz and @phase the initial LFO value as a
331 * fractional part of a period, being 0 the start of the period,
332 * 0.5 half a period and so on. The LFO is sinusoidal.
334 int effect_wobble(struct effect * e, double freq, double phase)
336 _init_effect(e, 0, _process_wobble);
337 _set_effect_lfo(e, freq, phase);
339 return(1);
343 /* square wave wobble */
345 static float _process_square_wobble(struct effect * e, float input)
347 float s;
349 s=sin(e->lfo) > 0 ? input : 0;
350 e->lfo += e->lfo_inc;
352 return(s);
357 * effect_square_wobble - Sets a square wave wobble effect.
358 * @e: the effect structure
359 * @freq: frequency in Hz
360 * @phase: initial phase
362 * Sets an effect like the wobble one (see documentation for
363 * effect_wobble()), but using a square wave, meaning that input
364 * goes unfiltered (full amplitude) for half the period and
365 * complete silence the other half.
367 int effect_square_wobble(struct effect * e, double freq, double phase)
369 _init_effect(e, 0, _process_square_wobble);
370 _set_effect_lfo(e, freq, phase);
372 return(1);
376 /* fader */
378 static float _process_fader(struct effect * e, float input)
380 float s;
382 s=input * e->gain;
384 if(e->size)
386 e->size--;
387 e->gain += e->igain;
390 return(s);
395 * effect_fader - Sets a fader effect.
396 * @e: the effect structure
397 * @size: number of samples the fader will last
398 * @initial: initial volume
399 * @final: final volume
401 * Sets a fader effect. The effect will fade in or out the input
402 * volume from @initial to @final during @size samples.
404 int effect_fader(struct effect * e, double size, float initial, float final)
406 _init_effect(e, 0, _process_fader);
408 /* size is used as the number of samples,
409 though this effect has no buffer */
410 e->size=size;
412 e->gain=initial;
413 e->igain=(final - initial) / (float) size;
415 return(1);