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