1 /* FluidSynth - A Software Synthesizer
3 * Copyright (C) 2003 Peter Hanappe and others.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public License
7 * as published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 2002 : API design by Peter Hanappe and Antoine Schmitt
24 August 2002 : Implementation by Antoine Schmitt as@gratin.org
25 as part of the infiniteCD author project
26 http://www.infiniteCD.org/
27 Oct4.2002 : AS : corrected bug in heap allocation, that caused a crash during sequencer free.
31 #include "fluid_event_priv.h"
32 #include "fluidsynth_priv.h"
34 /***************************************************************
39 /* Event alloc/free */
42 fluid_event_clear(fluid_event_t* evt)
44 FLUID_MEMSET(evt, 0, sizeof(fluid_event_t));
46 // by default, no type
53 * Create a new sequencer event structure.
54 * @return New sequencer event structure or NULL if out of memory
61 evt = FLUID_NEW(fluid_event_t);
63 fluid_log(FLUID_PANIC, "event: Out of memory\n");
66 fluid_event_clear(evt);
72 * Delete a sequencer event structure.
73 * @param evt Sequencer event structure created by new_fluid_event().
76 delete_fluid_event(fluid_event_t* evt)
87 * Set the time field of a sequencer event.
89 * @param evt Sequencer event structure
90 * @param time Time value to assign
93 fluid_event_set_time(fluid_event_t* evt, unsigned int time)
99 * Set source of a sequencer event (DOCME).
100 * @param evt Sequencer event structure
104 fluid_event_set_source(fluid_event_t* evt, short src)
110 * Set destination of a sequencer event (DOCME).
111 * @param evt Sequencer event structure
115 fluid_event_set_dest(fluid_event_t* evt, short dest)
121 * Set a sequencer event to be a timer event.
122 * @param evt Sequencer event structure
126 fluid_event_timer(fluid_event_t* evt, void* data)
128 evt->type = FLUID_SEQ_TIMER;
133 * Set a sequencer event to be a note on event.
134 * @param evt Sequencer event structure
135 * @param channel MIDI channel number
136 * @param key MIDI note number (0-127)
137 * @param vel MIDI velocity value (0-127)
140 fluid_event_noteon(fluid_event_t* evt, int channel, short key, short vel)
142 evt->type = FLUID_SEQ_NOTEON;
143 evt->channel = channel;
149 * Set a sequencer event to be a note off event.
150 * @param evt Sequencer event structure
151 * @param channel MIDI channel number
152 * @param key MIDI note number (0-127)
155 fluid_event_noteoff(fluid_event_t* evt, int channel, short key)
157 evt->type = FLUID_SEQ_NOTEOFF;
158 evt->channel = channel;
163 * Set a sequencer event to be a note duration event.
164 * @param evt Sequencer event structure
165 * @param channel MIDI channel number
166 * @param key MIDI note number (0-127)
167 * @param vel MIDI velocity value (0-127)
168 * @param duration Duration of note (DOCME units?)
171 fluid_event_note(fluid_event_t* evt, int channel, short key, short vel, unsigned int duration)
173 evt->type = FLUID_SEQ_NOTE;
174 evt->channel = channel;
177 evt->duration = duration;
181 * Set a sequencer event to be an all sounds off event.
182 * @param evt Sequencer event structure
183 * @param channel MIDI channel number
186 fluid_event_all_sounds_off(fluid_event_t* evt, int channel)
188 evt->type = FLUID_SEQ_ALLSOUNDSOFF;
189 evt->channel = channel;
193 * Set a sequencer event to be a all notes off event.
194 * @param evt Sequencer event structure
195 * @param channel MIDI channel number
198 fluid_event_all_notes_off(fluid_event_t* evt, int channel)
200 evt->type = FLUID_SEQ_ALLNOTESOFF;
201 evt->channel = channel;
205 * Set a sequencer event to be a bank select event.
206 * @param evt Sequencer event structure
207 * @param channel MIDI channel number
208 * @param bank_num MIDI bank number (0-16383)
211 fluid_event_bank_select(fluid_event_t* evt, int channel, short bank_num)
213 evt->type = FLUID_SEQ_BANKSELECT;
214 evt->channel = channel;
215 evt->control = bank_num;
219 * Set a sequencer event to be a program change event.
220 * @param evt Sequencer event structure
221 * @param channel MIDI channel number
222 * @param val MIDI program number (0-127)
225 fluid_event_program_change(fluid_event_t* evt, int channel, short val)
227 evt->type = FLUID_SEQ_PROGRAMCHANGE;
228 evt->channel = channel;
233 * Set a sequencer event to be a program select event.
234 * @param evt Sequencer event structure
235 * @param channel MIDI channel number
236 * @param sfont_id SoundFont ID number
237 * @param bank_num MIDI bank number (0-16383)
238 * @param preset_num MIDI preset number (0-127)
241 fluid_event_program_select(fluid_event_t* evt, int channel,
242 unsigned int sfont_id, short bank_num, short preset_num)
244 evt->type = FLUID_SEQ_PROGRAMSELECT;
245 evt->channel = channel;
246 evt->duration = sfont_id;
247 evt->value = preset_num;
248 evt->control = bank_num;
252 * Set a sequencer event to be an any control change event.
253 * @param evt Sequencer event structure
254 * @param channel MIDI channel number
258 fluid_event_any_control_change(fluid_event_t* evt, int channel)
260 evt->type = FLUID_SEQ_ANYCONTROLCHANGE;
261 evt->channel = channel;
265 * Set a sequencer event to be a pitch bend event.
266 * @param evt Sequencer event structure
267 * @param channel MIDI channel number
268 * @param pitch MIDI pitch bend value (0-16383, 8192 = no bend)
271 fluid_event_pitch_bend(fluid_event_t* evt, int channel, int pitch)
273 evt->type = FLUID_SEQ_PITCHBEND;
274 evt->channel = channel;
275 if (pitch < 0) pitch = 0;
276 if (pitch > 16383) pitch = 16383;
281 * Set a sequencer event to be a pitch wheel sensitivity event.
282 * @param evt Sequencer event structure
283 * @param channel MIDI channel number
284 * @param value MIDI pitch wheel sensitivity value (DOCME units?)
287 fluid_event_pitch_wheelsens(fluid_event_t* evt, int channel, short value)
289 evt->type = FLUID_SEQ_PITCHWHHELSENS;
290 evt->channel = channel;
295 * Set a sequencer event to be a modulation event.
296 * @param evt Sequencer event structure
297 * @param channel MIDI channel number
298 * @param val MIDI modulation value (0-127)
301 fluid_event_modulation(fluid_event_t* evt, int channel, short val)
303 evt->type = FLUID_SEQ_MODULATION;
304 evt->channel = channel;
305 if (val < 0) val = 0;
306 if (val > 127) val = 127;
311 * Set a sequencer event to be a MIDI sustain event.
312 * @param evt Sequencer event structure
313 * @param channel MIDI channel number
314 * @param val MIDI sustain value (0-127)
317 fluid_event_sustain(fluid_event_t* evt, int channel, short val)
319 evt->type = FLUID_SEQ_SUSTAIN;
320 evt->channel = channel;
321 if (val < 0) val = 0;
322 if (val > 127) val = 127;
327 * Set a sequencer event to be a MIDI control change event.
328 * @param evt Sequencer event structure
329 * @param channel MIDI channel number
330 * @param control MIDI control number (0-127)
331 * @param val MIDI control value (0-16383 DOCME is that true?)
334 fluid_event_control_change(fluid_event_t* evt, int channel, short control, short val)
336 evt->type = FLUID_SEQ_CONTROLCHANGE;
337 evt->channel = channel;
338 evt->control = control;
343 * Set a sequencer event to be a stereo pan event.
344 * @param evt Sequencer event structure
345 * @param channel MIDI channel number
346 * @param val MIDI panning value (0-127, 0=left, 64 = middle, 127 = right)
349 fluid_event_pan(fluid_event_t* evt, int channel, short val)
351 evt->type = FLUID_SEQ_PAN;
352 evt->channel = channel;
353 if (val < 0) val = 0;
354 if (val > 127) val = 127;
359 * Set a sequencer event to be a volume event.
360 * @param evt Sequencer event structure
361 * @param channel MIDI channel number
362 * @param val Volume value (0-127)
365 fluid_event_volume(fluid_event_t* evt, int channel, short val)
367 evt->type = FLUID_SEQ_VOLUME;
368 evt->channel = channel;
369 if (val < 0) val = 0;
370 if (val > 127) val = 127;
375 * Set a sequencer event to be a reverb send event.
376 * @param evt Sequencer event structure
377 * @param channel MIDI channel number
378 * @param val Reverb amount (0-127)
381 fluid_event_reverb_send(fluid_event_t* evt, int channel, short val)
383 evt->type = FLUID_SEQ_REVERBSEND;
384 evt->channel = channel;
385 if (val < 0) val = 0;
386 if (val > 127) val = 127;
391 * Set a sequencer event to be a chorus send event.
392 * @param evt Sequencer event structure
393 * @param channel MIDI channel number
394 * @param val Chorus amount (0-127)
397 fluid_event_chorus_send(fluid_event_t* evt, int channel, short val)
399 evt->type = FLUID_SEQ_CHORUSSEND;
400 evt->channel = channel;
401 if (val < 0) val = 0;
402 if (val > 127) val = 127;
408 * Set a sequencer event to be an unregistering event.
409 * @param evt Sequencer event structure
413 fluid_event_unregistering(fluid_event_t* evt)
415 evt->type = FLUID_SEQ_UNREGISTERING;
419 * Set a sequencer event to be a channel-wide aftertouch event.
420 * @param evt Sequencer event structure
421 * @param channel MIDI channel number
422 * @param val Aftertouch amount (0-127)
426 fluid_event_channel_pressure(fluid_event_t* evt, int channel, short val)
428 evt->type = FLUID_SEQ_CHANNELPRESSURE;
429 evt->channel = channel;
430 if (val < 0) val = 0;
431 if (val > 127) val = 127;
436 * Set a sequencer event to be a midi system reset event.
437 * @param evt Sequencer event structure
441 fluid_event_system_reset(fluid_event_t* evt)
443 evt->type = FLUID_SEQ_SYSTEMRESET;
449 * Accessing event data
453 * Get the event type (#fluid_seq_event_type) field from a sequencer event structure.
454 * @param evt Sequencer event structure
455 * @return Event type (#fluid_seq_event_type).
457 int fluid_event_get_type(fluid_event_t* evt)
463 * Get the time field from a sequencer event structure.
464 * @param evt Sequencer event structure
465 * @return Time value (DOCME units?)
467 unsigned int fluid_event_get_time(fluid_event_t* evt)
473 * Get the source field from a sequencer event structure.
474 * @param evt Sequencer event structure
477 short fluid_event_get_source(fluid_event_t* evt)
483 * Get the dest field from a sequencer event structure.
484 * @param evt Sequencer event structure
487 short fluid_event_get_dest(fluid_event_t* evt)
493 * Get the MIDI channel field from a sequencer event structure.
494 * @param evt Sequencer event structure
495 * @return MIDI channel number (DOCME 0-15 or more?)
497 int fluid_event_get_channel(fluid_event_t* evt)
503 * Get the MIDI note field from a sequencer event structure.
504 * @param evt Sequencer event structure
505 * @return MIDI note number (0-127)
507 short fluid_event_get_key(fluid_event_t* evt)
513 * Get the MIDI velocity field from a sequencer event structure.
514 * @param evt Sequencer event structure
515 * @return MIDI velocity value (0-127)
517 short fluid_event_get_velocity(fluid_event_t* evt)
524 * Get the MIDI control number field from a sequencer event structure.
525 * @param evt Sequencer event structure
526 * @return MIDI control number (0-127)
528 short fluid_event_get_control(fluid_event_t* evt)
534 * Get the value field from a sequencer event structure.
535 * @param evt Sequencer event structure
536 * @return Value field of event.
538 * The Value field is used by the following event types:
539 * #FLUID_SEQ_PROGRAMCHANGE, #FLUID_SEQ_PROGRAMSELECT (preset_num),
540 * #FLUID_SEQ_PITCHWHHELSENS, #FLUID_SEQ_MODULATION, #FLUID_SEQ_SUSTAIN,
541 * #FLUID_SEQ_CONTROLCHANGE, #FLUID_SEQ_PAN, #FLUID_SEQ_VOLUME,
542 * #FLUID_SEQ_REVERBSEND, #FLUID_SEQ_CHORUSSEND.
544 short fluid_event_get_value(fluid_event_t* evt)
550 * Get the data field from a sequencer event structure.
551 * @param evt Sequencer event structure
552 * @return Data field of event.
554 * Used by the #FLUID_SEQ_TIMER event type.
556 void* fluid_event_get_data(fluid_event_t* evt)
562 * Get the duration field from a sequencer event structure.
563 * @param evt Sequencer event structure
564 * @return Note duration value (DOCME units?)
566 * Used by the #FLUID_SEQ_NOTE event type.
568 unsigned int fluid_event_get_duration(fluid_event_t* evt)
570 return evt->duration;
574 * Get the MIDI bank field from a sequencer event structure.
575 * @param evt Sequencer event structure
576 * @return MIDI bank number (0-16383)
578 * Used by the #FLUID_SEQ_BANKSELECT and #FLUID_SEQ_PROGRAMSELECT
581 short fluid_event_get_bank(fluid_event_t* evt)
587 * Get the pitch field from a sequencer event structure.
588 * @param evt Sequencer event structure
589 * @return MIDI pitch bend pitch value (0-16383, 8192 = no bend)
591 * Used by the #FLUID_SEQ_PITCHBEND event type.
593 int fluid_event_get_pitch(fluid_event_t* evt)
599 * Get the MIDI program field from a sequencer event structure.
600 * @param evt Sequencer event structure
601 * @return MIDI program number (0-127)
603 * Used by the #FLUID_SEQ_PROGRAMCHANGE and #FLUID_SEQ_PROGRAMSELECT
607 fluid_event_get_program(fluid_event_t* evt)
613 * Get the SoundFont ID field from a sequencer event structure.
614 * @param evt Sequencer event structure
615 * @return SoundFont identifier value.
617 * Used by the #FLUID_SEQ_PROGRAMSELECT event type.
620 fluid_event_get_sfont_id(fluid_event_t* evt)
622 return evt->duration;
627 /********************/
628 /* heap management */
629 /********************/
632 _fluid_evt_heap_init(int nbEvents)
634 #ifdef HEAP_WITH_DYNALLOC
637 fluid_evt_heap_t* heap;
638 fluid_evt_entry *tmp;
640 heap = FLUID_NEW(fluid_evt_heap_t);
642 fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
646 heap->freelist = NULL;
647 fluid_mutex_init(heap->mutex);
650 fluid_mutex_lock(heap->mutex);
652 /* Allocate the event entries */
653 for (i = 0; i < nbEvents; i++) {
654 tmp = FLUID_NEW(fluid_evt_entry);
655 tmp->next = heap->freelist;
656 heap->freelist = tmp;
660 fluid_mutex_unlock(heap->mutex);
665 fluid_evt_heap_t* heap;
666 int siz = 2*sizeof(fluid_evt_entry *) + sizeof(fluid_evt_entry)*nbEvents;
668 heap = (fluid_evt_heap_t *)FLUID_MALLOC(siz);
670 fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
673 FLUID_MEMSET(heap, 0, siz);
675 /* link all heap events */
677 fluid_evt_entry *tmp = &(heap->pool);
678 for (i = 0 ; i < nbEvents - 1 ; i++)
679 tmp[i].next = &(tmp[i+1]);
680 tmp[nbEvents-1].next = NULL;
682 /* set head & tail */
683 heap->tail = &(tmp[nbEvents-1]);
684 heap->head = &(heap->pool);
691 _fluid_evt_heap_free(fluid_evt_heap_t* heap)
693 #ifdef HEAP_WITH_DYNALLOC
694 fluid_evt_entry *tmp, *next;
697 fluid_mutex_lock(heap->mutex);
699 tmp = heap->freelist;
707 fluid_mutex_unlock(heap->mutex);
708 fluid_mutex_destroy(heap->mutex);
718 _fluid_seq_heap_get_free(fluid_evt_heap_t* heap)
720 #ifdef HEAP_WITH_DYNALLOC
721 fluid_evt_entry* evt = NULL;
724 fluid_mutex_lock(heap->mutex);
727 if (heap->freelist == NULL) {
728 heap->freelist = FLUID_NEW(fluid_evt_entry);
729 if (heap->freelist != NULL) {
730 heap->freelist->next = NULL;
735 evt = heap->freelist;
738 heap->freelist = heap->freelist->next;
743 fluid_mutex_unlock(heap->mutex);
748 fluid_evt_entry* evt;
749 if (heap->head == NULL) return NULL;
751 /* take from head of the heap */
752 /* critical - should threadlock ? */
754 heap->head = heap->head->next;
761 _fluid_seq_heap_set_free(fluid_evt_heap_t* heap, fluid_evt_entry* evt)
763 #ifdef HEAP_WITH_DYNALLOC
766 fluid_mutex_lock(heap->mutex);
768 evt->next = heap->freelist;
769 heap->freelist = evt;
772 fluid_mutex_unlock(heap->mutex);
775 /* append to the end of the heap */
776 /* critical - should threadlock ? */
777 heap->tail->next = evt;