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