Changed year in copyright notices.
[ahxm.git] / ss_eff.c
blobf0e9a1df4454baa8ab17caa062eb46f5b57372e1
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2007 Angel Ortega <angel@triptico.com>
6 ss_eff.c - Software syntesizer's digital 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 <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <math.h>
33 #include "ahxm.h"
35 /*******************
36 Data
37 ********************/
39 /*******************
40 Code
41 ********************/
43 static struct ss_eff * ss_eff_add(struct ss_eff ** ec, double size,
44 sample_t gain, sample_t (* func)(struct ss_eff *, sample_t))
45 /* adds an effect to the ec chain */
47 struct ss_eff * e;
49 /* convert to frames */
50 size = MS2F(size);
52 /* create new structure and reset */
53 if((e = malloc(sizeof(struct ss_eff))) == NULL)
54 return(NULL);
56 memset(e, '\0', sizeof(struct ss_eff));
58 /* enqueue */
59 if(*ec == NULL)
60 *ec = e;
61 else
63 struct ss_eff * t;
65 /* loop to add e to the end */
66 for(t = *ec;t->next != NULL;t = t->next);
68 t->next = e;
71 /* add buffer */
72 if(size > 0)
74 e->wave = ss_alloc_wave((int) size, 1, ss_frequency, -1);
75 ss_prepare_wave(e->wave);
78 e->gain = gain;
79 e->func = func;
81 return(e);
85 static void ss_eff_set_lfo(struct ss_eff * e, double freq,
86 double phase, double depth)
87 /* sets an alfo */
89 e->lfo = phase * 6.28;
90 e->lfo_inc = (freq * 6.28) / (double) ss_frequency;
91 e->lfo_depth = MS2F(depth);
95 static double ss_eff_lfo(struct ss_eff * e)
96 /* processes an lfo */
98 double r = sin(e->lfo);
99 e->lfo += e->lfo_inc;
101 return(r);
106 * ss_eff_process - Processes a chain of digital effects
107 * @e: the effect chain
108 * @s: input sample
110 * Processes a chain of digital effects, taking each one as input
111 * the output of the previous one.
113 sample_t ss_eff_process(struct ss_eff * e, sample_t s)
115 while(e != NULL)
117 /* filter */
118 s = e->func(e, s);
120 /* increment cursor */
121 if(e->wave != NULL)
123 if(++e->cursor >= e->wave->size)
124 e->cursor = 0;
127 /* move to next */
128 e = e->next;
131 return(s);
136 * ss_eff_off - Destroys a chain of digital effects
137 * @ec: the effect chain
139 * Destroys a chain of digital effects.
141 void ss_eff_off(struct ss_eff ** ec)
143 while(*ec != NULL)
145 struct ss_eff * e = (*ec)->next;
147 /* free the buffer, if any */
148 if((*ec)->wave != NULL)
149 ss_free_wave((*ec)->wave);
151 /* free the effect itself */
152 free(*ec);
154 /* move to next */
155 *ec = e;
160 /* effects */
162 static sample_t * eff_cursor_ptr(struct ss_eff * e)
163 /* returns a pointer to the current sample */
165 sample_t * wave = e->wave->wave[0];
166 return(wave + (int) e->cursor);
170 /* delay */
172 static sample_t func_delay(struct ss_eff * e, sample_t input)
174 sample_t * p;
175 sample_t s;
177 p = eff_cursor_ptr(e);
178 s = *p;
179 *p = input;
181 return(s);
186 * ss_eff_delay - Adds a delay effect.
187 * @ec: the effect chain
188 * @size: delay in milliseconds
190 * Adds a delay effect. On output, this effect will simply
191 * delay the output of the samples fed to it in @size
192 * frames. No further filtering is done.
194 void ss_eff_delay(struct ss_eff ** ec, double size)
196 ss_eff_add(ec, size, 0, func_delay);
200 /* echo */
202 static sample_t func_echo(struct ss_eff * e, sample_t input)
204 sample_t * p;
205 sample_t s;
207 p = eff_cursor_ptr(e);
208 s = *p * e->gain;
209 *p = input;
211 return(input + s);
216 * ss_eff_echo - Adds an echo effect.
217 * @ec: the effect chain
218 * @size: delay in milliseconds
219 * @gain: echo gain
221 * Adds an echo effect. Outputs the current sample mixed
222 * with the product of the sample sent @size frames ago
223 * multiplied by the specified @gain.
225 void ss_eff_echo(struct ss_eff ** ec, double size, sample_t gain)
227 ss_eff_add(ec, size, gain, func_echo);
231 /* comb */
233 static sample_t func_comb(struct ss_eff * e, sample_t input)
235 sample_t * p;
236 sample_t s;
238 p = eff_cursor_ptr(e);
239 s = *p;
240 *p = input + (s * e->gain);
242 return(input + s);
247 * ss_effect_comb - Adds a comb filter.
248 * @ec: the effect chain
249 * @size: delay in milliseconds
250 * @gain: filter gain
252 * Adds a comb filter, being @size the number of samples to
253 * delay and @gain the feedback output. Comb filters are
254 * used in reverbs.
256 void ss_eff_comb(struct ss_eff ** ec, double size, sample_t gain)
258 ss_eff_add(ec, size, gain, func_comb);
262 /* allpass */
264 static sample_t func_allpass(struct ss_eff * e, sample_t input)
266 sample_t * p;
267 sample_t s, t, u;
269 p = eff_cursor_ptr(e);
270 t = *p;
272 u = input + (t * e->gain);
273 s = t - (e->gain * u);
275 *p = u;
277 return(s);
282 * ss_eff_allpass - Adds an allpass filter.
283 * @ec: the effect chain
284 * @size: delay in milliseconds
285 * @gain: filter gain
287 * Adds an allpass filter, being @size the number of samples to
288 * delay and @gain the feedback output. Allpass filters are
289 * used in reverbs.
291 void ss_eff_allpass(struct ss_eff ** ec, double size, sample_t gain)
293 ss_eff_add(ec, size, gain, func_allpass);
297 /* flanger */
299 static sample_t func_flanger(struct ss_eff * e, sample_t input)
301 double c;
302 sample_t s;
303 sample_t * p;
305 c = e->cursor - e->lfo_depth - (e->lfo_depth * ss_eff_lfo(e));
307 s = ss_get_sample(e->wave, 0, c) * e->gain;
309 p = eff_cursor_ptr(e);
310 *p = input;
312 return(input + s);
318 * ss_eff_flanger - Adds a flanger effect.
319 * @ec: the effect chain
320 * @size: delay in milliseconds
321 * @gain: output gain
322 * @depth: flanger depth in milliseconds
323 * @freq: LFO frequency [0..1]
324 * @phase: initial phase [0..1]
326 * Adds a flanger effect, being @size the number of samples
327 * to delay, @gain the output gain, @depth the number of samples
328 * the output will be 'flanged' (bigger values mean bigger
329 * fluctuations in the final frequency), @freq the frequency of
330 * the LFO 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 void ss_eff_flanger(struct ss_eff ** ec, double size, sample_t gain,
335 double depth, double freq, double phase)
337 struct ss_eff * e;
339 e = ss_eff_add(ec, size, gain, func_flanger);
340 ss_eff_set_lfo(e, freq, phase, depth);
344 /* wobble */
346 static sample_t func_wobble(struct ss_eff * e, sample_t input)
348 sample_t s;
350 s = (input * fabs(ss_eff_lfo(e)) * e->gain) +
351 (input * (1.0 - e->gain));
353 return(s);
358 * ss_effect_wobble - Adds a wobble effect.
359 * @ec: the effect chain
360 * @freq: frequency [0..1]
361 * @phase: initial phase [0..1]
362 * @gain: ammount of effect [0..1]
364 * Adds a wobble effect, where the sample amplitudes are
365 * multiplied by an LFO, so sound volume wobbles from full
366 * volume to silence twice a period. @freq is the LFO frequency
367 * in Hz and @phase the initial LFO value as a
368 * fractional part of a period, being 0 the start of the period,
369 * 0.5 half a period and so on. The LFO is sinusoidal.
371 void ss_eff_wobble(struct ss_eff ** ec, double freq, double phase, sample_t gain)
373 struct ss_eff * e;
375 e = ss_eff_add(ec, 0, gain, func_wobble);
376 ss_eff_set_lfo(e, freq, phase, 0);
380 /* square wave wobble */
382 static sample_t func_square_wobble(struct ss_eff * e, sample_t input)
384 return(ss_eff_lfo(e) > 0 ? input : 0);
389 * ss_eff_square_wobble - Adds a square wave wobble effect.
390 * @ec: the effect chain
391 * @freq: frequency [0..1]
392 * @phase: initial phase [0..1]
394 * Adds an effect like the wobble one (see documentation for
395 * effect_wobble()), but using a square wave, meaning that input
396 * goes unfiltered (full amplitude) for half the period and
397 * complete silence the other half.
399 void ss_eff_square_wobble(struct ss_eff ** ec, double freq, double phase)
401 struct ss_eff * e;
403 e = ss_eff_add(ec, 0, 0, func_square_wobble);
404 ss_eff_set_lfo(e, freq, phase, 0);
408 /* half wobble */
410 static sample_t func_half_wobble(struct ss_eff * e, sample_t input)
412 sample_t s;
414 s = ss_eff_lfo(e);
416 return(s > 0.0 ? s * input : 0.0);
421 * ss_eff_half_wobble - Adds a half wave wobble effect.
422 * @ec: the effect chain
423 * @freq: frequency [0..1]
424 * @phase: initial phase [0..1]
426 * Adds an effect like the wobble one (see documentation for
427 * effect_wobble()), but returning only the first half of the
428 * full period as a wobble and the second as silence.
430 void ss_eff_half_wobble(struct ss_eff ** ec, double freq, double phase)
432 struct ss_eff * e;
434 e = ss_eff_add(ec, 0, 0, func_half_wobble);
435 ss_eff_set_lfo(e, freq, phase, 0);
439 /* fader */
441 static sample_t func_fader(struct ss_eff * e, sample_t input)
443 sample_t s;
445 s = input * e->gain;
446 e->gain += e->igain;
448 if(e->cursor == e->wave->size - 1)
449 e->igain = 0;
451 return(s);
456 * ss_eff_fader - Adds a fader effect.
457 * @ec: the effect chain
458 * @size: number of milliseconds the fader will last
459 * @initial: initial volume
460 * @final: final volume
462 * Adds a fader effect. The effect will fade in or out the input
463 * volume from @initial to @final during @size samples.
465 void ss_eff_fader(struct ss_eff ** ec, double size, sample_t initial, sample_t final)
467 struct ss_eff * e;
469 e = ss_eff_add(ec, size, initial, func_fader);
471 e->igain = (final - initial) / (sample_t) MS2F(size);
476 * ss_eff_reverb - Adds a simple reverb effect.
477 * @ec: the effect chain
479 * Adds a simple reverb effect, using a chain of allpass filters.
481 void ss_eff_reverb(struct ss_eff ** ec)
483 ss_eff_allpass(ec, 20.0, 0.9);
484 ss_eff_allpass(ec, 36.0, 0.9);
485 ss_eff_allpass(ec, 39.0, 0.9);
489 /* foldback distortion */
491 static sample_t func_foldback(struct ss_eff * e, sample_t input)
493 sample_t s = input;
495 /* http://www.musicdsp.org/archive.php?classid=4#203 */
496 if(input > e->gain)
497 s = e->gain - (input - e->gain);
498 else
499 if(input < -e->gain)
500 s = -e->gain + (-e->gain - input);
502 return(s);
507 * ss_eff_foldback - Adds a foldback distortion effect.
508 * @ec: the effect chain
509 * @threshold: threshold to apply the folding
511 * Adds a foldback distortion effect. All aplitudes above the
512 * threshold are folded back.
514 void ss_eff_foldback(struct ss_eff ** ec, sample_t threshold)
516 ss_eff_add(ec, 0, threshold, func_foldback);
520 /* atan distortion */
522 static sample_t func_atan(struct ss_eff * e, sample_t input)
524 sample_t s = input;
526 /* atan */
527 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=104 */
528 s = atan(s * e->gain) / e->gain;
530 return(s);
535 * ss_eff_atan - Adds an 'atan' distortion effect.
536 * @ec: the effect chain
537 * @gain: amount of effect
539 * Adds an 'atan' distortion effect.
541 void ss_eff_atan(struct ss_eff ** ec, sample_t gain)
543 ss_eff_add(ec, 0, gain, func_atan);
547 /* distort distortion */
549 static sample_t func_distort(struct ss_eff * e, sample_t input)
551 sample_t s = input;
553 /* distort */
554 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=86 */
555 s = s - e->gain * s * s * s;
557 return(s);
562 * ss_eff_distort - Adds a 'distort' distortion effect.
563 * @ec: the effect chain
564 * @gain: amount of effect
566 * Adds a 'distort' distortion effect.
568 void ss_eff_distort(struct ss_eff ** ec, sample_t gain)
570 ss_eff_add(ec, 0, gain, func_distort);
574 /* overdrive distortion */
576 static sample_t func_overdrive(struct ss_eff * e, sample_t input)
578 sample_t s = input;
580 /* overdrive */
581 /* http://www.musicdsp.org/archive.php?classid=4#41 */
582 s = s * (fabs(s) + e->gain) / (s * s + (e->gain - 1) * fabs(s) + 1);
584 return(s);
589 * ss_eff_overdrive - Adds an 'overdrive' distortion effect.
590 * @ec: the effect chain
591 * @gain: amount of effect
593 * Adds an 'overdrive' distortion effect.
595 void ss_eff_overdrive(struct ss_eff ** ec, sample_t gain)
597 ss_eff_add(ec, 0, gain, func_overdrive);