1 /* FluidSynth - A Software Synthesizer
2 *
3 * Copyright (C) 2003 Peter Hanappe and others.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
9 *
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 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser 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
18 * 02110-1301, USA
19 */
20
21
22 /*
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.
28 */
29
30
31 #include "fluid_event.h"
32 #include "fluidsynth_priv.h"
33
34 /***************************************************************
35 *
36 * SEQUENCER EVENTS
37 */
38
39 /* Event alloc/free */
40
41 void
fluid_event_clear(fluid_event_t * evt)42 fluid_event_clear(fluid_event_t *evt)
43 {
44 FLUID_MEMSET(evt, 0, sizeof(fluid_event_t));
45
46 // by default, no type
47 evt->dest = -1;
48 evt->src = -1;
49 evt->type = -1;
50 }
51
52 /**
53 * Create a new sequencer event structure.
54 * @return New sequencer event structure or NULL if out of memory
55 */
56 fluid_event_t *
new_fluid_event()57 new_fluid_event()
58 {
59 fluid_event_t *evt;
60
61 evt = FLUID_NEW(fluid_event_t);
62
63 if(evt == NULL)
64 {
65 FLUID_LOG(FLUID_PANIC, "event: Out of memory\n");
66 return NULL;
67 }
68
69 fluid_event_clear(evt);
70
71 return(evt);
72 }
73
74 /**
75 * Delete a sequencer event structure.
76 * @param evt Sequencer event structure created by new_fluid_event().
77 */
78 void
delete_fluid_event(fluid_event_t * evt)79 delete_fluid_event(fluid_event_t *evt)
80 {
81 fluid_return_if_fail(evt != NULL);
82
83 FLUID_FREE(evt);
84 }
85
86 /**
87 * Set the time field of a sequencer event.
88 * @internal
89 * @param evt Sequencer event structure
90 * @param time Time value to assign
91 */
92 void
fluid_event_set_time(fluid_event_t * evt,unsigned int time)93 fluid_event_set_time(fluid_event_t *evt, unsigned int time)
94 {
95 evt->time = time;
96 }
97
98 /**
99 * Set source of a sequencer event. \c src must be a unique sequencer ID or -1 if not set.
100 * @param evt Sequencer event structure
101 * @param src Unique sequencer ID
102 */
103 void
fluid_event_set_source(fluid_event_t * evt,fluid_seq_id_t src)104 fluid_event_set_source(fluid_event_t *evt, fluid_seq_id_t src)
105 {
106 evt->src = src;
107 }
108
109 /**
110 * Set destination of this sequencer event, i.e. the sequencer client this event will be sent to. \c dest must be a unique sequencer ID.
111 * @param evt Sequencer event structure
112 * @param dest The destination unique sequencer ID
113 */
114 void
fluid_event_set_dest(fluid_event_t * evt,fluid_seq_id_t dest)115 fluid_event_set_dest(fluid_event_t *evt, fluid_seq_id_t dest)
116 {
117 evt->dest = dest;
118 }
119
120 /**
121 * Set a sequencer event to be a timer event.
122 * @param evt Sequencer event structure
123 * @param data User supplied data pointer
124 */
125 void
fluid_event_timer(fluid_event_t * evt,void * data)126 fluid_event_timer(fluid_event_t *evt, void *data)
127 {
128 evt->type = FLUID_SEQ_TIMER;
129 evt->data = data;
130 }
131
132 /**
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)
138 */
139 void
fluid_event_noteon(fluid_event_t * evt,int channel,short key,short vel)140 fluid_event_noteon(fluid_event_t *evt, int channel, short key, short vel)
141 {
142 evt->type = FLUID_SEQ_NOTEON;
143 evt->channel = channel;
144 evt->key = key;
145 evt->vel = vel;
146 }
147
148 /**
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)
153 */
154 void
fluid_event_noteoff(fluid_event_t * evt,int channel,short key)155 fluid_event_noteoff(fluid_event_t *evt, int channel, short key)
156 {
157 evt->type = FLUID_SEQ_NOTEOFF;
158 evt->channel = channel;
159 evt->key = key;
160 }
161
162 /**
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 in the time scale used by the sequencer (by default milliseconds)
169 */
170 void
fluid_event_note(fluid_event_t * evt,int channel,short key,short vel,unsigned int duration)171 fluid_event_note(fluid_event_t *evt, int channel, short key, short vel, unsigned int duration)
172 {
173 evt->type = FLUID_SEQ_NOTE;
174 evt->channel = channel;
175 evt->key = key;
176 evt->vel = vel;
177 evt->duration = duration;
178 }
179
180 /**
181 * Set a sequencer event to be an all sounds off event.
182 * @param evt Sequencer event structure
183 * @param channel MIDI channel number
184 */
185 void
fluid_event_all_sounds_off(fluid_event_t * evt,int channel)186 fluid_event_all_sounds_off(fluid_event_t *evt, int channel)
187 {
188 evt->type = FLUID_SEQ_ALLSOUNDSOFF;
189 evt->channel = channel;
190 }
191
192 /**
193 * Set a sequencer event to be a all notes off event.
194 * @param evt Sequencer event structure
195 * @param channel MIDI channel number
196 */
197 void
fluid_event_all_notes_off(fluid_event_t * evt,int channel)198 fluid_event_all_notes_off(fluid_event_t *evt, int channel)
199 {
200 evt->type = FLUID_SEQ_ALLNOTESOFF;
201 evt->channel = channel;
202 }
203
204 /**
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)
209 */
210 void
fluid_event_bank_select(fluid_event_t * evt,int channel,short bank_num)211 fluid_event_bank_select(fluid_event_t *evt, int channel, short bank_num)
212 {
213 evt->type = FLUID_SEQ_BANKSELECT;
214 evt->channel = channel;
215 evt->control = bank_num;
216 }
217
218 /**
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)
223 */
224 void
fluid_event_program_change(fluid_event_t * evt,int channel,short val)225 fluid_event_program_change(fluid_event_t *evt, int channel, short val)
226 {
227 evt->type = FLUID_SEQ_PROGRAMCHANGE;
228 evt->channel = channel;
229 evt->value = val;
230 }
231
232 /**
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)
239 */
240 void
fluid_event_program_select(fluid_event_t * evt,int channel,unsigned int sfont_id,short bank_num,short preset_num)241 fluid_event_program_select(fluid_event_t *evt, int channel,
242 unsigned int sfont_id, short bank_num, short preset_num)
243 {
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;
249 }
250
251 /**
252 * Set a sequencer event to be an any control change event (for internal use).
253 * @param evt Sequencer event structure
254 * @param channel MIDI channel number
255 */
256 void
fluid_event_any_control_change(fluid_event_t * evt,int channel)257 fluid_event_any_control_change(fluid_event_t *evt, int channel)
258 {
259 evt->type = FLUID_SEQ_ANYCONTROLCHANGE;
260 evt->channel = channel;
261 }
262
263 /**
264 * Set a sequencer event to be a pitch bend event.
265 * @param evt Sequencer event structure
266 * @param channel MIDI channel number
267 * @param pitch MIDI pitch bend value (0-16383, 8192 = no bend)
268 */
269 void
fluid_event_pitch_bend(fluid_event_t * evt,int channel,int pitch)270 fluid_event_pitch_bend(fluid_event_t *evt, int channel, int pitch)
271 {
272 evt->type = FLUID_SEQ_PITCHBEND;
273 evt->channel = channel;
274
275 if(pitch < 0)
276 {
277 pitch = 0;
278 }
279
280 if(pitch > 16383)
281 {
282 pitch = 16383;
283 }
284
285 evt->pitch = pitch;
286 }
287
288 /**
289 * Set a sequencer event to be a pitch wheel sensitivity event.
290 * @param evt Sequencer event structure
291 * @param channel MIDI channel number
292 * @param value MIDI pitch wheel sensitivity value in semitones
293 */
294 void
fluid_event_pitch_wheelsens(fluid_event_t * evt,int channel,short value)295 fluid_event_pitch_wheelsens(fluid_event_t *evt, int channel, short value)
296 {
297 evt->type = FLUID_SEQ_PITCHWHEELSENS;
298 evt->channel = channel;
299 evt->value = value;
300 }
301
302 /**
303 * Set a sequencer event to be a modulation event.
304 * @param evt Sequencer event structure
305 * @param channel MIDI channel number
306 * @param val MIDI modulation value (0-127)
307 */
308 void
fluid_event_modulation(fluid_event_t * evt,int channel,short val)309 fluid_event_modulation(fluid_event_t *evt, int channel, short val)
310 {
311 evt->type = FLUID_SEQ_MODULATION;
312 evt->channel = channel;
313
314 if(val < 0)
315 {
316 val = 0;
317 }
318
319 if(val > 127)
320 {
321 val = 127;
322 }
323
324 evt->value = val;
325 }
326
327 /**
328 * Set a sequencer event to be a MIDI sustain event.
329 * @param evt Sequencer event structure
330 * @param channel MIDI channel number
331 * @param val MIDI sustain value (0-127)
332 */
333 void
fluid_event_sustain(fluid_event_t * evt,int channel,short val)334 fluid_event_sustain(fluid_event_t *evt, int channel, short val)
335 {
336 evt->type = FLUID_SEQ_SUSTAIN;
337 evt->channel = channel;
338
339 if(val < 0)
340 {
341 val = 0;
342 }
343
344 if(val > 127)
345 {
346 val = 127;
347 }
348
349 evt->value = val;
350 }
351
352 /**
353 * Set a sequencer event to be a MIDI control change event.
354 * @param evt Sequencer event structure
355 * @param channel MIDI channel number
356 * @param control MIDI control number (0-127)
357 * @param val MIDI control value (0-127)
358 */
359 void
fluid_event_control_change(fluid_event_t * evt,int channel,short control,short val)360 fluid_event_control_change(fluid_event_t *evt, int channel, short control, short val)
361 {
362 evt->type = FLUID_SEQ_CONTROLCHANGE;
363 evt->channel = channel;
364 evt->control = control;
365 evt->value = val;
366 }
367
368 /**
369 * Set a sequencer event to be a stereo pan event.
370 * @param evt Sequencer event structure
371 * @param channel MIDI channel number
372 * @param val MIDI panning value (0-127, 0=left, 64 = middle, 127 = right)
373 */
374 void
fluid_event_pan(fluid_event_t * evt,int channel,short val)375 fluid_event_pan(fluid_event_t *evt, int channel, short val)
376 {
377 evt->type = FLUID_SEQ_PAN;
378 evt->channel = channel;
379
380 if(val < 0)
381 {
382 val = 0;
383 }
384
385 if(val > 127)
386 {
387 val = 127;
388 }
389
390 evt->value = val;
391 }
392
393 /**
394 * Set a sequencer event to be a volume event.
395 * @param evt Sequencer event structure
396 * @param channel MIDI channel number
397 * @param val Volume value (0-127)
398 */
399 void
fluid_event_volume(fluid_event_t * evt,int channel,short val)400 fluid_event_volume(fluid_event_t *evt, int channel, short val)
401 {
402 evt->type = FLUID_SEQ_VOLUME;
403 evt->channel = channel;
404
405 if(val < 0)
406 {
407 val = 0;
408 }
409
410 if(val > 127)
411 {
412 val = 127;
413 }
414
415 evt->value = val;
416 }
417
418 /**
419 * Set a sequencer event to be a reverb send event.
420 * @param evt Sequencer event structure
421 * @param channel MIDI channel number
422 * @param val Reverb amount (0-127)
423 */
424 void
fluid_event_reverb_send(fluid_event_t * evt,int channel,short val)425 fluid_event_reverb_send(fluid_event_t *evt, int channel, short val)
426 {
427 evt->type = FLUID_SEQ_REVERBSEND;
428 evt->channel = channel;
429
430 if(val < 0)
431 {
432 val = 0;
433 }
434
435 if(val > 127)
436 {
437 val = 127;
438 }
439
440 evt->value = val;
441 }
442
443 /**
444 * Set a sequencer event to be a chorus send event.
445 * @param evt Sequencer event structure
446 * @param channel MIDI channel number
447 * @param val Chorus amount (0-127)
448 */
449 void
fluid_event_chorus_send(fluid_event_t * evt,int channel,short val)450 fluid_event_chorus_send(fluid_event_t *evt, int channel, short val)
451 {
452 evt->type = FLUID_SEQ_CHORUSSEND;
453 evt->channel = channel;
454
455 if(val < 0)
456 {
457 val = 0;
458 }
459
460 if(val > 127)
461 {
462 val = 127;
463 }
464
465 evt->value = val;
466 }
467
468
469 /**
470 * Set a sequencer event to be an unregistering event.
471 * @param evt Sequencer event structure
472 * @since 1.1.0
473 */
474 void
fluid_event_unregistering(fluid_event_t * evt)475 fluid_event_unregistering(fluid_event_t *evt)
476 {
477 evt->type = FLUID_SEQ_UNREGISTERING;
478 }
479
480 /**
481 * Set a sequencer event to be a channel-wide aftertouch event.
482 * @param evt Sequencer event structure
483 * @param channel MIDI channel number
484 * @param val Aftertouch amount (0-127)
485 * @since 1.1.0
486 */
487 void
fluid_event_channel_pressure(fluid_event_t * evt,int channel,short val)488 fluid_event_channel_pressure(fluid_event_t *evt, int channel, short val)
489 {
490 evt->type = FLUID_SEQ_CHANNELPRESSURE;
491 evt->channel = channel;
492
493 if(val < 0)
494 {
495 val = 0;
496 }
497
498 if(val > 127)
499 {
500 val = 127;
501 }
502
503 evt->value = val;
504 }
505
506 /**
507 * Set a sequencer event to be a polyphonic aftertouch event.
508 * @param evt Sequencer event structure
509 * @param channel MIDI channel number
510 * @param key MIDI note number (0-127)
511 * @param val Aftertouch amount (0-127)
512 * @since 2.0.0
513 */
514 void
fluid_event_key_pressure(fluid_event_t * evt,int channel,short key,short val)515 fluid_event_key_pressure(fluid_event_t *evt, int channel, short key, short val)
516 {
517 evt->type = FLUID_SEQ_KEYPRESSURE;
518 evt->channel = channel;
519
520 if(key < 0)
521 {
522 key = 0;
523 }
524
525 if(key > 127)
526 {
527 key = 127;
528 }
529
530 if(val < 0)
531 {
532 val = 0;
533 }
534
535 if(val > 127)
536 {
537 val = 127;
538 }
539
540 evt->key = key;
541 evt->value = val;
542 }
543
544 /**
545 * Set a sequencer event to be a midi system reset event.
546 * @param evt Sequencer event structure
547 * @since 1.1.0
548 */
549 void
fluid_event_system_reset(fluid_event_t * evt)550 fluid_event_system_reset(fluid_event_t *evt)
551 {
552 evt->type = FLUID_SEQ_SYSTEMRESET;
553 }
554
555
556
557 /*
558 * Accessing event data
559 */
560
561 /**
562 * Get the event type (#fluid_seq_event_type) field from a sequencer event structure.
563 * @param evt Sequencer event structure
564 * @return Event type (#fluid_seq_event_type).
565 */
fluid_event_get_type(fluid_event_t * evt)566 int fluid_event_get_type(fluid_event_t *evt)
567 {
568 return evt->type;
569 }
570
571 /**
572 * @internal
573 * Get the time field from a sequencer event structure.
574 * @param evt Sequencer event structure
575 * @return Time value
576 */
fluid_event_get_time(fluid_event_t * evt)577 unsigned int fluid_event_get_time(fluid_event_t *evt)
578 {
579 return evt->time;
580 }
581
582 /**
583 * Get the source sequencer client from a sequencer event structure.
584 * @param evt Sequencer event structure
585 * @return source field of the sequencer event
586 */
fluid_event_get_source(fluid_event_t * evt)587 fluid_seq_id_t fluid_event_get_source(fluid_event_t *evt)
588 {
589 return evt->src;
590 }
591
592 /**
593 * Get the dest sequencer client from a sequencer event structure.
594 * @param evt Sequencer event structure
595 * @return dest field of the sequencer event
596 */
fluid_event_get_dest(fluid_event_t * evt)597 fluid_seq_id_t fluid_event_get_dest(fluid_event_t *evt)
598 {
599 return evt->dest;
600 }
601
602 /**
603 * Get the MIDI channel field from a sequencer event structure.
604 * @param evt Sequencer event structure
605 * @return MIDI zero-based channel number
606 */
fluid_event_get_channel(fluid_event_t * evt)607 int fluid_event_get_channel(fluid_event_t *evt)
608 {
609 return evt->channel;
610 }
611
612 /**
613 * Get the MIDI note field from a sequencer event structure.
614 * @param evt Sequencer event structure
615 * @return MIDI note number (0-127)
616 */
fluid_event_get_key(fluid_event_t * evt)617 short fluid_event_get_key(fluid_event_t *evt)
618 {
619 return evt->key;
620 }
621
622 /**
623 * Get the MIDI velocity field from a sequencer event structure.
624 * @param evt Sequencer event structure
625 * @return MIDI velocity value (0-127)
626 */
fluid_event_get_velocity(fluid_event_t * evt)627 short fluid_event_get_velocity(fluid_event_t *evt)
628
629 {
630 return evt->vel;
631 }
632
633 /**
634 * Get the MIDI control number field from a sequencer event structure.
635 * @param evt Sequencer event structure
636 * @return MIDI control number (0-127)
637 */
fluid_event_get_control(fluid_event_t * evt)638 short fluid_event_get_control(fluid_event_t *evt)
639 {
640 return evt->control;
641 }
642
643 /**
644 * Get the value field from a sequencer event structure.
645 * @param evt Sequencer event structure
646 * @return Value field of event.
647 *
648 * The Value field is used by the following event types:
649 * #FLUID_SEQ_PROGRAMCHANGE, #FLUID_SEQ_PROGRAMSELECT (preset_num),
650 * #FLUID_SEQ_PITCHWHEELSENS, #FLUID_SEQ_MODULATION, #FLUID_SEQ_SUSTAIN,
651 * #FLUID_SEQ_CONTROLCHANGE, #FLUID_SEQ_PAN, #FLUID_SEQ_VOLUME,
652 * #FLUID_SEQ_REVERBSEND, #FLUID_SEQ_CHORUSSEND.
653 */
fluid_event_get_value(fluid_event_t * evt)654 short fluid_event_get_value(fluid_event_t *evt)
655 {
656 return evt->value;
657 }
658
659 /**
660 * Get the data field from a sequencer event structure.
661 * @param evt Sequencer event structure
662 * @return Data field of event.
663 *
664 * Used by the #FLUID_SEQ_TIMER event type.
665 */
fluid_event_get_data(fluid_event_t * evt)666 void *fluid_event_get_data(fluid_event_t *evt)
667 {
668 return evt->data;
669 }
670
671 /**
672 * Get the duration field from a sequencer event structure.
673 * @param evt Sequencer event structure
674 * @return Note duration value in the time scale used by the sequencer (by default milliseconds)
675 *
676 * Used by the #FLUID_SEQ_NOTE event type.
677 */
fluid_event_get_duration(fluid_event_t * evt)678 unsigned int fluid_event_get_duration(fluid_event_t *evt)
679 {
680 return evt->duration;
681 }
682
683 /**
684 * Get the MIDI bank field from a sequencer event structure.
685 * @param evt Sequencer event structure
686 * @return MIDI bank number (0-16383)
687 *
688 * Used by the #FLUID_SEQ_BANKSELECT and #FLUID_SEQ_PROGRAMSELECT
689 * event types.
690 */
fluid_event_get_bank(fluid_event_t * evt)691 short fluid_event_get_bank(fluid_event_t *evt)
692 {
693 return evt->control;
694 }
695
696 /**
697 * Get the pitch field from a sequencer event structure.
698 * @param evt Sequencer event structure
699 * @return MIDI pitch bend pitch value (0-16383, 8192 = no bend)
700 *
701 * Used by the #FLUID_SEQ_PITCHBEND event type.
702 */
fluid_event_get_pitch(fluid_event_t * evt)703 int fluid_event_get_pitch(fluid_event_t *evt)
704 {
705 return evt->pitch;
706 }
707
708 /**
709 * Get the MIDI program field from a sequencer event structure.
710 * @param evt Sequencer event structure
711 * @return MIDI program number (0-127)
712 *
713 * Used by the #FLUID_SEQ_PROGRAMCHANGE and #FLUID_SEQ_PROGRAMSELECT
714 * event types.
715 */
716 short
fluid_event_get_program(fluid_event_t * evt)717 fluid_event_get_program(fluid_event_t *evt)
718 {
719 return evt->value;
720 }
721
722 /**
723 * Get the SoundFont ID field from a sequencer event structure.
724 * @param evt Sequencer event structure
725 * @return SoundFont identifier value.
726 *
727 * Used by the #FLUID_SEQ_PROGRAMSELECT event type.
728 */
729 unsigned int
fluid_event_get_sfont_id(fluid_event_t * evt)730 fluid_event_get_sfont_id(fluid_event_t *evt)
731 {
732 return evt->duration;
733 }
734
735
736
737 /********************/
738 /* heap management */
739 /********************/
740
741 fluid_evt_heap_t *
_fluid_evt_heap_init(int nbEvents)742 _fluid_evt_heap_init(int nbEvents)
743 {
744 #ifdef HEAP_WITH_DYNALLOC
745
746 int i;
747 fluid_evt_heap_t *heap;
748 fluid_evt_entry *tmp;
749
750 heap = FLUID_NEW(fluid_evt_heap_t);
751
752 if(heap == NULL)
753 {
754 FLUID_LOG(FLUID_PANIC, "sequencer: Out of memory\n");
755 return NULL;
756 }
757
758 heap->freelist = NULL;
759 fluid_mutex_init(heap->mutex);
760
761 /* LOCK */
762 fluid_mutex_lock(heap->mutex);
763
764 /* Allocate the event entries */
765 for(i = 0; i < nbEvents; i++)
766 {
767 tmp = FLUID_NEW(fluid_evt_entry);
768 tmp->next = heap->freelist;
769 heap->freelist = tmp;
770 }
771
772 /* UNLOCK */
773 fluid_mutex_unlock(heap->mutex);
774
775
776 #else
777 int i;
778 fluid_evt_heap_t *heap;
779 int siz = 2 * sizeof(fluid_evt_entry *) + sizeof(fluid_evt_entry) * nbEvents;
780
781 heap = (fluid_evt_heap_t *)FLUID_MALLOC(siz);
782
783 if(heap == NULL)
784 {
785 FLUID_LOG(FLUID_PANIC, "sequencer: Out of memory\n");
786 return NULL;
787 }
788
789 FLUID_MEMSET(heap, 0, siz);
790
791 /* link all heap events */
792 {
793 fluid_evt_entry *tmp = &(heap->pool);
794
795 for(i = 0 ; i < nbEvents - 1 ; i++)
796 {
797 tmp[i].next = &(tmp[i + 1]);
798 }
799
800 tmp[nbEvents - 1].next = NULL;
801
802 /* set head & tail */
803 heap->tail = &(tmp[nbEvents - 1]);
804 heap->head = &(heap->pool);
805 }
806 #endif
807 return (heap);
808 }
809
810 void
_fluid_evt_heap_free(fluid_evt_heap_t * heap)811 _fluid_evt_heap_free(fluid_evt_heap_t *heap)
812 {
813 #ifdef HEAP_WITH_DYNALLOC
814 fluid_evt_entry *tmp, *next;
815
816 /* LOCK */
817 fluid_mutex_lock(heap->mutex);
818
819 tmp = heap->freelist;
820
821 while(tmp)
822 {
823 next = tmp->next;
824 FLUID_FREE(tmp);
825 tmp = next;
826 }
827
828 /* UNLOCK */
829 fluid_mutex_unlock(heap->mutex);
830 fluid_mutex_destroy(heap->mutex);
831
832 FLUID_FREE(heap);
833
834 #else
835 FLUID_FREE(heap);
836 #endif
837 }
838
839 fluid_evt_entry *
_fluid_seq_heap_get_free(fluid_evt_heap_t * heap)840 _fluid_seq_heap_get_free(fluid_evt_heap_t *heap)
841 {
842 #ifdef HEAP_WITH_DYNALLOC
843 fluid_evt_entry *evt = NULL;
844
845 /* LOCK */
846 fluid_mutex_lock(heap->mutex);
847
848 #if !defined(MACOS9)
849
850 if(heap->freelist == NULL)
851 {
852 heap->freelist = FLUID_NEW(fluid_evt_entry);
853
854 if(heap->freelist != NULL)
855 {
856 heap->freelist->next = NULL;
857 }
858 }
859
860 #endif
861
862 evt = heap->freelist;
863
864 if(evt != NULL)
865 {
866 heap->freelist = heap->freelist->next;
867 evt->next = NULL;
868 }
869
870 /* UNLOCK */
871 fluid_mutex_unlock(heap->mutex);
872
873 return evt;
874
875 #else
876 fluid_evt_entry *evt;
877
878 if(heap->head == NULL)
879 {
880 return NULL;
881 }
882
883 /* take from head of the heap */
884 /* critical - should threadlock ? */
885 evt = heap->head;
886 heap->head = heap->head->next;
887
888 return evt;
889 #endif
890 }
891
892 void
_fluid_seq_heap_set_free(fluid_evt_heap_t * heap,fluid_evt_entry * evt)893 _fluid_seq_heap_set_free(fluid_evt_heap_t *heap, fluid_evt_entry *evt)
894 {
895 #ifdef HEAP_WITH_DYNALLOC
896
897 /* LOCK */
898 fluid_mutex_lock(heap->mutex);
899
900 evt->next = heap->freelist;
901 heap->freelist = evt;
902
903 /* UNLOCK */
904 fluid_mutex_unlock(heap->mutex);
905
906 #else
907 /* append to the end of the heap */
908 /* critical - should threadlock ? */
909 heap->tail->next = evt;
910 heap->tail = evt;
911 evt->next = NULL;
912 #endif
913 }
914