Branch annhell-branch-paged MERGED.
[ahxm.git] / ss_eff.c
blobd63c3cd2f72cddc080e08f39d00d43105dfeafef
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)
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 * 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 * ss_eff_lfo(e);
352 return(s);
357 * effect_wobble - Adds a wobble effect.
358 * @ec: the effect chain
359 * @freq: frequency [0..1]
360 * @phase: initial phase [0..1]
362 * Adds a wobble effect, where the sample amplitudes are
363 * multiplied by an LFO, so sound volume wobbles from full
364 * volume to silence twice a period. @freq is the LFO frequency
365 * in Hz and @phase the initial LFO value as a
366 * fractional part of a period, being 0 the start of the period,
367 * 0.5 half a period and so on. The LFO is sinusoidal.
369 void ss_eff_wobble(struct ss_eff ** ec, double freq, double phase)
371 struct ss_eff * e;
373 e = ss_eff_add(ec, 0, 0, func_wobble);
374 ss_eff_set_lfo(e, freq, phase, 0);
378 /* square wave wobble */
380 static sample_t func_square_wobble(struct ss_eff * e, sample_t input)
382 return(ss_eff_lfo(e) > 0 ? input : 0);
387 * ss_eff_square_wobble - Adds a square wave wobble effect.
388 * @ec: the effect chain
389 * @freq: frequency [0..1]
390 * @phase: initial phase [0..1]
392 * Adds an effect like the wobble one (see documentation for
393 * effect_wobble()), but using a square wave, meaning that input
394 * goes unfiltered (full amplitude) for half the period and
395 * complete silence the other half.
397 void ss_eff_square_wobble(struct ss_eff ** ec, double freq, double phase)
399 struct ss_eff * e;
401 e = ss_eff_add(ec, 0, 0, func_square_wobble);
402 ss_eff_set_lfo(e, freq, phase, 0);
406 /* fader */
408 static sample_t func_fader(struct ss_eff * e, sample_t input)
410 sample_t s;
412 s = input * e->gain;
413 e->gain += e->igain;
415 if(e->cursor == e->wave->size - 1)
416 e->igain = 0;
418 return(s);
423 * ss_eff_fader - Adds a fader effect.
424 * @ec: the effect chain
425 * @size: number of milliseconds the fader will last
426 * @initial: initial volume
427 * @final: final volume
429 * Adds a fader effect. The effect will fade in or out the input
430 * volume from @initial to @final during @size samples.
432 void ss_eff_fader(struct ss_eff ** ec, double size, sample_t initial, sample_t final)
434 struct ss_eff * e;
436 e = ss_eff_add(ec, size, initial, func_fader);
438 e->igain = (final - initial) / (sample_t) MS2F(size);
443 * ss_eff_reverb - Adds a simple reverb effect.
444 * @ec: the effect chain
446 * Adds a simple reverb effect, using a chain of allpass filters.
448 void ss_eff_reverb(struct ss_eff ** ec)
450 ss_eff_allpass(ec, 20.0, 0.9);
451 ss_eff_allpass(ec, 36.0, 0.9);
452 ss_eff_allpass(ec, 39.0, 0.9);