The old CHANNEL_MAP event has been deleted from everywhere.
[ahxm.git] / ss_gen.c
blobbfa1ddda6eb4e9618eecb88457b64139611a211c
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2005 Angel Ortega <angel@triptico.com>
6 ss_gen.c - Software syntesizer's sound generators
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 <stdlib.h>
30 #include <string.h>
31 #include <math.h>
33 #include "ss_core.h"
34 #include "ss_gen.h"
36 /*******************
37 Data
38 ********************/
40 /* number of generators */
41 int _ss_gen_num=SS_GEN_NUM;
43 /* generator pool */
44 struct ss_gen * _ss_gen_pool=NULL;
46 /* free generator queue */
47 struct ss_gen * _ss_gen_free=NULL;
50 /*******************
51 Code
52 ********************/
54 static void ss_gen_enqueue(struct ss_gen ** q, struct ss_gen * g)
55 /* Enqueues a generator in a generator queue */
57 g->prev=NULL;
58 g->next=*q;
60 if(*q != NULL)
61 (*q)->prev=g;
63 *q=g;
67 static struct ss_gen * ss_gen_dequeue(struct ss_gen ** q, struct ss_gen * g)
68 /* Dequeues a generator from a generator queue */
70 if(g->prev != NULL)
71 g->prev->next=g->next;
72 else
73 *q=g->next;
75 if(g->next != NULL)
76 g->next->prev=g->prev;
78 return(g);
82 static struct ss_gen * ss_gen_pop(struct ss_gen ** q)
83 /* gets the first enqueued generator from q */
85 struct ss_gen * g=NULL;
87 if(*q != NULL)
88 g=ss_gen_dequeue(q, *q);
90 return(g);
94 /**
95 * ss_gen_alloc - Allocs and enqueues a generator
96 * @q: queue where the generator will be enqueued
98 * Allocs and enqueues a generator into the @q queue.
100 * The new generator is returned, or NULL if the
101 * generator pool is empty.
103 struct ss_gen * ss_gen_alloc(struct ss_gen ** q)
105 int n;
106 struct ss_gen * g;
108 /* first time allocation */
109 if(_ss_gen_pool == NULL)
111 _ss_gen_pool=(struct ss_gen *) malloc(_ss_gen_num *
112 sizeof(struct ss_gen));
114 memset(_ss_gen_pool, '\0',
115 _ss_gen_num * sizeof(struct ss_gen));
117 /* enqueue all into the free generator queue */
118 for(n=0;n < _ss_gen_num;n++)
119 ss_gen_enqueue(&_ss_gen_free, &_ss_gen_pool[n]);
122 if((g=ss_gen_pop(&_ss_gen_free)) != NULL)
123 ss_gen_enqueue(q, g);
125 return(g);
130 * ss_gen_free - Dequeues a generator and frees it
131 * @q: the queue holding the generator
132 * @g: the generator
134 * Dequeues a generator and sends it back to the generator pool.
136 void ss_gen_free(struct ss_gen ** q, struct ss_gen * g)
138 ss_gen_enqueue(&_ss_gen_free, ss_gen_dequeue(q, g));
143 * ss_gen_sustain - Sets sustain for a generator
144 * @g: the generator
145 * @sustain: sustain time in msecs
147 * Sets sustain for a generator, where @sustain is expressed
148 * in milliseconds.
150 void ss_gen_sustain(struct ss_gen * g, double sustain)
152 g->sustain=MS2F(sustain);
157 * ss_gen_vibrato - Sets vibrato for a generator
158 * @g: the generator
159 * @depth: vibrato depth in msecs
160 * @freq: vibrato frequency
162 * Sets vibrato for a generator, with a @depth expressed in
163 * milliseconds and a frequency @freq expressed in hzs.
165 void ss_gen_vibrato(struct ss_gen * g, double depth, double freq)
167 g->vib_depth=MS2F(depth);
168 g->vib_inc=( 6.28 * freq ) / (double)ss_frequency;
169 g->vibrato=0.0;
174 * ss_gen_play - Activates a generator.
175 * @g: generator
176 * @freq: frequency of the sound to be generated
177 * @vol: volume
178 * @note_id: note id
179 * @w: the wave
181 * Activates a generator, usually as a response for a 'note on'
182 * message from an upper level. The wave @w holds all the sample
183 * data (PCM data, base frequency, etc.), @freq is the desired
184 * frequency, @vol the volume and @note_id a positive, unique
185 * identifier for the note.
187 void ss_gen_play(struct ss_gen * g, double freq, float vol, int note_id,
188 struct ss_wave * w)
190 g->note_id=note_id;
191 g->vol=vol;
193 memcpy(&g->w, w, sizeof(struct ss_wave));
195 /* calculate increment */
196 g->inc=freq / w->base_freq;
197 g->inc *= (double) w->s_rate / (double) ss_frequency;
199 /* default sustain (short) */
200 ss_gen_sustain(g, 50.0);
202 /* default vibrato (none) */
203 ss_gen_vibrato(g, 0.0, 0.0);
205 /* no portamento by default */
206 g->portamento=0;
208 /* start from the beginning */
209 g->cursor=0;
211 /* TEST: vibrato */
212 /* good freq: 6 Hz */
213 /* good depth: 1/6 semitone */
214 #if 0
215 if(trk_id == 2)
217 g->vib_depth=30; /* 20 */
218 g->vib_inc=( 6.28 * 6.0 ) / (double)ss_frequency; /* 0.001 */
220 else
221 g->vib_inc=0.0;
222 #endif
227 * ss_gen_release - Releases a generator.
228 * @g: the generator
230 * Releases a generator, usually as a response for a 'note off'
231 * message from an upper level. The generator enters SS_GEN_RELEASED
232 * mode, which starts generating sustain data until it's over.
234 void ss_gen_release(struct ss_gen * g)
236 /* note needs not be tracked anymore */
237 g->note_id=-1;
239 /* calculates the delta volume */
240 g->dvol=g->vol / (float) g->sustain;
245 * ss_gen_frame - Generates a frame of samples.
246 * @g: the generator
247 * @frame: array where the output samples will be stored
249 * Generates a frame of samples from the @g generator, that will be stored
250 * in the @frame array.
252 * Returns non-zero if the generator is stopped and should be freed.
254 int ss_gen_frame(struct ss_gen * g, int n_channels, float frame[])
256 int n;
257 int to_free=0;
258 double v;
259 float l_frame[CHANNELS];
261 v=g->cursor;
263 /* process vibrato */
264 if(g->vib_inc)
266 g->vibrato += g->vib_inc;
267 v += sin(g->vibrato) * g->vib_depth;
270 /* add samples to frame */
271 for(n=0;n < g->w.n_channels;n++)
272 l_frame[n] = ss_get_sample(&g->w, n, v) * g->vol;
274 /* spread the frame into n_channels */
275 for(n=0;n < n_channels;n++)
276 frame[n] += l_frame[n % g->w.n_channels];
278 /* increment pointer */
279 g->cursor += g->inc;
281 /* test loop boundaries */
282 if(g->cursor > g->w.loop_end)
284 /* loop mode? */
285 if(g->w.loop_start < 0)
286 to_free=1;
287 else
288 g->cursor=g->w.loop_start;
291 /* process sustain */
292 if(g->note_id == -1)
294 g->vol -= g->dvol;
296 if(--g->sustain <= 0)
297 to_free=1;
300 /* process portamento */
301 g->inc += g->portamento;
303 return(to_free);
308 * ss_gen_portamento - Sets portamento for a generator.
309 * @g: the generator
310 * @portamento: portamento time
311 * @dest_inc: destination inc (frequency)
313 * Sets the portamento for a generator. @portamento is the
314 * number of frames the generator should move from its current
315 * cursor increment to @dest_inc. See generator_play() for an
316 * explanation of the value contained in @dest_inc.
318 * Returns -1 if the generator is not active, or 0 if the
319 * portamento was accepted.
321 * FIXME: The API for portamento will surely change.
323 int ss_gen_portamento(struct ss_gen * g, int portamento, double dest_inc)
326 g->portamento=portamento;
327 g->dest_inc=dest_inc;
328 g->dinc=((dest_inc - g->inc) / (double) portamento);
330 return(0);