Use const in ss_output.c where possible.
[ahxm.git] / ss_eff.c
blob54272764f0d0b8661dbc1aa4a89a4e4a87deb8d6
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 {
62 struct ss_eff *t;
64 /* loop to add e to the end */
65 for (t = *ec; t->next != NULL; t = t->next);
67 t->next = e;
70 /* add buffer */
71 if (size > 0) {
72 e->wave = ss_alloc_wave((int) size, 1, ss_frequency, -1);
73 ss_prepare_wave(e->wave);
76 e->gain = gain;
77 e->func = func;
79 return e;
83 static void ss_eff_set_lfo(struct ss_eff *e, double freq, double phase, double depth)
84 /* sets an alfo */
86 e->lfo = phase * 6.28;
87 e->lfo_inc = (freq * 6.28) / (double) ss_frequency;
88 e->lfo_depth = MS2F(depth);
92 static double ss_eff_lfo(struct ss_eff *e)
93 /* processes an lfo */
95 double r = sin(e->lfo);
96 e->lfo += e->lfo_inc;
98 return r;
103 * ss_eff_process - Processes a chain of digital effects
104 * @e: the effect chain
105 * @s: input sample
107 * Processes a chain of digital effects, taking each one as input
108 * the output of the previous one.
110 sample_t ss_eff_process(struct ss_eff * e, sample_t s)
112 while (e != NULL) {
113 /* filter */
114 s = e->func(e, s);
116 /* increment cursor */
117 if (e->wave != NULL) {
118 if (++e->cursor >= e->wave->size)
119 e->cursor = 0;
122 /* move to next */
123 e = e->next;
126 return s;
131 * ss_eff_off - Destroys a chain of digital effects
132 * @ec: the effect chain
134 * Destroys a chain of digital effects.
136 void ss_eff_off(struct ss_eff **ec)
138 while (*ec != NULL) {
139 struct ss_eff *e = (*ec)->next;
141 /* free the buffer, if any */
142 if ((*ec)->wave != NULL)
143 ss_free_wave((*ec)->wave);
145 /* free the effect itself */
146 free(*ec);
148 /* move to next */
149 *ec = e;
154 /* effects */
156 static sample_t *eff_cursor_ptr(struct ss_eff *e)
157 /* returns a pointer to the current sample */
159 sample_t *wave = e->wave->wave[0];
160 return wave + (int) e->cursor;
164 /* delay */
166 static sample_t func_delay(struct ss_eff *e, sample_t input)
168 sample_t *p;
169 sample_t s;
171 p = eff_cursor_ptr(e);
172 s = *p;
173 *p = input;
175 return s;
180 * ss_eff_delay - Adds a delay effect.
181 * @ec: the effect chain
182 * @size: delay in milliseconds
184 * Adds a delay effect. On output, this effect will simply
185 * delay the output of the samples fed to it in @size
186 * frames. No further filtering is done.
188 void ss_eff_delay(struct ss_eff **ec, double size)
190 ss_eff_add(ec, size, 0, func_delay);
194 /* echo */
196 static sample_t func_echo(struct ss_eff *e, sample_t input)
198 sample_t *p;
199 sample_t s;
201 p = eff_cursor_ptr(e);
202 s = *p * e->gain;
203 *p = input;
205 return input + s;
210 * ss_eff_echo - Adds an echo effect.
211 * @ec: the effect chain
212 * @size: delay in milliseconds
213 * @gain: echo gain
215 * Adds an echo effect. Outputs the current sample mixed
216 * with the product of the sample sent @size frames ago
217 * multiplied by the specified @gain.
219 void ss_eff_echo(struct ss_eff **ec, double size, sample_t gain)
221 ss_eff_add(ec, size, gain, func_echo);
225 /* comb */
227 static sample_t func_comb(struct ss_eff *e, sample_t input)
229 sample_t *p;
230 sample_t s;
232 p = eff_cursor_ptr(e);
233 s = *p;
234 *p = input + (s * e->gain);
236 return input + s;
241 * ss_effect_comb - Adds a comb filter.
242 * @ec: the effect chain
243 * @size: delay in milliseconds
244 * @gain: filter gain
246 * Adds a comb filter, being @size the number of samples to
247 * delay and @gain the feedback output. Comb filters are
248 * used in reverbs.
250 void ss_eff_comb(struct ss_eff **ec, double size, sample_t gain)
252 ss_eff_add(ec, size, gain, func_comb);
256 /* allpass */
258 static sample_t func_allpass(struct ss_eff *e, sample_t input)
260 sample_t *p;
261 sample_t s, t, u;
263 p = eff_cursor_ptr(e);
264 t = *p;
266 u = input + (t * e->gain);
267 s = t - (e->gain * u);
269 *p = u;
271 return s;
276 * ss_eff_allpass - Adds an allpass filter.
277 * @ec: the effect chain
278 * @size: delay in milliseconds
279 * @gain: filter gain
281 * Adds an allpass filter, being @size the number of samples to
282 * delay and @gain the feedback output. Allpass filters are
283 * used in reverbs.
285 void ss_eff_allpass(struct ss_eff **ec, double size, sample_t gain)
287 ss_eff_add(ec, size, gain, func_allpass);
291 /* flanger */
293 static sample_t func_flanger(struct ss_eff *e, sample_t input)
295 double c;
296 sample_t s;
297 sample_t *p;
299 c = e->cursor - e->lfo_depth - (e->lfo_depth * ss_eff_lfo(e));
301 s = ss_get_sample(e->wave, 0, c) * e->gain;
303 p = eff_cursor_ptr(e);
304 *p = input;
306 return input + s;
312 * ss_eff_flanger - Adds a flanger effect.
313 * @ec: the effect chain
314 * @size: delay in milliseconds
315 * @gain: output gain
316 * @depth: flanger depth in milliseconds
317 * @freq: LFO frequency [0..1]
318 * @phase: initial phase [0..1]
320 * Adds a flanger effect, being @size the number of samples
321 * to delay, @gain the output gain, @depth the number of samples
322 * the output will be 'flanged' (bigger values mean bigger
323 * fluctuations in the final frequency), @freq the frequency of
324 * the LFO in Hz and @phase the initial LFO value as a
325 * fractional part of a period, being 0 the start of the period,
326 * 0.5 half a period and so on. The LFO is sinusoidal.
328 void ss_eff_flanger(struct ss_eff **ec, double size, sample_t gain,
329 double depth, double freq, double phase)
331 struct ss_eff *e;
333 e = ss_eff_add(ec, size, gain, func_flanger);
334 ss_eff_set_lfo(e, freq, phase, depth);
338 /* wobble */
340 static sample_t func_wobble(struct ss_eff *e, sample_t input)
342 sample_t s;
344 s = (input * fabs(ss_eff_lfo(e)) * e->gain) + (input * (1.0 - e->gain));
346 return s;
351 * ss_effect_wobble - Adds a wobble effect.
352 * @ec: the effect chain
353 * @freq: frequency [0..1]
354 * @phase: initial phase [0..1]
355 * @gain: ammount of effect [0..1]
357 * Adds a wobble effect, where the sample amplitudes are
358 * multiplied by an LFO, so sound volume wobbles from full
359 * volume to silence twice a period. @freq is the LFO frequency
360 * in Hz and @phase the initial LFO value as a
361 * fractional part of a period, being 0 the start of the period,
362 * 0.5 half a period and so on. The LFO is sinusoidal.
364 void ss_eff_wobble(struct ss_eff **ec, double freq, double phase, sample_t gain)
366 struct ss_eff *e;
368 e = ss_eff_add(ec, 0, gain, func_wobble);
369 ss_eff_set_lfo(e, freq, phase, 0);
373 /* square wave wobble */
375 static sample_t func_square_wobble(struct ss_eff *e, sample_t input)
377 return ss_eff_lfo(e) > 0 ? input : 0;
382 * ss_eff_square_wobble - Adds a square wave wobble effect.
383 * @ec: the effect chain
384 * @freq: frequency [0..1]
385 * @phase: initial phase [0..1]
387 * Adds an effect like the wobble one (see documentation for
388 * effect_wobble()), but using a square wave, meaning that input
389 * goes unfiltered (full amplitude) for half the period and
390 * complete silence the other half.
392 void ss_eff_square_wobble(struct ss_eff **ec, double freq, double phase)
394 struct ss_eff *e;
396 e = ss_eff_add(ec, 0, 0, func_square_wobble);
397 ss_eff_set_lfo(e, freq, phase, 0);
401 /* half wobble */
403 static sample_t func_half_wobble(struct ss_eff *e, sample_t input)
405 sample_t s;
407 s = ss_eff_lfo(e);
409 return s > 0.0 ? s * input : 0.0;
414 * ss_eff_half_wobble - Adds a half wave wobble effect.
415 * @ec: the effect chain
416 * @freq: frequency [0..1]
417 * @phase: initial phase [0..1]
419 * Adds an effect like the wobble one (see documentation for
420 * effect_wobble()), but returning only the first half of the
421 * full period as a wobble and the second as silence.
423 void ss_eff_half_wobble(struct ss_eff **ec, double freq, double phase)
425 struct ss_eff *e;
427 e = ss_eff_add(ec, 0, 0, func_half_wobble);
428 ss_eff_set_lfo(e, freq, phase, 0);
432 /* fader */
434 static sample_t func_fader(struct ss_eff *e, sample_t input)
436 sample_t s;
438 s = input * e->gain;
439 e->gain += e->igain;
441 if (e->cursor == e->wave->size - 1)
442 e->igain = 0;
444 return s;
449 * ss_eff_fader - Adds a fader effect.
450 * @ec: the effect chain
451 * @size: number of milliseconds the fader will last
452 * @initial: initial volume
453 * @final: final volume
455 * Adds a fader effect. The effect will fade in or out the input
456 * volume from @initial to @final during @size samples.
458 void ss_eff_fader(struct ss_eff **ec, double size, sample_t initial, sample_t final)
460 struct ss_eff *e;
462 e = ss_eff_add(ec, size, initial, func_fader);
464 e->igain = (final - initial) / (sample_t) MS2F(size);
469 * ss_eff_reverb - Adds a simple reverb effect.
470 * @ec: the effect chain
472 * Adds a simple reverb effect, using a chain of allpass filters.
474 void ss_eff_reverb(struct ss_eff **ec)
476 ss_eff_allpass(ec, 20.0, 0.9);
477 ss_eff_allpass(ec, 36.0, 0.9);
478 ss_eff_allpass(ec, 39.0, 0.9);
482 /* foldback distortion */
484 static sample_t func_foldback(struct ss_eff *e, sample_t input)
486 sample_t s = input;
488 /* http://www.musicdsp.org/archive.php?classid=4#203 */
489 if (input > e->gain)
490 s = e->gain - (input - e->gain);
491 else if (input < -e->gain)
492 s = -e->gain + (-e->gain - input);
494 return s;
499 * ss_eff_foldback - Adds a foldback distortion effect.
500 * @ec: the effect chain
501 * @threshold: threshold to apply the folding
503 * Adds a foldback distortion effect. All aplitudes above the
504 * threshold are folded back.
506 void ss_eff_foldback(struct ss_eff **ec, sample_t threshold)
508 ss_eff_add(ec, 0, threshold, func_foldback);
512 /* atan distortion */
514 static sample_t func_atan(struct ss_eff *e, sample_t input)
516 sample_t s = input;
518 /* atan */
519 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=104 */
520 s = atan(s * e->gain) / e->gain;
522 return s;
527 * ss_eff_atan - Adds an 'atan' distortion effect.
528 * @ec: the effect chain
529 * @gain: amount of effect
531 * Adds an 'atan' distortion effect.
533 void ss_eff_atan(struct ss_eff **ec, sample_t gain)
535 ss_eff_add(ec, 0, gain, func_atan);
539 /* distort distortion */
541 static sample_t func_distort(struct ss_eff *e, sample_t input)
543 sample_t s = input;
545 /* distort */
546 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=86 */
547 s = s - e->gain * s * s * s;
549 return s;
554 * ss_eff_distort - Adds a 'distort' distortion effect.
555 * @ec: the effect chain
556 * @gain: amount of effect
558 * Adds a 'distort' distortion effect.
560 void ss_eff_distort(struct ss_eff **ec, sample_t gain)
562 ss_eff_add(ec, 0, gain, func_distort);
566 /* overdrive distortion */
568 static sample_t func_overdrive(struct ss_eff *e, sample_t input)
570 sample_t s = input;
572 /* overdrive */
573 /* http://www.musicdsp.org/archive.php?classid=4#41 */
574 s = s * (fabs(s) + e->gain) / (s * s + (e->gain - 1) * fabs(s) + 1);
576 return s;
581 * ss_eff_overdrive - Adds an 'overdrive' distortion effect.
582 * @ec: the effect chain
583 * @gain: amount of effect
585 * Adds an 'overdrive' distortion effect.
587 void ss_eff_overdrive(struct ss_eff **ec, sample_t gain)
589 ss_eff_add(ec, 0, gain, func_overdrive);