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
40 /* number of generators */
41 int _ss_gen_num
=SS_GEN_NUM
;
44 struct ss_gen
* _ss_gen_pool
=NULL
;
46 /* free generator queue */
47 struct ss_gen
* _ss_gen_free
=NULL
;
54 static void ss_gen_enqueue(struct ss_gen
** q
, struct ss_gen
* g
)
55 /* Enqueues a generator in a generator queue */
67 static void ss_gen_dequeue(struct ss_gen
** q
, struct ss_gen
* g
)
68 /* Dequeues a generator from a generator queue */
71 g
->prev
->next
=g
->next
;
76 g
->next
->prev
=g
->prev
;
80 static struct ss_gen
* ss_gen_pop(struct ss_gen
** q
)
81 /* gets the first enqueued generator from q */
83 struct ss_gen
* g
=NULL
;
96 * ss_gen_alloc - Allocs and enqueues a generator
97 * @q: queue where the generator will be enqueued
99 * Allocs and enqueues a generator into the @q queue.
101 * The new generator is returned, or NULL if the
102 * generator pool is empty.
104 struct ss_gen
* ss_gen_alloc(struct ss_gen
** q
)
109 /* first time allocation */
110 if(_ss_gen_pool
== NULL
)
112 _ss_gen_pool
=(struct ss_gen
*) malloc(_ss_gen_num
*
113 sizeof(struct ss_gen
));
115 memset(_ss_gen_pool
, '\0',
116 _ss_gen_num
* sizeof(struct ss_gen
));
118 /* enqueue all into the free generator queue */
119 for(n
=0;n
< _ss_gen_num
;n
++)
120 ss_gen_enqueue(&_ss_gen_free
, &_ss_gen_pool
[n
]);
123 if((g
=ss_gen_pop(&_ss_gen_free
)) != NULL
)
124 ss_gen_enqueue(q
, g
);
131 * ss_gen_free - Dequeues a generator and frees it
132 * @q: the queue holding the generator
135 * Dequeues a generator and sends it back to the generator pool.
137 void ss_gen_free(struct ss_gen
** q
, struct ss_gen
* g
)
139 ss_gen_dequeue(q
, g
);
140 ss_gen_enqueue(&_ss_gen_free
, g
);
145 * ss_gen_sustain - Sets sustain for a generator
147 * @sustain: sustain time in msecs
149 * Sets sustain for a generator, where @sustain is expressed
152 void ss_gen_sustain(struct ss_gen
* g
, double sustain
)
154 g
->sustain
=MS2F(sustain
);
159 * ss_gen_vibrato - Sets vibrato for a generator
161 * @depth: vibrato depth in msecs
162 * @freq: vibrato frequency
164 * Sets vibrato for a generator, with a @depth expressed in
165 * milliseconds and a frequency @freq expressed in hzs.
167 void ss_gen_vibrato(struct ss_gen
* g
, double depth
, double freq
)
169 g
->vib_depth
=MS2F(depth
);
170 g
->vib_inc
=( 6.28 * freq
) / (double)ss_frequency
;
176 * ss_gen_play - Activates a generator.
179 * @freq: frequency of the sound to be generated
180 * @vol: volume for each channel
183 * Activates a generator, usually as a response for a 'note on'
184 * message from an upper level. The wave @w holds all the sample
185 * data (PCM data, base frequency, etc.), @freq is the desired
186 * frequency, @vol a channel map and @note_id a unique identifier
189 void ss_gen_play(struct ss_gen
* g
, int note_id
, double freq
, float vol
[],
194 g
->mode
=SS_GEN_PLAYING
;
197 memcpy(&g
->w
, w
, sizeof(struct ss_wave
));
199 /* transfer volumes */
200 for(n
=0;n
< CHANNELS
;n
++)
203 /* calculate increment */
204 g
->inc
=freq
/ w
->base_freq
;
205 g
->inc
*= (double) w
->s_rate
/ (double) ss_frequency
;
207 /* default sustain (short) */
208 ss_gen_sustain(g
, 50.0);
210 /* default vibrato (none) */
211 ss_gen_vibrato(g
, 0.0, 0.0);
213 /* no portamento by default */
216 /* start from the beginning */
220 /* good freq: 6 Hz */
221 /* good depth: 1/6 semitone */
225 g
->vib_depth
=30; /* 20 */
226 g
->vib_inc
=( 6.28 * 6.0 ) / (double)ss_frequency
; /* 0.001 */
235 * ss_gen_release - Releases a generator.
238 * Releases a generator, usually as a response for a 'note off'
239 * message from an upper level. The generator enters SS_GEN_RELEASED
240 * mode, which starts generating sustain data until it's over.
242 void ss_gen_release(struct ss_gen
* g
)
246 /* note needs not be tracked anymore */
249 /* generator is released */
250 g
->mode
=SS_GEN_RELEASED
;
252 /* calculates delta volume values */
253 for(n
=0;n
< CHANNELS
;n
++)
256 g
->dvol
[n
]=g
->vol
[n
] / (float) g
->sustain
;
264 * ss_gen_frame - Generates a frame of samples.
266 * @frame: array where the output samples will be stored
268 * Generates a frame of samples from the @g generator, that will be stored
269 * in the @sample array.
271 * Returns non-zero if the generator is stopped and should be freed.
273 int ss_gen_frame(struct ss_gen
* g
, float frame
[])
282 /* process vibrato */
285 g
->vibrato
+= g
->vib_inc
;
286 v
+= sin(g
->vibrato
) * g
->vib_depth
;
290 for(n
=0;n
< CHANNELS
;n
++)
292 if(g
->w
.wave
[n
] != NULL
)
294 s
=ss_get_sample(&g
->w
, n
, v
);
301 /* increment pointer */
304 /* test loop boundaries */
305 if(g
->cursor
> g
->w
.loop_end
)
308 if(g
->w
.loop_start
== -1)
311 g
->cursor
=g
->w
.loop_start
;
314 /* process sustain */
315 if(g
->mode
== SS_GEN_RELEASED
)
317 for(n
=0;n
< CHANNELS
;n
++)
318 g
->vol
[n
] -= g
->dvol
[n
];
320 if(--g
->sustain
<= 0)
324 /* process portamento */
325 g
->inc
+= g
->portamento
;
332 * ss_gen_portamento - Sets portamento for a generator.
334 * @portamento: portamento time
335 * @dest_inc: destination inc (frequency)
337 * Sets the portamento for a generator. @portamento is the
338 * number of frames the generator should move from its current
339 * cursor increment to @dest_inc. See generator_play() for an
340 * explanation of the value contained in @dest_inc.
342 * Returns -1 if the generator is not active, or 0 if the
343 * portamento was accepted.
345 * FIXME: The API for portamento will surely change.
347 int ss_gen_portamento(struct ss_gen
* g
, int portamento
, double dest_inc
)
349 /* generator must be playing */
350 if(g
->mode
!= SS_GEN_PLAYING
)
353 g->portamento=portamento;
354 g->dest_inc=dest_inc;
355 g->dinc=((dest_inc - g->inc) / (double) portamento);