Each volume was being applied to all the accumulated frame samples
[ahxm.git] / ss_eff.c
blobac7fe7e4af460a4be1cf5c215c01bf3a5646a5e8
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 "ss_core.h"
34 #include "ss_eff.h"
36 /*******************
37 Data
38 ********************/
40 /*******************
41 Code
42 ********************/
44 struct ss_eff * ss_eff_add(struct ss_eff ** ec, double size,
45 float gain, float (* func)(struct ss_eff *, float))
46 /* adds an effect to the ec chain */
48 struct ss_eff * e;
50 /* convert to frames */
51 size=MS2F(size);
53 /* create new structure and reset */
54 if((e=malloc(sizeof(struct ss_eff))) == NULL)
55 return(NULL);
57 memset(e, '\0', sizeof(struct ss_eff));
59 /* enqueue */
60 if(*ec == NULL)
61 *ec=e;
62 else
64 struct ss_eff * t;
66 /* loop to add e to the end */
67 for(t=*ec;t->next != NULL;t=t->next);
69 t->next=e;
72 /* add buffer */
73 if(size > 0)
75 e->wave=(float *) malloc(((int) size) * sizeof(float));
76 memset(e->wave, '\0', ((int) size) * sizeof(float));
79 e->size=size;
80 e->gain=gain;
81 e->func=func;
83 return(e);
87 void ss_eff_set_lfo(struct ss_eff * e, double freq, double phase, double depth)
88 /* sets an alfo */
90 e->lfo=phase * 6.28;
91 e->lfo_inc=(freq * 6.28) / (double) ss_frequency;
92 e->lfo_depth=MS2F(depth);
96 double ss_eff_lfo(struct ss_eff * e)
97 /* processes an lfo */
99 double r=sin(e->lfo);
100 e->lfo += e->lfo_inc;
102 return(r);
107 * ss_eff_process - Processes a chain of digital effects
108 * @e: the effect chain
109 * @s: input sample
111 * Processes a chain of digital effects, taking each one as input
112 * the output of the previous one.
114 float ss_eff_process(struct ss_eff * e, float s)
116 while(e != NULL)
118 /* filter */
119 s=e->func(e, s);
121 /* increment cursor */
122 if(++e->cursor >= e->size)
123 e->cursor=0;
125 /* move to next */
126 e=e->next;
129 return(s);
134 * ss_eff_off - Destroys a chain of digital effects
135 * @ec: the effect chain
137 * Destroys a chain of digital effects.
139 void ss_eff_off(struct ss_eff ** ec)
141 while(*ec != NULL)
143 struct ss_eff * e=(*ec)->next;
145 /* free the buffer, if any */
146 if((*ec)->wave != NULL)
147 free((*ec)->wave);
149 /* free the effect itself */
150 free(*ec);
152 /* move to next */
153 *ec=e;
158 /* effects */
160 /* delay */
162 static float func_delay(struct ss_eff * e, float input)
164 float s;
166 s=e->wave[(int) e->cursor];
167 e->wave[(int) e->cursor]=input;
169 return(s);
174 * ss_eff_delay - Adds a delay effect.
175 * @ec: the effect chain
176 * @size: delay in milliseconds
178 * Adds a delay effect. On output, this effect will simply
179 * delay the output of the samples fed to it in @size
180 * frames. No further filtering is done.
182 void ss_eff_delay(struct ss_eff ** ec, double size)
184 ss_eff_add(ec, size, 0, func_delay);
188 /* echo */
190 static float func_echo(struct ss_eff * e, float input)
192 float s;
194 s=e->wave[(int) e->cursor] * e->gain;
195 e->wave[(int) e->cursor]=input;
197 return(input + s);
202 * ss_eff_echo - Adds an echo effect.
203 * @ec: the effect chain
204 * @size: delay in milliseconds
205 * @gain: echo gain
207 * Adds an echo effect. Outputs the current sample mixed
208 * with the product of the sample sent @size frames ago
209 * multiplied by the specified @gain.
211 void ss_eff_echo(struct ss_eff ** ec, double size, float gain)
213 ss_eff_add(ec, size, gain, func_echo);
217 /* comb */
219 static float func_comb(struct ss_eff * e, float input)
221 float s;
223 s=e->wave[(int) e->cursor];
224 e->wave[(int) e->cursor]=input + (s * e->gain);
226 return(input + s);
231 * effect_comb - Adds a comb filter.
232 * @ec: the effect chain
233 * @size: delay in milliseconds
234 * @gain: filter gain
236 * Adds a comb filter, being @size the number of samples to
237 * delay and @gain the feedback output. Comb filters are
238 * used in reverbs.
240 void ss_eff_comb(struct ss_eff ** ec, double size, float gain)
242 ss_eff_add(ec, size, gain, func_comb);
246 /* allpass */
248 static float func_allpass(struct ss_eff * e, float input)
250 float s, t, u;
252 t=e->wave[(int)e->cursor];
254 u=input + (t * e->gain);
255 s=t - (e->gain * u);
257 e->wave[(int) e->cursor]=u;
259 return(s);
264 * ss_eff_allpass - Adds an allpass filter.
265 * @ec: the effect chain
266 * @size: delay in milliseconds
267 * @gain: filter gain
269 * Adds an allpass filter, being @size the number of samples to
270 * delay and @gain the feedback output. Allpass filters are
271 * used in reverbs.
273 void ss_eff_allpass(struct ss_eff ** ec, double size, float gain)
275 ss_eff_add(ec, size, gain, func_allpass);
279 /* flanger */
281 static float func_flanger(struct ss_eff * e, float input)
283 double c;
284 float s;
286 c=e->cursor - e->lfo_depth - (e->lfo_depth * ss_eff_lfo(e));
288 s=ss_get_sample(e->wave, e->size, c) * e->gain;
290 e->wave[(int) e->cursor]=input;
292 return(input + s);
298 * ss_eff_flanger: Adds a flanger effect.
299 * @ec: the effect chain
300 * @size: delay in milliseconds
301 * @gain: output gain
302 * @depth: flanger depth in milliseconds
303 * @freq: LFO frequency [0..1]
304 * @phase: initial phase [0..1]
306 * Adds a flanger effect, being @size the number of samples
307 * to delay, @gain the output gain, @depth the number of samples
308 * the output will be 'flanged' (bigger values mean bigger
309 * fluctuations in the final frequency), @freq the frequency of
310 * the LFO in Hz and @phase the initial LFO value as a
311 * fractional part of a period, being 0 the start of the period,
312 * 0.5 half a period and so on. The LFO is sinusoidal.
314 void ss_eff_flanger(struct ss_eff ** ec, double size, float gain,
315 double depth, double freq, double phase)
317 struct ss_eff * e;
319 e=ss_eff_add(ec, size, gain, func_flanger);
320 ss_eff_set_lfo(e, freq, phase, depth);
324 /* wobble */
326 static float func_wobble(struct ss_eff * e, float input)
328 float s;
330 s=input * ss_eff_lfo(e);
332 return(s);
337 * effect_wobble - Adds a wobble effect.
338 * @ec: the effect chain
339 * @freq: frequency [0..1]
340 * @phase: initial phase [0..1]
342 * Adds a wobble effect, where the sample amplitudes are
343 * multiplied by an LFO, so sound volume wobbles from full
344 * volume to silence twice a period. @freq is the LFO frequency
345 * in Hz and @phase the initial LFO value as a
346 * fractional part of a period, being 0 the start of the period,
347 * 0.5 half a period and so on. The LFO is sinusoidal.
349 void ss_eff_wobble(struct ss_eff ** ec, double freq, double phase)
351 struct ss_eff * e;
353 e=ss_eff_add(ec, 0, 0, func_wobble);
354 ss_eff_set_lfo(e, freq, phase, 0);
358 /* square wave wobble */
360 static float func_square_wobble(struct ss_eff * e, float input)
362 return(ss_eff_lfo(e) > 0 ? input : 0);
367 * ss_eff_square_wobble - Adds a square wave wobble effect.
368 * @ec: the effect chain
369 * @freq: frequency [0..1]
370 * @phase: initial phase [0..1]
372 * Adds an effect like the wobble one (see documentation for
373 * effect_wobble()), but using a square wave, meaning that input
374 * goes unfiltered (full amplitude) for half the period and
375 * complete silence the other half.
377 void ss_eff_square_wobble(struct ss_eff ** ec, double freq, double phase)
379 struct ss_eff * e;
381 e=ss_eff_add(ec, 0, 0, func_square_wobble);
382 ss_eff_set_lfo(e, freq, phase, 0);
386 /* fader */
388 static float func_fader(struct ss_eff * e, float input)
390 float s;
392 s=input * e->gain;
394 if(e->size)
396 e->size--;
397 e->gain += e->igain;
400 return(s);
405 * ss_eff_fader - Adds a fader effect.
406 * @ec: the effect chain
407 * @size: number of milliseconds the fader will last
408 * @initial: initial volume
409 * @final: final volume
411 * Adds a fader effect. The effect will fade in or out the input
412 * volume from @initial to @final during @size samples.
414 void ss_eff_fader(struct ss_eff ** ec, double size, float initial, float final)
416 struct ss_eff * e;
418 e=ss_eff_add(ec, size, initial, func_fader);
420 e->igain=(final - initial) / (float) MS2F(size);
425 * ss_eff_reverb - Adds a simple reverb effect.
426 * @ec: the effect chain
428 * Adds a simple reverb effect, using a chain of allpass filters.
430 void ss_eff_reverb(struct ss_eff ** ec)
432 ss_eff_allpass(ec, 20.0, 0.9);
433 ss_eff_allpass(ec, 36.0, 0.9);
434 ss_eff_allpass(ec, 39.0, 0.9);