Version 1.0.2b RELEASED.
[ahxm.git] / ss_eff.c
blobd7a0aefb4b00f2b33899e38ecb5e4d4409871687
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2005 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 "annhell.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)
73 e->wave = ss_alloc_wave((int) size, 1, ss_frequency);
75 e->gain = gain;
76 e->func = func;
78 return(e);
82 static void ss_eff_set_lfo(struct ss_eff * e, double freq,
83 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)
114 /* filter */
115 s = e->func(e, s);
117 /* increment cursor */
118 if(e->wave != NULL)
120 if(++e->cursor >= e->wave->size)
121 e->cursor = 0;
124 /* move to next */
125 e = e->next;
128 return(s);
133 * ss_eff_off - Destroys a chain of digital effects
134 * @ec: the effect chain
136 * Destroys a chain of digital effects.
138 void ss_eff_off(struct ss_eff ** ec)
140 while(*ec != NULL)
142 struct ss_eff * e = (*ec)->next;
144 /* free the buffer, if any */
145 if((*ec)->wave != NULL)
146 ss_free_wave((*ec)->wave);
148 /* free the effect itself */
149 free(*ec);
151 /* move to next */
152 *ec = e;
157 /* effects */
159 static sample_t * eff_cursor_ptr(struct ss_eff * e)
160 /* returns a pointer to the current sample */
162 sample_t * wave = e->wave->wave[0];
163 return(wave + (int) e->cursor);
167 /* delay */
169 static sample_t func_delay(struct ss_eff * e, sample_t input)
171 sample_t * p;
172 sample_t s;
174 p = eff_cursor_ptr(e);
175 s = *p;
176 *p = input;
178 return(s);
183 * ss_eff_delay - Adds a delay effect.
184 * @ec: the effect chain
185 * @size: delay in milliseconds
187 * Adds a delay effect. On output, this effect will simply
188 * delay the output of the samples fed to it in @size
189 * frames. No further filtering is done.
191 void ss_eff_delay(struct ss_eff ** ec, double size)
193 ss_eff_add(ec, size, 0, func_delay);
197 /* echo */
199 static sample_t func_echo(struct ss_eff * e, sample_t input)
201 sample_t * p;
202 sample_t s;
204 p = eff_cursor_ptr(e);
205 s = *p * e->gain;
206 *p = input;
208 return(input + s);
213 * ss_eff_echo - Adds an echo effect.
214 * @ec: the effect chain
215 * @size: delay in milliseconds
216 * @gain: echo gain
218 * Adds an echo effect. Outputs the current sample mixed
219 * with the product of the sample sent @size frames ago
220 * multiplied by the specified @gain.
222 void ss_eff_echo(struct ss_eff ** ec, double size, sample_t gain)
224 ss_eff_add(ec, size, gain, func_echo);
228 /* comb */
230 static sample_t func_comb(struct ss_eff * e, sample_t input)
232 sample_t * p;
233 sample_t s;
235 p = eff_cursor_ptr(e);
236 s = *p;
237 *p = input + (s * e->gain);
239 return(input + s);
244 * effect_comb - Adds a comb filter.
245 * @ec: the effect chain
246 * @size: delay in milliseconds
247 * @gain: filter gain
249 * Adds a comb filter, being @size the number of samples to
250 * delay and @gain the feedback output. Comb filters are
251 * used in reverbs.
253 void ss_eff_comb(struct ss_eff ** ec, double size, sample_t gain)
255 ss_eff_add(ec, size, gain, func_comb);
259 /* allpass */
261 static sample_t func_allpass(struct ss_eff * e, sample_t input)
263 sample_t * p;
264 sample_t s, t, u;
266 p = eff_cursor_ptr(e);
267 t = *p;
269 u = input + (t * e->gain);
270 s = t - (e->gain * u);
272 *p = u;
274 return(s);
279 * ss_eff_allpass - Adds an allpass filter.
280 * @ec: the effect chain
281 * @size: delay in milliseconds
282 * @gain: filter gain
284 * Adds an allpass filter, being @size the number of samples to
285 * delay and @gain the feedback output. Allpass filters are
286 * used in reverbs.
288 void ss_eff_allpass(struct ss_eff ** ec, double size, sample_t gain)
290 ss_eff_add(ec, size, gain, func_allpass);
294 /* flanger */
296 static sample_t func_flanger(struct ss_eff * e, sample_t input)
298 double c;
299 sample_t s;
300 sample_t * p;
302 c = e->cursor - e->lfo_depth - (e->lfo_depth * ss_eff_lfo(e));
304 s = ss_get_sample(e->wave, 0, c) * e->gain;
306 p = eff_cursor_ptr(e);
307 *p = input;
309 return(input + s);
315 * ss_eff_flanger: Adds a flanger effect.
316 * @ec: the effect chain
317 * @size: delay in milliseconds
318 * @gain: output gain
319 * @depth: flanger depth in milliseconds
320 * @freq: LFO frequency [0..1]
321 * @phase: initial phase [0..1]
323 * Adds a flanger effect, being @size the number of samples
324 * to delay, @gain the output gain, @depth the number of samples
325 * the output will be 'flanged' (bigger values mean bigger
326 * fluctuations in the final frequency), @freq the frequency of
327 * the LFO in Hz and @phase the initial LFO value as a
328 * fractional part of a period, being 0 the start of the period,
329 * 0.5 half a period and so on. The LFO is sinusoidal.
331 void ss_eff_flanger(struct ss_eff ** ec, double size, sample_t gain,
332 double depth, double freq, double phase)
334 struct ss_eff * e;
336 e = ss_eff_add(ec, size, gain, func_flanger);
337 ss_eff_set_lfo(e, freq, phase, depth);
341 /* wobble */
343 static sample_t func_wobble(struct ss_eff * e, sample_t input)
345 sample_t s;
347 s = input * ss_eff_lfo(e);
349 return(s);
354 * effect_wobble - Adds a wobble effect.
355 * @ec: the effect chain
356 * @freq: frequency [0..1]
357 * @phase: initial phase [0..1]
359 * Adds a wobble effect, where the sample amplitudes are
360 * multiplied by an LFO, so sound volume wobbles from full
361 * volume to silence twice a period. @freq is the LFO frequency
362 * in Hz and @phase the initial LFO value as a
363 * fractional part of a period, being 0 the start of the period,
364 * 0.5 half a period and so on. The LFO is sinusoidal.
366 void ss_eff_wobble(struct ss_eff ** ec, double freq, double phase)
368 struct ss_eff * e;
370 e = ss_eff_add(ec, 0, 0, func_wobble);
371 ss_eff_set_lfo(e, freq, phase, 0);
375 /* square wave wobble */
377 static sample_t func_square_wobble(struct ss_eff * e, sample_t input)
379 return(ss_eff_lfo(e) > 0 ? input : 0);
384 * ss_eff_square_wobble - Adds a square wave wobble effect.
385 * @ec: the effect chain
386 * @freq: frequency [0..1]
387 * @phase: initial phase [0..1]
389 * Adds an effect like the wobble one (see documentation for
390 * effect_wobble()), but using a square wave, meaning that input
391 * goes unfiltered (full amplitude) for half the period and
392 * complete silence the other half.
394 void ss_eff_square_wobble(struct ss_eff ** ec, double freq, double phase)
396 struct ss_eff * e;
398 e = ss_eff_add(ec, 0, 0, func_square_wobble);
399 ss_eff_set_lfo(e, freq, phase, 0);
403 /* fader */
405 static sample_t func_fader(struct ss_eff * e, sample_t input)
407 sample_t s;
409 s = input * e->gain;
410 e->gain += e->igain;
412 if(e->cursor == e->wave->size - 1)
413 e->igain = 0;
415 return(s);
420 * ss_eff_fader - Adds a fader effect.
421 * @ec: the effect chain
422 * @size: number of milliseconds the fader will last
423 * @initial: initial volume
424 * @final: final volume
426 * Adds a fader effect. The effect will fade in or out the input
427 * volume from @initial to @final during @size samples.
429 void ss_eff_fader(struct ss_eff ** ec, double size, sample_t initial, sample_t final)
431 struct ss_eff * e;
433 e = ss_eff_add(ec, size, initial, func_fader);
435 e->igain = (final - initial) / (sample_t) MS2F(size);
440 * ss_eff_reverb - Adds a simple reverb effect.
441 * @ec: the effect chain
443 * Adds a simple reverb effect, using a chain of allpass filters.
445 void ss_eff_reverb(struct ss_eff ** ec)
447 ss_eff_allpass(ec, 20.0, 0.9);
448 ss_eff_allpass(ec, 36.0, 0.9);
449 ss_eff_allpass(ec, 39.0, 0.9);