Tweaked CFLAGS detection in config.sh.
[ahxm.git] / ss_eff.c
blobdf5da0392894c5c7cc340cbf68a44b57639738b4
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2008 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"
36 /** helping functions **/
38 static struct ss_eff *ss_eff_add(struct ss_eff **ec, double size,
39 sample_t gain,
40 sample_t(*func) (struct ss_eff *,
41 sample_t))
42 /* adds an effect to the ec chain */
44 struct ss_eff *e;
46 /* convert to frames */
47 size = MS2F(size);
49 /* create new structure and reset */
50 if ((e = malloc(sizeof(struct ss_eff))) == NULL)
51 return NULL;
53 memset(e, '\0', sizeof(struct ss_eff));
55 /* enqueue */
56 if (*ec == NULL)
57 *ec = e;
58 else {
59 struct ss_eff *t;
61 /* loop to add e to the end */
62 for (t = *ec; t->next != NULL; t = t->next);
64 t->next = e;
67 /* add buffer */
68 if (size > 0) {
69 e->wave = ss_alloc_wave((int) size, 1, ss_frequency, -1);
70 ss_prepare_wave(e->wave);
73 e->gain = gain;
74 e->func = func;
76 return e;
80 static void ss_eff_set_lfo(struct ss_eff *e, double freq, double phase,
81 double depth)
82 /* sets an alfo */
84 e->lfo = phase * 6.28;
85 e->lfo_inc = (freq * 6.28) / (double) ss_frequency;
86 e->lfo_depth = MS2F(depth);
90 static double ss_eff_lfo(struct ss_eff *e)
91 /* processes an lfo */
93 double r = sin(e->lfo);
94 e->lfo += e->lfo_inc;
96 return r;
101 * ss_eff_process - Processes a chain of digital effects
102 * @e: the effect chain
103 * @s: input sample
105 * Processes a chain of digital effects, taking each one as input
106 * the output of the previous one.
108 sample_t ss_eff_process(struct ss_eff * e, sample_t s)
110 while (e != NULL) {
111 /* filter */
112 s = e->func(e, s);
114 /* increment cursor */
115 if (e->wave != NULL) {
116 if (++e->cursor >= e->wave->size)
117 e->cursor = 0;
120 /* move to next */
121 e = e->next;
124 return s;
129 * ss_eff_off - Destroys a chain of digital effects
130 * @ec: the effect chain
132 * Destroys a chain of digital effects.
134 void ss_eff_off(struct ss_eff **ec)
136 while (*ec != NULL) {
137 struct ss_eff *e = (*ec)->next;
139 /* free the buffer, if any */
140 if ((*ec)->wave != NULL)
141 ss_free_wave((*ec)->wave);
143 /* free the effect itself */
144 free(*ec);
146 /* move to next */
147 *ec = e;
152 static sample_t *eff_cursor_ptr(struct ss_eff *e)
153 /* returns a pointer to the current sample */
155 sample_t *wave = e->wave->wave[0];
156 return wave + (int) e->cursor;
160 /** Effect: delay **/
162 static sample_t func_delay(struct ss_eff *e, sample_t input)
164 sample_t *p;
165 sample_t s;
167 p = eff_cursor_ptr(e);
168 s = *p;
169 *p = input;
171 return s;
176 * ss_eff_delay - Adds a delay effect.
177 * @ec: the effect chain
178 * @size: delay in milliseconds
180 * Adds a delay effect. On output, this effect will simply
181 * delay the output of the samples fed to it in @size
182 * frames. No further filtering is done.
184 void ss_eff_delay(struct ss_eff **ec, double size)
186 ss_eff_add(ec, size, 0, func_delay);
190 /** Effect: echo **/
192 static sample_t func_echo(struct ss_eff *e, sample_t input)
194 sample_t *p;
195 sample_t s;
197 p = eff_cursor_ptr(e);
198 s = *p * e->gain;
199 *p = input;
201 return input + s;
206 * ss_eff_echo - Adds an echo effect.
207 * @ec: the effect chain
208 * @size: delay in milliseconds
209 * @gain: echo gain
211 * Adds an echo effect. Outputs the current sample mixed
212 * with the product of the sample sent @size frames ago
213 * multiplied by the specified @gain.
215 void ss_eff_echo(struct ss_eff **ec, double size, sample_t gain)
217 ss_eff_add(ec, size, gain, func_echo);
221 /** Effect: comb **/
223 static sample_t func_comb(struct ss_eff *e, sample_t input)
225 sample_t *p;
226 sample_t s;
228 p = eff_cursor_ptr(e);
229 s = *p;
230 *p = input + (s * e->gain);
232 return input + s;
237 * ss_effect_comb - Adds a comb filter.
238 * @ec: the effect chain
239 * @size: delay in milliseconds
240 * @gain: filter gain
242 * Adds a comb filter, being @size the number of samples to
243 * delay and @gain the feedback output. Comb filters are
244 * used in reverbs.
246 void ss_eff_comb(struct ss_eff **ec, double size, sample_t gain)
248 ss_eff_add(ec, size, gain, func_comb);
252 /** Effect: allpass **/
254 static sample_t func_allpass(struct ss_eff *e, sample_t input)
256 sample_t *p;
257 sample_t s, t, u;
259 p = eff_cursor_ptr(e);
260 t = *p;
262 u = input + (t * e->gain);
263 s = t - (e->gain * u);
265 *p = u;
267 return s;
272 * ss_eff_allpass - Adds an allpass filter.
273 * @ec: the effect chain
274 * @size: delay in milliseconds
275 * @gain: filter gain
277 * Adds an allpass filter, being @size the number of samples to
278 * delay and @gain the feedback output. Allpass filters are
279 * used in reverbs.
281 void ss_eff_allpass(struct ss_eff **ec, double size, sample_t gain)
283 ss_eff_add(ec, size, gain, func_allpass);
287 /** Effect: flanger **/
289 static sample_t func_flanger(struct ss_eff *e, sample_t input)
291 double c;
292 sample_t s;
293 sample_t *p;
295 c = e->cursor - e->lfo_depth - (e->lfo_depth * ss_eff_lfo(e));
297 s = ss_get_sample(e->wave, 0, c) * e->gain;
299 p = eff_cursor_ptr(e);
300 *p = input;
302 return input + s;
308 * ss_eff_flanger - Adds a flanger effect.
309 * @ec: the effect chain
310 * @size: delay in milliseconds
311 * @gain: output gain
312 * @depth: flanger depth in milliseconds
313 * @freq: LFO frequency [0..1]
314 * @phase: initial phase [0..1]
316 * Adds a flanger effect, being @size the number of samples
317 * to delay, @gain the output gain, @depth the number of samples
318 * the output will be 'flanged' (bigger values mean bigger
319 * fluctuations in the final frequency), @freq the frequency of
320 * the LFO in Hz and @phase the initial LFO value as a
321 * fractional part of a period, being 0 the start of the period,
322 * 0.5 half a period and so on. The LFO is sinusoidal.
324 void ss_eff_flanger(struct ss_eff **ec, double size, sample_t gain,
325 double depth, double freq, double phase)
327 struct ss_eff *e;
329 e = ss_eff_add(ec, size, gain, func_flanger);
330 ss_eff_set_lfo(e, freq, phase, depth);
334 /** Effect: wobble **/
336 static sample_t func_wobble(struct ss_eff *e, sample_t input)
338 sample_t s;
340 s = (input * fabs(ss_eff_lfo(e)) * e->gain) +
341 (input * (1.0 - e->gain));
343 return s;
348 * ss_effect_wobble - Adds a wobble effect.
349 * @ec: the effect chain
350 * @freq: frequency [0..1]
351 * @phase: initial phase [0..1]
352 * @gain: ammount of effect [0..1]
354 * Adds a wobble effect, where the sample amplitudes are
355 * multiplied by an LFO, so sound volume wobbles from full
356 * volume to silence twice a period. @freq is the LFO frequency
357 * in Hz and @phase the initial LFO value as a
358 * fractional part of a period, being 0 the start of the period,
359 * 0.5 half a period and so on. The LFO is sinusoidal.
361 void ss_eff_wobble(struct ss_eff **ec, double freq, double phase,
362 sample_t gain)
364 struct ss_eff *e;
366 e = ss_eff_add(ec, 0, gain, func_wobble);
367 ss_eff_set_lfo(e, freq, phase, 0);
371 /** Effect: square wave wobble **/
373 static sample_t func_square_wobble(struct ss_eff *e, sample_t input)
375 return ss_eff_lfo(e) > 0 ? input : 0;
380 * ss_eff_square_wobble - Adds a square wave wobble effect.
381 * @ec: the effect chain
382 * @freq: frequency [0..1]
383 * @phase: initial phase [0..1]
385 * Adds an effect like the wobble one (see documentation for
386 * effect_wobble()), but using a square wave, meaning that input
387 * goes unfiltered (full amplitude) for half the period and
388 * complete silence the other half.
390 void ss_eff_square_wobble(struct ss_eff **ec, double freq, double phase)
392 struct ss_eff *e;
394 e = ss_eff_add(ec, 0, 0, func_square_wobble);
395 ss_eff_set_lfo(e, freq, phase, 0);
399 /** Effect: half wobble **/
401 static sample_t func_half_wobble(struct ss_eff *e, sample_t input)
403 sample_t s;
405 s = ss_eff_lfo(e);
407 return s > 0.0 ? s * input : 0.0;
412 * ss_eff_half_wobble - Adds a half wave wobble effect.
413 * @ec: the effect chain
414 * @freq: frequency [0..1]
415 * @phase: initial phase [0..1]
417 * Adds an effect like the wobble one (see documentation for
418 * effect_wobble()), but returning only the first half of the
419 * full period as a wobble and the second as silence.
421 void ss_eff_half_wobble(struct ss_eff **ec, double freq, double phase)
423 struct ss_eff *e;
425 e = ss_eff_add(ec, 0, 0, func_half_wobble);
426 ss_eff_set_lfo(e, freq, phase, 0);
430 /** Effect: fader **/
432 static sample_t func_fader(struct ss_eff *e, sample_t input)
434 sample_t s;
436 s = input * e->gain;
437 e->gain += e->igain;
439 if (e->cursor == e->wave->size - 1)
440 e->igain = 0;
442 return s;
447 * ss_eff_fader - Adds a fader effect.
448 * @ec: the effect chain
449 * @size: number of milliseconds the fader will last
450 * @initial: initial volume
451 * @final: final volume
453 * Adds a fader effect. The effect will fade in or out the input
454 * volume from @initial to @final during @size samples.
456 void ss_eff_fader(struct ss_eff **ec, double size, sample_t initial,
457 sample_t final)
459 struct ss_eff *e;
461 e = ss_eff_add(ec, size, initial, func_fader);
463 e->igain = (final - initial) / (sample_t) MS2F(size);
467 /** Effect: reverb **/
470 * ss_eff_reverb - Adds a simple reverb effect.
471 * @ec: the effect chain
473 * Adds a simple reverb effect, using a chain of allpass filters.
475 void ss_eff_reverb(struct ss_eff **ec)
477 ss_eff_allpass(ec, 20.0, 0.9);
478 ss_eff_allpass(ec, 36.0, 0.9);
479 ss_eff_allpass(ec, 39.0, 0.9);
483 /** Effect: foldback distortion **/
485 static sample_t func_foldback(struct ss_eff *e, sample_t input)
487 sample_t s = input;
489 /* http://www.musicdsp.org/archive.php?classid=4#203 */
490 if (input > e->gain)
491 s = e->gain - (input - e->gain);
492 else
493 if (input < -e->gain)
494 s = -e->gain + (-e->gain - input);
496 return s;
501 * ss_eff_foldback - Adds a foldback distortion effect.
502 * @ec: the effect chain
503 * @threshold: threshold to apply the folding
505 * Adds a foldback distortion effect. All aplitudes above the
506 * threshold are folded back.
508 void ss_eff_foldback(struct ss_eff **ec, sample_t threshold)
510 ss_eff_add(ec, 0, threshold, func_foldback);
514 /** Effect: atan distortion **/
516 static sample_t func_atan(struct ss_eff *e, sample_t input)
518 sample_t s = input;
520 /* atan */
521 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=104 */
522 s = atan(s * e->gain) / e->gain;
524 return s;
529 * ss_eff_atan - Adds an 'atan' distortion effect.
530 * @ec: the effect chain
531 * @gain: amount of effect
533 * Adds an 'atan' distortion effect.
535 void ss_eff_atan(struct ss_eff **ec, sample_t gain)
537 ss_eff_add(ec, 0, gain, func_atan);
541 /** Effect: distort distortion **/
543 static sample_t func_distort(struct ss_eff *e, sample_t input)
545 sample_t s = input;
547 /* distort */
548 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=86 */
549 s = s - e->gain * s * s * s;
551 return s;
556 * ss_eff_distort - Adds a 'distort' distortion effect.
557 * @ec: the effect chain
558 * @gain: amount of effect
560 * Adds a 'distort' distortion effect.
562 void ss_eff_distort(struct ss_eff **ec, sample_t gain)
564 ss_eff_add(ec, 0, gain, func_distort);
568 /** Effect: overdrive distortion **/
570 static sample_t func_overdrive(struct ss_eff *e, sample_t input)
572 sample_t s = input;
574 /* overdrive */
575 /* http://www.musicdsp.org/archive.php?classid=4#41 */
576 s = s * (fabs(s) + e->gain) / (s * s + (e->gain - 1) * fabs(s) + 1);
578 return s;
583 * ss_eff_overdrive - Adds an 'overdrive' distortion effect.
584 * @ec: the effect chain
585 * @gain: amount of effect
587 * Adds an 'overdrive' distortion effect.
589 void ss_eff_overdrive(struct ss_eff **ec, sample_t gain)
591 ss_eff_add(ec, 0, gain, func_overdrive);