Added section marks to ss_eff.c.
[ahxm.git] / ss_eff.c
blob7dfd59aaa69bf257a28aae512463437f76907999
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, sample_t(*func) (struct ss_eff *, sample_t))
40 /* adds an effect to the ec chain */
42 struct ss_eff *e;
44 /* convert to frames */
45 size = MS2F(size);
47 /* create new structure and reset */
48 if ((e = malloc(sizeof(struct ss_eff))) == NULL)
49 return NULL;
51 memset(e, '\0', sizeof(struct ss_eff));
53 /* enqueue */
54 if (*ec == NULL)
55 *ec = e;
56 else {
57 struct ss_eff *t;
59 /* loop to add e to the end */
60 for (t = *ec; t->next != NULL; t = t->next);
62 t->next = e;
65 /* add buffer */
66 if (size > 0) {
67 e->wave = ss_alloc_wave((int) size, 1, ss_frequency, -1);
68 ss_prepare_wave(e->wave);
71 e->gain = gain;
72 e->func = func;
74 return e;
78 static void ss_eff_set_lfo(struct ss_eff *e, double freq, double phase, double depth)
79 /* sets an alfo */
81 e->lfo = phase * 6.28;
82 e->lfo_inc = (freq * 6.28) / (double) ss_frequency;
83 e->lfo_depth = MS2F(depth);
87 static double ss_eff_lfo(struct ss_eff *e)
88 /* processes an lfo */
90 double r = sin(e->lfo);
91 e->lfo += e->lfo_inc;
93 return r;
97 /**
98 * ss_eff_process - Processes a chain of digital effects
99 * @e: the effect chain
100 * @s: input sample
102 * Processes a chain of digital effects, taking each one as input
103 * the output of the previous one.
105 sample_t ss_eff_process(struct ss_eff * e, sample_t s)
107 while (e != NULL) {
108 /* filter */
109 s = e->func(e, s);
111 /* increment cursor */
112 if (e->wave != NULL) {
113 if (++e->cursor >= e->wave->size)
114 e->cursor = 0;
117 /* move to next */
118 e = e->next;
121 return s;
126 * ss_eff_off - Destroys a chain of digital effects
127 * @ec: the effect chain
129 * Destroys a chain of digital effects.
131 void ss_eff_off(struct ss_eff **ec)
133 while (*ec != NULL) {
134 struct ss_eff *e = (*ec)->next;
136 /* free the buffer, if any */
137 if ((*ec)->wave != NULL)
138 ss_free_wave((*ec)->wave);
140 /* free the effect itself */
141 free(*ec);
143 /* move to next */
144 *ec = e;
149 static sample_t *eff_cursor_ptr(struct ss_eff *e)
150 /* returns a pointer to the current sample */
152 sample_t *wave = e->wave->wave[0];
153 return wave + (int) e->cursor;
157 /** Effect: delay **/
159 static sample_t func_delay(struct ss_eff *e, sample_t input)
161 sample_t *p;
162 sample_t s;
164 p = eff_cursor_ptr(e);
165 s = *p;
166 *p = input;
168 return s;
173 * ss_eff_delay - Adds a delay effect.
174 * @ec: the effect chain
175 * @size: delay in milliseconds
177 * Adds a delay effect. On output, this effect will simply
178 * delay the output of the samples fed to it in @size
179 * frames. No further filtering is done.
181 void ss_eff_delay(struct ss_eff **ec, double size)
183 ss_eff_add(ec, size, 0, func_delay);
187 /** Effect: echo **/
189 static sample_t func_echo(struct ss_eff *e, sample_t input)
191 sample_t *p;
192 sample_t s;
194 p = eff_cursor_ptr(e);
195 s = *p * e->gain;
196 *p = input;
198 return input + s;
203 * ss_eff_echo - Adds an echo effect.
204 * @ec: the effect chain
205 * @size: delay in milliseconds
206 * @gain: echo gain
208 * Adds an echo effect. Outputs the current sample mixed
209 * with the product of the sample sent @size frames ago
210 * multiplied by the specified @gain.
212 void ss_eff_echo(struct ss_eff **ec, double size, sample_t gain)
214 ss_eff_add(ec, size, gain, func_echo);
218 /** Effect: comb **/
220 static sample_t func_comb(struct ss_eff *e, sample_t input)
222 sample_t *p;
223 sample_t s;
225 p = eff_cursor_ptr(e);
226 s = *p;
227 *p = input + (s * e->gain);
229 return input + s;
234 * ss_effect_comb - Adds a comb filter.
235 * @ec: the effect chain
236 * @size: delay in milliseconds
237 * @gain: filter gain
239 * Adds a comb filter, being @size the number of samples to
240 * delay and @gain the feedback output. Comb filters are
241 * used in reverbs.
243 void ss_eff_comb(struct ss_eff **ec, double size, sample_t gain)
245 ss_eff_add(ec, size, gain, func_comb);
249 /** Effect: allpass **/
251 static sample_t func_allpass(struct ss_eff *e, sample_t input)
253 sample_t *p;
254 sample_t s, t, u;
256 p = eff_cursor_ptr(e);
257 t = *p;
259 u = input + (t * e->gain);
260 s = t - (e->gain * u);
262 *p = u;
264 return s;
269 * ss_eff_allpass - Adds an allpass filter.
270 * @ec: the effect chain
271 * @size: delay in milliseconds
272 * @gain: filter gain
274 * Adds an allpass filter, being @size the number of samples to
275 * delay and @gain the feedback output. Allpass filters are
276 * used in reverbs.
278 void ss_eff_allpass(struct ss_eff **ec, double size, sample_t gain)
280 ss_eff_add(ec, size, gain, func_allpass);
284 /** Effect: flanger **/
286 static sample_t func_flanger(struct ss_eff *e, sample_t input)
288 double c;
289 sample_t s;
290 sample_t *p;
292 c = e->cursor - e->lfo_depth - (e->lfo_depth * ss_eff_lfo(e));
294 s = ss_get_sample(e->wave, 0, c) * e->gain;
296 p = eff_cursor_ptr(e);
297 *p = input;
299 return input + s;
305 * ss_eff_flanger - Adds a flanger effect.
306 * @ec: the effect chain
307 * @size: delay in milliseconds
308 * @gain: output gain
309 * @depth: flanger depth in milliseconds
310 * @freq: LFO frequency [0..1]
311 * @phase: initial phase [0..1]
313 * Adds a flanger effect, being @size the number of samples
314 * to delay, @gain the output gain, @depth the number of samples
315 * the output will be 'flanged' (bigger values mean bigger
316 * fluctuations in the final frequency), @freq the frequency of
317 * the LFO in Hz and @phase the initial LFO value as a
318 * fractional part of a period, being 0 the start of the period,
319 * 0.5 half a period and so on. The LFO is sinusoidal.
321 void ss_eff_flanger(struct ss_eff **ec, double size, sample_t gain,
322 double depth, double freq, double phase)
324 struct ss_eff *e;
326 e = ss_eff_add(ec, size, gain, func_flanger);
327 ss_eff_set_lfo(e, freq, phase, depth);
331 /** Effect: wobble **/
333 static sample_t func_wobble(struct ss_eff *e, sample_t input)
335 sample_t s;
337 s = (input * fabs(ss_eff_lfo(e)) * e->gain) + (input * (1.0 - e->gain));
339 return s;
344 * ss_effect_wobble - Adds a wobble effect.
345 * @ec: the effect chain
346 * @freq: frequency [0..1]
347 * @phase: initial phase [0..1]
348 * @gain: ammount of effect [0..1]
350 * Adds a wobble effect, where the sample amplitudes are
351 * multiplied by an LFO, so sound volume wobbles from full
352 * volume to silence twice a period. @freq is the LFO frequency
353 * in Hz and @phase the initial LFO value as a
354 * fractional part of a period, being 0 the start of the period,
355 * 0.5 half a period and so on. The LFO is sinusoidal.
357 void ss_eff_wobble(struct ss_eff **ec, double freq, double phase, sample_t gain)
359 struct ss_eff *e;
361 e = ss_eff_add(ec, 0, gain, func_wobble);
362 ss_eff_set_lfo(e, freq, phase, 0);
366 /** Effect: square wave wobble **/
368 static sample_t func_square_wobble(struct ss_eff *e, sample_t input)
370 return ss_eff_lfo(e) > 0 ? input : 0;
375 * ss_eff_square_wobble - Adds a square wave wobble effect.
376 * @ec: the effect chain
377 * @freq: frequency [0..1]
378 * @phase: initial phase [0..1]
380 * Adds an effect like the wobble one (see documentation for
381 * effect_wobble()), but using a square wave, meaning that input
382 * goes unfiltered (full amplitude) for half the period and
383 * complete silence the other half.
385 void ss_eff_square_wobble(struct ss_eff **ec, double freq, double phase)
387 struct ss_eff *e;
389 e = ss_eff_add(ec, 0, 0, func_square_wobble);
390 ss_eff_set_lfo(e, freq, phase, 0);
394 /** Effect: half wobble **/
396 static sample_t func_half_wobble(struct ss_eff *e, sample_t input)
398 sample_t s;
400 s = ss_eff_lfo(e);
402 return s > 0.0 ? s * input : 0.0;
407 * ss_eff_half_wobble - Adds a half wave wobble effect.
408 * @ec: the effect chain
409 * @freq: frequency [0..1]
410 * @phase: initial phase [0..1]
412 * Adds an effect like the wobble one (see documentation for
413 * effect_wobble()), but returning only the first half of the
414 * full period as a wobble and the second as silence.
416 void ss_eff_half_wobble(struct ss_eff **ec, double freq, double phase)
418 struct ss_eff *e;
420 e = ss_eff_add(ec, 0, 0, func_half_wobble);
421 ss_eff_set_lfo(e, freq, phase, 0);
425 /** Effect: fader **/
427 static sample_t func_fader(struct ss_eff *e, sample_t input)
429 sample_t s;
431 s = input * e->gain;
432 e->gain += e->igain;
434 if (e->cursor == e->wave->size - 1)
435 e->igain = 0;
437 return s;
442 * ss_eff_fader - Adds a fader effect.
443 * @ec: the effect chain
444 * @size: number of milliseconds the fader will last
445 * @initial: initial volume
446 * @final: final volume
448 * Adds a fader effect. The effect will fade in or out the input
449 * volume from @initial to @final during @size samples.
451 void ss_eff_fader(struct ss_eff **ec, double size, sample_t initial, sample_t final)
453 struct ss_eff *e;
455 e = ss_eff_add(ec, size, initial, func_fader);
457 e->igain = (final - initial) / (sample_t) MS2F(size);
461 /** Effect: reverb **/
464 * ss_eff_reverb - Adds a simple reverb effect.
465 * @ec: the effect chain
467 * Adds a simple reverb effect, using a chain of allpass filters.
469 void ss_eff_reverb(struct ss_eff **ec)
471 ss_eff_allpass(ec, 20.0, 0.9);
472 ss_eff_allpass(ec, 36.0, 0.9);
473 ss_eff_allpass(ec, 39.0, 0.9);
477 /** Effect: foldback distortion **/
479 static sample_t func_foldback(struct ss_eff *e, sample_t input)
481 sample_t s = input;
483 /* http://www.musicdsp.org/archive.php?classid=4#203 */
484 if (input > e->gain)
485 s = e->gain - (input - e->gain);
486 else if (input < -e->gain)
487 s = -e->gain + (-e->gain - input);
489 return s;
494 * ss_eff_foldback - Adds a foldback distortion effect.
495 * @ec: the effect chain
496 * @threshold: threshold to apply the folding
498 * Adds a foldback distortion effect. All aplitudes above the
499 * threshold are folded back.
501 void ss_eff_foldback(struct ss_eff **ec, sample_t threshold)
503 ss_eff_add(ec, 0, threshold, func_foldback);
507 /** Effect: atan distortion **/
509 static sample_t func_atan(struct ss_eff *e, sample_t input)
511 sample_t s = input;
513 /* atan */
514 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=104 */
515 s = atan(s * e->gain) / e->gain;
517 return s;
522 * ss_eff_atan - Adds an 'atan' distortion effect.
523 * @ec: the effect chain
524 * @gain: amount of effect
526 * Adds an 'atan' distortion effect.
528 void ss_eff_atan(struct ss_eff **ec, sample_t gain)
530 ss_eff_add(ec, 0, gain, func_atan);
534 /** Effect: distort distortion **/
536 static sample_t func_distort(struct ss_eff *e, sample_t input)
538 sample_t s = input;
540 /* distort */
541 /* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=86 */
542 s = s - e->gain * s * s * s;
544 return s;
549 * ss_eff_distort - Adds a 'distort' distortion effect.
550 * @ec: the effect chain
551 * @gain: amount of effect
553 * Adds a 'distort' distortion effect.
555 void ss_eff_distort(struct ss_eff **ec, sample_t gain)
557 ss_eff_add(ec, 0, gain, func_distort);
561 /** Effect: overdrive distortion **/
563 static sample_t func_overdrive(struct ss_eff *e, sample_t input)
565 sample_t s = input;
567 /* overdrive */
568 /* http://www.musicdsp.org/archive.php?classid=4#41 */
569 s = s * (fabs(s) + e->gain) / (s * s + (e->gain - 1) * fabs(s) + 1);
571 return s;
576 * ss_eff_overdrive - Adds an 'overdrive' distortion effect.
577 * @ec: the effect chain
578 * @gain: amount of effect
580 * Adds an 'overdrive' distortion effect.
582 void ss_eff_overdrive(struct ss_eff **ec, sample_t gain)
584 ss_eff_add(ec, 0, gain, func_overdrive);