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     evt->id = -1;
51 }
52 
53 /**
54  * Create a new sequencer event structure.
55  * @return New sequencer event structure or NULL if out of memory
56  */
57 fluid_event_t *
new_fluid_event()58 new_fluid_event()
59 {
60     fluid_event_t *evt;
61 
62     evt = FLUID_NEW(fluid_event_t);
63 
64     if(evt == NULL)
65     {
66         FLUID_LOG(FLUID_PANIC, "event: Out of memory\n");
67         return NULL;
68     }
69 
70     fluid_event_clear(evt);
71 
72     return(evt);
73 }
74 
75 /**
76  * Delete a sequencer event structure.
77  * @param evt Sequencer event structure created by new_fluid_event().
78  */
79 void
delete_fluid_event(fluid_event_t * evt)80 delete_fluid_event(fluid_event_t *evt)
81 {
82     fluid_return_if_fail(evt != NULL);
83 
84     FLUID_FREE(evt);
85 }
86 
87 /**
88  * Set the time field of a sequencer event.
89  * @internal
90  * @param evt Sequencer event structure
91  * @param time Time value to assign
92  */
93 void
fluid_event_set_time(fluid_event_t * evt,unsigned int time)94 fluid_event_set_time(fluid_event_t *evt, unsigned int time)
95 {
96     evt->time = time;
97 }
98 
99 void
fluid_event_set_id(fluid_event_t * evt,fluid_note_id_t id)100 fluid_event_set_id(fluid_event_t *evt, fluid_note_id_t id)
101 {
102     evt->id = id;
103 }
104 
105 /**
106  * Set source of a sequencer event. \c src must be a unique sequencer ID or -1 if not set.
107  * @param evt Sequencer event structure
108  * @param src Unique sequencer ID
109  */
110 void
fluid_event_set_source(fluid_event_t * evt,fluid_seq_id_t src)111 fluid_event_set_source(fluid_event_t *evt, fluid_seq_id_t src)
112 {
113     evt->src = src;
114 }
115 
116 /**
117  * 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.
118  * @param evt Sequencer event structure
119  * @param dest The destination unique sequencer ID
120  */
121 void
fluid_event_set_dest(fluid_event_t * evt,fluid_seq_id_t dest)122 fluid_event_set_dest(fluid_event_t *evt, fluid_seq_id_t dest)
123 {
124     evt->dest = dest;
125 }
126 
127 /**
128  * Set a sequencer event to be a timer event.
129  * @param evt Sequencer event structure
130  * @param data User supplied data pointer
131  */
132 void
fluid_event_timer(fluid_event_t * evt,void * data)133 fluid_event_timer(fluid_event_t *evt, void *data)
134 {
135     evt->type = FLUID_SEQ_TIMER;
136     evt->data = data;
137 }
138 
139 /**
140  * Set a sequencer event to be a note on event.
141  * @param evt Sequencer event structure
142  * @param channel MIDI channel number
143  * @param key MIDI note number (0-127)
144  * @param vel MIDI velocity value (0-127)
145  * @note Since fluidsynth 2.2.2, this function will give you a #FLUID_SEQ_NOTEOFF when
146  * called with @p vel being zero.
147  */
148 void
fluid_event_noteon(fluid_event_t * evt,int channel,short key,short vel)149 fluid_event_noteon(fluid_event_t *evt, int channel, short key, short vel)
150 {
151     if(vel == 0)
152     {
153         fluid_event_noteoff(evt, channel, key);
154         return;
155     }
156 
157     evt->type = FLUID_SEQ_NOTEON;
158     evt->channel = channel;
159     evt->key = key;
160     evt->vel = vel;
161 }
162 
163 /**
164  * Set a sequencer event to be a note off event.
165  * @param evt Sequencer event structure
166  * @param channel MIDI channel number
167  * @param key MIDI note number (0-127)
168  */
169 void
fluid_event_noteoff(fluid_event_t * evt,int channel,short key)170 fluid_event_noteoff(fluid_event_t *evt, int channel, short key)
171 {
172     evt->type = FLUID_SEQ_NOTEOFF;
173     evt->channel = channel;
174     evt->key = key;
175 }
176 
177 /**
178  * Set a sequencer event to be a note duration event.
179  *
180  * Before fluidsynth 2.2.0, this event type was naively implemented when used in conjunction with fluid_sequencer_register_fluidsynth(),
181  * because it simply enqueued a fluid_event_noteon() and fluid_event_noteoff().
182  * A handling for overlapping notes was not implemented. Starting with 2.2.0, this changes: If a fluid_event_note() is already playing,
183  * while another fluid_event_note() arrives on the same @c channel and @c key, the earlier event will be canceled.
184  * @param evt Sequencer event structure
185  * @param channel MIDI channel number
186  * @param key MIDI note number (0-127)
187  * @param vel MIDI velocity value (1-127)
188  * @param duration Duration of note in the time scale used by the sequencer
189  *
190  * @note The application should decide whether to use only Notes with duration, or separate NoteOn and NoteOff events.
191  * @warning Calling this function with @p vel or @p duration being zero results in undefined behavior!
192  */
193 void
fluid_event_note(fluid_event_t * evt,int channel,short key,short vel,unsigned int duration)194 fluid_event_note(fluid_event_t *evt, int channel, short key, short vel, unsigned int duration)
195 {
196     evt->type = FLUID_SEQ_NOTE;
197     evt->channel = channel;
198     evt->key = key;
199     evt->vel = vel;
200     evt->duration = duration;
201 }
202 
203 /**
204  * Set a sequencer event to be an all sounds off event.
205  * @param evt Sequencer event structure
206  * @param channel MIDI channel number
207  */
208 void
fluid_event_all_sounds_off(fluid_event_t * evt,int channel)209 fluid_event_all_sounds_off(fluid_event_t *evt, int channel)
210 {
211     evt->type = FLUID_SEQ_ALLSOUNDSOFF;
212     evt->channel = channel;
213 }
214 
215 /**
216  * Set a sequencer event to be a all notes off event.
217  * @param evt Sequencer event structure
218  * @param channel MIDI channel number
219  */
220 void
fluid_event_all_notes_off(fluid_event_t * evt,int channel)221 fluid_event_all_notes_off(fluid_event_t *evt, int channel)
222 {
223     evt->type = FLUID_SEQ_ALLNOTESOFF;
224     evt->channel = channel;
225 }
226 
227 /**
228  * Set a sequencer event to be a bank select event.
229  * @param evt Sequencer event structure
230  * @param channel MIDI channel number
231  * @param bank_num MIDI bank number (0-16383)
232  */
233 void
fluid_event_bank_select(fluid_event_t * evt,int channel,short bank_num)234 fluid_event_bank_select(fluid_event_t *evt, int channel, short bank_num)
235 {
236     evt->type = FLUID_SEQ_BANKSELECT;
237     evt->channel = channel;
238     evt->control = bank_num;
239 }
240 
241 /**
242  * Set a sequencer event to be a program change event.
243  * @param evt Sequencer event structure
244  * @param channel MIDI channel number
245  * @param val MIDI program number (0-127)
246  */
247 void
fluid_event_program_change(fluid_event_t * evt,int channel,int val)248 fluid_event_program_change(fluid_event_t *evt, int channel, int val)
249 {
250     evt->type = FLUID_SEQ_PROGRAMCHANGE;
251     evt->channel = channel;
252     evt->value = val;
253 }
254 
255 /**
256  * Set a sequencer event to be a program select event.
257  * @param evt Sequencer event structure
258  * @param channel MIDI channel number
259  * @param sfont_id SoundFont ID number
260  * @param bank_num MIDI bank number (0-16383)
261  * @param preset_num MIDI preset number (0-127)
262  */
263 void
fluid_event_program_select(fluid_event_t * evt,int channel,unsigned int sfont_id,short bank_num,short preset_num)264 fluid_event_program_select(fluid_event_t *evt, int channel,
265                            unsigned int sfont_id, short bank_num, short preset_num)
266 {
267     evt->type = FLUID_SEQ_PROGRAMSELECT;
268     evt->channel = channel;
269     evt->duration = sfont_id;
270     evt->value = preset_num;
271     evt->control = bank_num;
272 }
273 
274 /**
275  * Set a sequencer event to be a pitch bend event.
276  * @param evt Sequencer event structure
277  * @param channel MIDI channel number
278  * @param pitch MIDI pitch bend value (0-16383, 8192 = no bend)
279  */
280 void
fluid_event_pitch_bend(fluid_event_t * evt,int channel,int pitch)281 fluid_event_pitch_bend(fluid_event_t *evt, int channel, int pitch)
282 {
283     evt->type = FLUID_SEQ_PITCHBEND;
284     evt->channel = channel;
285 
286     if(pitch < 0)
287     {
288         pitch = 0;
289     }
290 
291     if(pitch > 16383)
292     {
293         pitch = 16383;
294     }
295 
296     evt->pitch = pitch;
297 }
298 
299 /**
300  * Set a sequencer event to be a pitch wheel sensitivity event.
301  * @param evt Sequencer event structure
302  * @param channel MIDI channel number
303  * @param value MIDI pitch wheel sensitivity value in semitones
304  */
305 void
fluid_event_pitch_wheelsens(fluid_event_t * evt,int channel,int value)306 fluid_event_pitch_wheelsens(fluid_event_t *evt, int channel, int value)
307 {
308     evt->type = FLUID_SEQ_PITCHWHEELSENS;
309     evt->channel = channel;
310     evt->value = value;
311 }
312 
313 /**
314  * Set a sequencer event to be a modulation event.
315  * @param evt Sequencer event structure
316  * @param channel MIDI channel number
317  * @param val MIDI modulation value (0-127)
318  */
319 void
fluid_event_modulation(fluid_event_t * evt,int channel,int val)320 fluid_event_modulation(fluid_event_t *evt, int channel, int val)
321 {
322     evt->type = FLUID_SEQ_MODULATION;
323     evt->channel = channel;
324 
325     if(val < 0)
326     {
327         val = 0;
328     }
329 
330     if(val > 127)
331     {
332         val = 127;
333     }
334 
335     evt->value = val;
336 }
337 
338 /**
339  * Set a sequencer event to be a MIDI sustain event.
340  * @param evt Sequencer event structure
341  * @param channel MIDI channel number
342  * @param val MIDI sustain value (0-127)
343  */
344 void
fluid_event_sustain(fluid_event_t * evt,int channel,int val)345 fluid_event_sustain(fluid_event_t *evt, int channel, int val)
346 {
347     evt->type = FLUID_SEQ_SUSTAIN;
348     evt->channel = channel;
349 
350     if(val < 0)
351     {
352         val = 0;
353     }
354 
355     if(val > 127)
356     {
357         val = 127;
358     }
359 
360     evt->value = val;
361 }
362 
363 /**
364  * Set a sequencer event to be a MIDI control change event.
365  * @param evt Sequencer event structure
366  * @param channel MIDI channel number
367  * @param control MIDI control number (0-127)
368  * @param val MIDI control value (0-127)
369  */
370 void
fluid_event_control_change(fluid_event_t * evt,int channel,short control,int val)371 fluid_event_control_change(fluid_event_t *evt, int channel, short control, int val)
372 {
373     evt->type = FLUID_SEQ_CONTROLCHANGE;
374     evt->channel = channel;
375     evt->control = control;
376     evt->value = val;
377 }
378 
379 /**
380  * Set a sequencer event to be a stereo pan event.
381  * @param evt Sequencer event structure
382  * @param channel MIDI channel number
383  * @param val MIDI panning value (0-127, 0=left, 64 = middle, 127 = right)
384  */
385 void
fluid_event_pan(fluid_event_t * evt,int channel,int val)386 fluid_event_pan(fluid_event_t *evt, int channel, int val)
387 {
388     evt->type = FLUID_SEQ_PAN;
389     evt->channel = channel;
390 
391     if(val < 0)
392     {
393         val = 0;
394     }
395 
396     if(val > 127)
397     {
398         val = 127;
399     }
400 
401     evt->value = val;
402 }
403 
404 /**
405  * Set a sequencer event to be a volume event.
406  * @param evt Sequencer event structure
407  * @param channel MIDI channel number
408  * @param val Volume value (0-127)
409  */
410 void
fluid_event_volume(fluid_event_t * evt,int channel,int val)411 fluid_event_volume(fluid_event_t *evt, int channel, int val)
412 {
413     evt->type = FLUID_SEQ_VOLUME;
414     evt->channel = channel;
415 
416     if(val < 0)
417     {
418         val = 0;
419     }
420 
421     if(val > 127)
422     {
423         val = 127;
424     }
425 
426     evt->value = val;
427 }
428 
429 /**
430  * Set a sequencer event to be a reverb send event.
431  * @param evt Sequencer event structure
432  * @param channel MIDI channel number
433  * @param val Reverb amount (0-127)
434  */
435 void
fluid_event_reverb_send(fluid_event_t * evt,int channel,int val)436 fluid_event_reverb_send(fluid_event_t *evt, int channel, int val)
437 {
438     evt->type = FLUID_SEQ_REVERBSEND;
439     evt->channel = channel;
440 
441     if(val < 0)
442     {
443         val = 0;
444     }
445 
446     if(val > 127)
447     {
448         val = 127;
449     }
450 
451     evt->value = val;
452 }
453 
454 /**
455  * Set a sequencer event to be a chorus send event.
456  * @param evt Sequencer event structure
457  * @param channel MIDI channel number
458  * @param val Chorus amount (0-127)
459  */
460 void
fluid_event_chorus_send(fluid_event_t * evt,int channel,int val)461 fluid_event_chorus_send(fluid_event_t *evt, int channel, int val)
462 {
463     evt->type = FLUID_SEQ_CHORUSSEND;
464     evt->channel = channel;
465 
466     if(val < 0)
467     {
468         val = 0;
469     }
470 
471     if(val > 127)
472     {
473         val = 127;
474     }
475 
476     evt->value = val;
477 }
478 
479 
480 /**
481  * Set a sequencer event to be an unregistering event.
482  * @param evt Sequencer event structure
483  * @since 1.1.0
484  */
485 void
fluid_event_unregistering(fluid_event_t * evt)486 fluid_event_unregistering(fluid_event_t *evt)
487 {
488     evt->type = FLUID_SEQ_UNREGISTERING;
489 }
490 
491 /**
492  * Set a sequencer event to be a scale change event.
493  * Useful for scheduling tempo changes.
494  * @param evt Sequencer event structure
495  * @param new_scale The new time scale to apply to the sequencer, see fluid_sequencer_set_time_scale()
496  * @since 2.2.0
497  */
498 void
fluid_event_scale(fluid_event_t * evt,double new_scale)499 fluid_event_scale(fluid_event_t *evt, double new_scale)
500 {
501     evt->type = FLUID_SEQ_SCALE;
502     evt->scale = new_scale;
503 }
504 
505 /**
506  * Set a sequencer event to be a channel-wide aftertouch event.
507  * @param evt Sequencer event structure
508  * @param channel MIDI channel number
509  * @param val Aftertouch amount (0-127)
510  * @since 1.1.0
511  */
512 void
fluid_event_channel_pressure(fluid_event_t * evt,int channel,int val)513 fluid_event_channel_pressure(fluid_event_t *evt, int channel, int val)
514 {
515     evt->type = FLUID_SEQ_CHANNELPRESSURE;
516     evt->channel = channel;
517 
518     if(val < 0)
519     {
520         val = 0;
521     }
522 
523     if(val > 127)
524     {
525         val = 127;
526     }
527 
528     evt->value = val;
529 }
530 
531 /**
532  * Set a sequencer event to be a polyphonic aftertouch event.
533  * @param evt Sequencer event structure
534  * @param channel MIDI channel number
535  * @param key MIDI note number (0-127)
536  * @param val Aftertouch amount (0-127)
537  * @since 2.0.0
538  */
539 void
fluid_event_key_pressure(fluid_event_t * evt,int channel,short key,int val)540 fluid_event_key_pressure(fluid_event_t *evt, int channel, short key, int val)
541 {
542     evt->type = FLUID_SEQ_KEYPRESSURE;
543     evt->channel = channel;
544 
545     if(key < 0)
546     {
547         key = 0;
548     }
549 
550     if(key > 127)
551     {
552         key = 127;
553     }
554 
555     if(val < 0)
556     {
557         val = 0;
558     }
559 
560     if(val > 127)
561     {
562         val = 127;
563     }
564 
565     evt->key = key;
566     evt->value = val;
567 }
568 
569 /**
570  * Set a sequencer event to be a midi system reset event.
571  * @param evt Sequencer event structure
572  * @since 1.1.0
573  */
574 void
fluid_event_system_reset(fluid_event_t * evt)575 fluid_event_system_reset(fluid_event_t *evt)
576 {
577     evt->type = FLUID_SEQ_SYSTEMRESET;
578 }
579 
580 
581 
582 /*
583  * Accessing event data
584  */
585 
586 /**
587  * Get the event type (#fluid_seq_event_type) field from a sequencer event structure.
588  * @param evt Sequencer event structure
589  * @return Event type (#fluid_seq_event_type).
590  */
fluid_event_get_type(fluid_event_t * evt)591 int fluid_event_get_type(fluid_event_t *evt)
592 {
593     return evt->type;
594 }
595 
596 /**
597  * @internal
598  * Get the time field from a sequencer event structure.
599  * @param evt Sequencer event structure
600  * @return Time value
601  */
fluid_event_get_time(fluid_event_t * evt)602 unsigned int fluid_event_get_time(fluid_event_t *evt)
603 {
604     return evt->time;
605 }
606 
607 /**
608  * @internal
609  * Get the time field from a sequencer event structure.
610  * @param evt Sequencer event structure
611  * @return Time value
612  */
fluid_event_get_id(fluid_event_t * evt)613 fluid_note_id_t fluid_event_get_id(fluid_event_t *evt)
614 {
615     return evt->id;
616 }
617 
618 /**
619  * Get the source sequencer client from a sequencer event structure.
620  * @param evt Sequencer event structure
621  * @return source field of the sequencer event
622  */
fluid_event_get_source(fluid_event_t * evt)623 fluid_seq_id_t fluid_event_get_source(fluid_event_t *evt)
624 {
625     return evt->src;
626 }
627 
628 /**
629  * Get the dest sequencer client from a sequencer event structure.
630  * @param evt Sequencer event structure
631  * @return dest field of the sequencer event
632  */
fluid_event_get_dest(fluid_event_t * evt)633 fluid_seq_id_t fluid_event_get_dest(fluid_event_t *evt)
634 {
635     return evt->dest;
636 }
637 
638 /**
639  * Get the MIDI channel field from a sequencer event structure.
640  * @param evt Sequencer event structure
641  * @return MIDI zero-based channel number
642  */
fluid_event_get_channel(fluid_event_t * evt)643 int fluid_event_get_channel(fluid_event_t *evt)
644 {
645     return evt->channel;
646 }
647 
648 /**
649  * Get the MIDI note field from a sequencer event structure.
650  * @param evt Sequencer event structure
651  * @return MIDI note number (0-127)
652  */
fluid_event_get_key(fluid_event_t * evt)653 short fluid_event_get_key(fluid_event_t *evt)
654 {
655     return evt->key;
656 }
657 
658 /**
659  * Get the MIDI velocity field from a sequencer event structure.
660  * @param evt Sequencer event structure
661  * @return MIDI velocity value (0-127)
662  */
fluid_event_get_velocity(fluid_event_t * evt)663 short fluid_event_get_velocity(fluid_event_t *evt)
664 
665 {
666     return evt->vel;
667 }
668 
669 /**
670  * Get the MIDI control number field from a sequencer event structure.
671  * @param evt Sequencer event structure
672  * @return MIDI control number (0-127)
673  */
fluid_event_get_control(fluid_event_t * evt)674 short fluid_event_get_control(fluid_event_t *evt)
675 {
676     return evt->control;
677 }
678 
679 /**
680  * Get the value field from a sequencer event structure.
681  * @param evt Sequencer event structure
682  * @return Value field of event.
683  *
684  * The Value field is used by the following event types:
685  * #FLUID_SEQ_PROGRAMCHANGE, #FLUID_SEQ_PROGRAMSELECT (preset_num),
686  * #FLUID_SEQ_PITCHWHEELSENS, #FLUID_SEQ_MODULATION, #FLUID_SEQ_SUSTAIN,
687  * #FLUID_SEQ_CONTROLCHANGE, #FLUID_SEQ_PAN, #FLUID_SEQ_VOLUME,
688  * #FLUID_SEQ_REVERBSEND, #FLUID_SEQ_CHORUSSEND.
689  */
fluid_event_get_value(fluid_event_t * evt)690 int fluid_event_get_value(fluid_event_t *evt)
691 {
692     return evt->value;
693 }
694 
695 /**
696  * Get the data field from a sequencer event structure.
697  * @param evt Sequencer event structure
698  * @return Data field of event.
699  *
700  * Used by the #FLUID_SEQ_TIMER event type.
701  */
fluid_event_get_data(fluid_event_t * evt)702 void *fluid_event_get_data(fluid_event_t *evt)
703 {
704     return evt->data;
705 }
706 
707 /**
708  * Get the duration field from a sequencer event structure.
709  * @param evt Sequencer event structure
710  * @return Note duration value in the time scale used by the sequencer (by default milliseconds)
711  *
712  * Used by the #FLUID_SEQ_NOTE event type.
713  */
fluid_event_get_duration(fluid_event_t * evt)714 unsigned int fluid_event_get_duration(fluid_event_t *evt)
715 {
716     return evt->duration;
717 }
718 
719 /**
720  * Get the MIDI bank field from a sequencer event structure.
721  * @param evt Sequencer event structure
722  * @return MIDI bank number (0-16383)
723  *
724  * Used by the #FLUID_SEQ_BANKSELECT and #FLUID_SEQ_PROGRAMSELECT
725  * event types.
726  */
fluid_event_get_bank(fluid_event_t * evt)727 short fluid_event_get_bank(fluid_event_t *evt)
728 {
729     return evt->control;
730 }
731 
732 /**
733  * Get the pitch field from a sequencer event structure.
734  * @param evt Sequencer event structure
735  * @return MIDI pitch bend pitch value (0-16383, 8192 = no bend)
736  *
737  * Used by the #FLUID_SEQ_PITCHBEND event type.
738  */
fluid_event_get_pitch(fluid_event_t * evt)739 int fluid_event_get_pitch(fluid_event_t *evt)
740 {
741     return evt->pitch;
742 }
743 
744 /**
745  * Get the MIDI program field from a sequencer event structure.
746  * @param evt Sequencer event structure
747  * @return MIDI program number (0-127)
748  *
749  * Used by the #FLUID_SEQ_PROGRAMCHANGE and #FLUID_SEQ_PROGRAMSELECT
750  * event types.
751  */
752 int
fluid_event_get_program(fluid_event_t * evt)753 fluid_event_get_program(fluid_event_t *evt)
754 {
755     return evt->value;
756 }
757 
758 /**
759  * Get the SoundFont ID field from a sequencer event structure.
760  * @param evt Sequencer event structure
761  * @return SoundFont identifier value.
762  *
763  * Used by the #FLUID_SEQ_PROGRAMSELECT event type.
764  */
765 unsigned int
fluid_event_get_sfont_id(fluid_event_t * evt)766 fluid_event_get_sfont_id(fluid_event_t *evt)
767 {
768     return evt->duration;
769 }
770 
771 /**
772  * Gets time scale field from a sequencer event structure.
773  * @param evt Sequencer event structure
774  * @return SoundFont identifier value.
775  *
776  * Used by the #FLUID_SEQ_SCALE event type.
777  */
fluid_event_get_scale(fluid_event_t * evt)778 double fluid_event_get_scale(fluid_event_t *evt)
779 {
780     return evt->scale;
781 }
782