1 /* FluidSynth - A Software Synthesizer
3 * Copyright (C) 2003 Peter Hanappe and others.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU 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.
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.
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
24 #include "fluidsynth_priv.h"
25 #include "fluid_sys.h"
26 #include "fluid_list.h"
28 typedef struct _fluid_midi_parser_t fluid_midi_parser_t;
30 fluid_midi_parser_t *new_fluid_midi_parser(void);
31 void delete_fluid_midi_parser(fluid_midi_parser_t *parser);
32 fluid_midi_event_t *fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigned char c);
35 /***************************************************************
41 #define MAX_NUMBER_OF_TRACKS 128
43 enum fluid_midi_event_type
45 /* channel messages */
49 CONTROL_CHANGE = 0xb0,
50 PROGRAM_CHANGE = 0xc0,
51 CHANNEL_PRESSURE = 0xd0,
53 /* system exclusive */
55 /* system common - never in midi files */
56 MIDI_TIME_CODE = 0xf1,
57 MIDI_SONG_POSITION = 0xf2,
58 MIDI_SONG_SELECT = 0xf3,
59 MIDI_TUNE_REQUEST = 0xf6,
61 /* system real-time - never in midi files */
67 MIDI_ACTIVE_SENSING = 0xfe,
68 MIDI_SYSTEM_RESET = 0xff,
69 /* meta event - for midi files only */
70 MIDI_META_EVENT = 0xff
73 enum fluid_midi_control_change
75 BANK_SELECT_MSB = 0x00,
76 MODULATION_MSB = 0x01,
79 PORTAMENTO_TIME_MSB = 0x05,
80 DATA_ENTRY_MSB = 0x06,
84 EXPRESSION_MSB = 0x0B,
87 GPC1_MSB = 0x10, /* general purpose controller */
91 BANK_SELECT_LSB = 0x20,
92 MODULATION_WHEEL_LSB = 0x21,
95 PORTAMENTO_TIME_LSB = 0x25,
96 DATA_ENTRY_LSB = 0x26,
100 EXPRESSION_LSB = 0x2B,
107 SUSTAIN_SWITCH = 0x40,
108 PORTAMENTO_SWITCH = 0x41,
109 SOSTENUTO_SWITCH = 0x42,
110 SOFT_PEDAL_SWITCH = 0x43,
111 LEGATO_SWITCH = 0x44,
127 PORTAMENTO_CTRL = 0x54,
128 EFFECTS_DEPTH1 = 0x5B,
129 EFFECTS_DEPTH2 = 0x5C,
130 EFFECTS_DEPTH3 = 0x5D,
131 EFFECTS_DEPTH4 = 0x5E,
132 EFFECTS_DEPTH5 = 0x5F,
133 DATA_ENTRY_INCR = 0x60,
134 DATA_ENTRY_DECR = 0x61,
139 ALL_SOUND_OFF = 0x78,
141 LOCAL_CONTROL = 0x7A,
142 ALL_NOTES_OFF = 0x7B,
149 /* General MIDI RPN event numbers (LSB, MSB = 0) */
152 RPN_PITCH_BEND_RANGE = 0x00,
153 RPN_CHANNEL_FINE_TUNE = 0x01,
154 RPN_CHANNEL_COARSE_TUNE = 0x02,
155 RPN_TUNING_PROGRAM_CHANGE = 0x03,
156 RPN_TUNING_BANK_SELECT = 0x04,
157 RPN_MODULATION_DEPTH_RANGE = 0x05
163 MIDI_COPYRIGHT = 0x02,
164 MIDI_TRACK_NAME = 0x03,
165 MIDI_INST_NAME = 0x04,
168 MIDI_CUE_POINT = 0x07,
170 MIDI_SET_TEMPO = 0x51,
171 MIDI_SMPTE_OFFSET = 0x54,
172 MIDI_TIME_SIGNATURE = 0x58,
173 MIDI_KEY_SIGNATURE = 0x59,
174 MIDI_SEQUENCER_EVENT = 0x7f
177 /* MIDI SYSEX useful manufacturer values */
178 enum midi_sysex_manuf
180 MIDI_SYSEX_MANUF_ROLAND = 0x41, /**< Roland manufacturer ID */
181 MIDI_SYSEX_UNIV_NON_REALTIME = 0x7E, /**< Universal non realtime message */
182 MIDI_SYSEX_UNIV_REALTIME = 0x7F /**< Universal realtime message */
185 #define MIDI_SYSEX_DEVICE_ID_ALL 0x7F /**< Device ID used in SYSEX messages to indicate all devices */
187 /* SYSEX sub-ID #1 which follows device ID */
188 #define MIDI_SYSEX_MIDI_TUNING_ID 0x08 /**< Sysex sub-ID #1 for MIDI tuning messages */
189 #define MIDI_SYSEX_GM_ID 0x09 /**< Sysex sub-ID #1 for General MIDI messages */
192 * SYSEX tuning message IDs.
194 enum midi_sysex_tuning_msg_id
196 MIDI_SYSEX_TUNING_BULK_DUMP_REQ = 0x00, /**< Bulk tuning dump request (non-realtime) */
197 MIDI_SYSEX_TUNING_BULK_DUMP = 0x01, /**< Bulk tuning dump response (non-realtime) */
198 MIDI_SYSEX_TUNING_NOTE_TUNE = 0x02, /**< Tuning note change message (realtime) */
199 MIDI_SYSEX_TUNING_BULK_DUMP_REQ_BANK = 0x03, /**< Bulk tuning dump request (with bank, non-realtime) */
200 MIDI_SYSEX_TUNING_BULK_DUMP_BANK = 0x04, /**< Bulk tuning dump resonse (with bank, non-realtime) */
201 MIDI_SYSEX_TUNING_OCTAVE_DUMP_1BYTE = 0x05, /**< Octave tuning dump using 1 byte values (non-realtime) */
202 MIDI_SYSEX_TUNING_OCTAVE_DUMP_2BYTE = 0x06, /**< Octave tuning dump using 2 byte values (non-realtime) */
203 MIDI_SYSEX_TUNING_NOTE_TUNE_BANK = 0x07, /**< Tuning note change message (with bank, realtime/non-realtime) */
204 MIDI_SYSEX_TUNING_OCTAVE_TUNE_1BYTE = 0x08, /**< Octave tuning message using 1 byte values (realtime/non-realtime) */
205 MIDI_SYSEX_TUNING_OCTAVE_TUNE_2BYTE = 0x09 /**< Octave tuning message using 2 byte values (realtime/non-realtime) */
208 /* General MIDI sub-ID #2 */
209 #define MIDI_SYSEX_GM_ON 0x01 /**< Enable GM mode */
210 #define MIDI_SYSEX_GM_OFF 0x02 /**< Disable GM mode */
212 enum fluid_driver_status
215 FLUID_MIDI_LISTENING,
219 /***************************************************************
221 * TYPE DEFINITIONS & FUNCTION DECLARATIONS
227 struct _fluid_midi_event_t
229 fluid_midi_event_t *next; /* Link to next event */
230 void *paramptr; /* Pointer parameter (for SYSEX data), size is stored to param1, param2 indicates if pointer should be freed (dynamic if TRUE) */
231 unsigned int dtime; /* Delay (ticks) between this and previous event. midi tracks. */
232 unsigned int param1; /* First parameter */
233 unsigned int param2; /* Second parameter */
234 unsigned char type; /* MIDI event type */
235 unsigned char channel; /* MIDI channel */
242 struct _fluid_track_t
246 fluid_midi_event_t *first;
247 fluid_midi_event_t *cur;
248 fluid_midi_event_t *last;
252 typedef struct _fluid_track_t fluid_track_t;
254 #define fluid_track_eot(track) ((track)->cur == NULL)
258 * fluid_playlist_item
259 * Used as the `data' elements of the fluid_player.playlist.
260 * Represents either a filename or a pre-loaded memory buffer.
261 * Exactly one of `filename' and `buffer' is non-NULL.
265 char *filename; /** Name of file (owned); NULL if data pre-loaded */
266 void *buffer; /** The MIDI file data (owned); NULL if filename */
267 size_t buffer_len; /** Number of bytes in buffer; 0 if filename */
268 } fluid_playlist_item;
273 struct _fluid_player_t
277 fluid_track_t *track[MAX_NUMBER_OF_TRACKS];
278 fluid_synth_t *synth;
279 fluid_timer_t *system_timer;
280 fluid_sample_timer_t *sample_timer;
282 int loop; /* -1 = loop infinitely, otherwise times left to loop the playlist */
283 fluid_list_t *playlist; /* List of fluid_playlist_item* objects */
284 fluid_list_t *currentfile; /* points to an item in files, or NULL if not playing */
286 char send_program_change; /* should we ignore the program changes? */
287 char use_system_timer; /* if zero, use sample timers, otherwise use system clock timer */
288 char reset_synth_between_songs; /* 1 if system reset should be sent to the synth between songs. */
289 int seek_ticks; /* new position in tempo ticks (midi ticks) for seeking */
290 int start_ticks; /* the number of tempo ticks passed at the last tempo change */
291 int cur_ticks; /* the number of tempo ticks passed */
292 int begin_msec; /* the time (msec) of the beginning of the file */
293 int start_msec; /* the start time of the last tempo change */
294 int cur_msec; /* the current time */
295 int miditempo; /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */
296 double deltatime; /* milliseconds per midi tick. depends on set-tempo */
297 unsigned int division;
299 handle_midi_event_func_t playback_callback; /* function fired on each midi event as it is played */
300 void *playback_userdata; /* pointer to user-defined data passed to playback_callback function */
303 void fluid_player_settings(fluid_settings_t *settings);
311 const char *buffer; /* Entire contents of MIDI file (borrowed) */
312 int buf_len; /* Length of buffer, in bytes */
313 int buf_pos; /* Current read position in contents buffer */
314 int eof; /* The "end of file" condition */
320 unsigned int smpte_fps;
321 unsigned int smpte_res;
322 unsigned int division; /* If uses_SMPTE == 0 then division is
323 ticks per beat (quarter-note) */
324 double tempo; /* Beats per second (SI rules =) */
334 #define FLUID_MIDI_PARSER_MAX_DATA_SIZE 1024 /**< Maximum size of MIDI parameters/data (largest is SYSEX data) */
337 * fluid_midi_parser_t
339 struct _fluid_midi_parser_t
341 unsigned char status; /* Identifies the type of event, that is currently received ('Noteon', 'Pitch Bend' etc). */
342 unsigned char channel; /* The channel of the event that is received (in case of a channel event) */
343 unsigned int nr_bytes; /* How many bytes have been read for the current event? */
344 unsigned int nr_bytes_total; /* How many bytes does the current event type include? */
345 unsigned char data[FLUID_MIDI_PARSER_MAX_DATA_SIZE]; /* The parameters or SYSEX data */
346 fluid_midi_event_t event; /* The event, that is returned to the MIDI driver. */
350 #endif /* _FLUID_MIDI_H */