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 #ifndef _FLUID_MIDI_H 22 #define _FLUID_MIDI_H 23 24 #include "fluidsynth_priv.h" 25 #include "fluid_sys.h" 26 #include "fluid_list.h" 27 28 typedef struct _fluid_midi_parser_t fluid_midi_parser_t; 29 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); 33 34 35 /*************************************************************** 36 * 37 * CONSTANTS & ENUM 38 */ 39 40 41 #define MAX_NUMBER_OF_TRACKS 128 42 43 enum fluid_midi_event_type 44 { 45 /* channel messages */ 46 NOTE_OFF = 0x80, 47 NOTE_ON = 0x90, 48 KEY_PRESSURE = 0xa0, 49 CONTROL_CHANGE = 0xb0, 50 PROGRAM_CHANGE = 0xc0, 51 CHANNEL_PRESSURE = 0xd0, 52 PITCH_BEND = 0xe0, 53 /* system exclusive */ 54 MIDI_SYSEX = 0xf0, 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, 60 MIDI_EOX = 0xf7, 61 /* system real-time - never in midi files */ 62 MIDI_SYNC = 0xf8, 63 MIDI_TICK = 0xf9, 64 MIDI_START = 0xfa, 65 MIDI_CONTINUE = 0xfb, 66 MIDI_STOP = 0xfc, 67 MIDI_ACTIVE_SENSING = 0xfe, 68 MIDI_SYSTEM_RESET = 0xff, 69 /* meta event - for midi files only */ 70 MIDI_META_EVENT = 0xff 71 }; 72 73 enum fluid_midi_control_change 74 { 75 BANK_SELECT_MSB = 0x00, 76 MODULATION_MSB = 0x01, 77 BREATH_MSB = 0x02, 78 FOOT_MSB = 0x04, 79 PORTAMENTO_TIME_MSB = 0x05, 80 DATA_ENTRY_MSB = 0x06, 81 VOLUME_MSB = 0x07, 82 BALANCE_MSB = 0x08, 83 PAN_MSB = 0x0A, 84 EXPRESSION_MSB = 0x0B, 85 EFFECTS1_MSB = 0x0C, 86 EFFECTS2_MSB = 0x0D, 87 GPC1_MSB = 0x10, /* general purpose controller */ 88 GPC2_MSB = 0x11, 89 GPC3_MSB = 0x12, 90 GPC4_MSB = 0x13, 91 BANK_SELECT_LSB = 0x20, 92 MODULATION_WHEEL_LSB = 0x21, 93 BREATH_LSB = 0x22, 94 FOOT_LSB = 0x24, 95 PORTAMENTO_TIME_LSB = 0x25, 96 DATA_ENTRY_LSB = 0x26, 97 VOLUME_LSB = 0x27, 98 BALANCE_LSB = 0x28, 99 PAN_LSB = 0x2A, 100 EXPRESSION_LSB = 0x2B, 101 EFFECTS1_LSB = 0x2C, 102 EFFECTS2_LSB = 0x2D, 103 GPC1_LSB = 0x30, 104 GPC2_LSB = 0x31, 105 GPC3_LSB = 0x32, 106 GPC4_LSB = 0x33, 107 SUSTAIN_SWITCH = 0x40, 108 PORTAMENTO_SWITCH = 0x41, 109 SOSTENUTO_SWITCH = 0x42, 110 SOFT_PEDAL_SWITCH = 0x43, 111 LEGATO_SWITCH = 0x44, 112 HOLD2_SWITCH = 0x45, 113 SOUND_CTRL1 = 0x46, 114 SOUND_CTRL2 = 0x47, 115 SOUND_CTRL3 = 0x48, 116 SOUND_CTRL4 = 0x49, 117 SOUND_CTRL5 = 0x4A, 118 SOUND_CTRL6 = 0x4B, 119 SOUND_CTRL7 = 0x4C, 120 SOUND_CTRL8 = 0x4D, 121 SOUND_CTRL9 = 0x4E, 122 SOUND_CTRL10 = 0x4F, 123 GPC5 = 0x50, 124 GPC6 = 0x51, 125 GPC7 = 0x52, 126 GPC8 = 0x53, 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, 135 NRPN_LSB = 0x62, 136 NRPN_MSB = 0x63, 137 RPN_LSB = 0x64, 138 RPN_MSB = 0x65, 139 ALL_SOUND_OFF = 0x78, 140 ALL_CTRL_OFF = 0x79, 141 LOCAL_CONTROL = 0x7A, 142 ALL_NOTES_OFF = 0x7B, 143 OMNI_OFF = 0x7C, 144 OMNI_ON = 0x7D, 145 POLY_OFF = 0x7E, 146 POLY_ON = 0x7F 147 }; 148 149 /* General MIDI RPN event numbers (LSB, MSB = 0) */ 150 enum midi_rpn_event 151 { 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 158 }; 159 160 enum midi_meta_event 161 { 162 MIDI_TEXT = 0x01, 163 MIDI_COPYRIGHT = 0x02, 164 MIDI_TRACK_NAME = 0x03, 165 MIDI_INST_NAME = 0x04, 166 MIDI_LYRIC = 0x05, 167 MIDI_MARKER = 0x06, 168 MIDI_CUE_POINT = 0x07, 169 MIDI_EOT = 0x2f, 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 175 }; 176 177 /* MIDI SYSEX useful manufacturer values */ 178 enum midi_sysex_manuf 179 { 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 */ 183 }; 184 185 #define MIDI_SYSEX_DEVICE_ID_ALL 0x7F /**< Device ID used in SYSEX messages to indicate all devices */ 186 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 */ 190 #define MIDI_SYSEX_GS_ID 0x42 /**< Model ID (GS) serving as sub-ID #1 for GS messages*/ 191 192 /** 193 * SYSEX tuning message IDs. 194 */ 195 enum midi_sysex_tuning_msg_id 196 { 197 MIDI_SYSEX_TUNING_BULK_DUMP_REQ = 0x00, /**< Bulk tuning dump request (non-realtime) */ 198 MIDI_SYSEX_TUNING_BULK_DUMP = 0x01, /**< Bulk tuning dump response (non-realtime) */ 199 MIDI_SYSEX_TUNING_NOTE_TUNE = 0x02, /**< Tuning note change message (realtime) */ 200 MIDI_SYSEX_TUNING_BULK_DUMP_REQ_BANK = 0x03, /**< Bulk tuning dump request (with bank, non-realtime) */ 201 MIDI_SYSEX_TUNING_BULK_DUMP_BANK = 0x04, /**< Bulk tuning dump resonse (with bank, non-realtime) */ 202 MIDI_SYSEX_TUNING_OCTAVE_DUMP_1BYTE = 0x05, /**< Octave tuning dump using 1 byte values (non-realtime) */ 203 MIDI_SYSEX_TUNING_OCTAVE_DUMP_2BYTE = 0x06, /**< Octave tuning dump using 2 byte values (non-realtime) */ 204 MIDI_SYSEX_TUNING_NOTE_TUNE_BANK = 0x07, /**< Tuning note change message (with bank, realtime/non-realtime) */ 205 MIDI_SYSEX_TUNING_OCTAVE_TUNE_1BYTE = 0x08, /**< Octave tuning message using 1 byte values (realtime/non-realtime) */ 206 MIDI_SYSEX_TUNING_OCTAVE_TUNE_2BYTE = 0x09 /**< Octave tuning message using 2 byte values (realtime/non-realtime) */ 207 }; 208 209 /* General MIDI sub-ID #2 */ 210 #define MIDI_SYSEX_GM_ON 0x01 /**< Enable GM mode */ 211 #define MIDI_SYSEX_GM_OFF 0x02 /**< Disable GM mode */ 212 #define MIDI_SYSEX_GS_DT1 0x12 /**< GS DT1 command */ 213 214 enum fluid_driver_status 215 { 216 FLUID_MIDI_READY, 217 FLUID_MIDI_LISTENING, 218 FLUID_MIDI_DONE 219 }; 220 221 /*************************************************************** 222 * 223 * TYPE DEFINITIONS & FUNCTION DECLARATIONS 224 */ 225 226 /* 227 * fluid_midi_event_t 228 */ 229 struct _fluid_midi_event_t 230 { 231 fluid_midi_event_t *next; /* Link to next event */ 232 void *paramptr; /* Pointer parameter (for SYSEX data), size is stored to param1, param2 indicates if pointer should be freed (dynamic if TRUE) */ 233 unsigned int dtime; /* Delay (ticks) between this and previous event. midi tracks. */ 234 unsigned int param1; /* First parameter */ 235 unsigned int param2; /* Second parameter */ 236 unsigned char type; /* MIDI event type */ 237 unsigned char channel; /* MIDI channel */ 238 }; 239 240 241 /* 242 * fluid_track_t 243 */ 244 struct _fluid_track_t 245 { 246 char *name; 247 int num; 248 fluid_midi_event_t *first; 249 fluid_midi_event_t *cur; 250 fluid_midi_event_t *last; 251 unsigned int ticks; 252 }; 253 254 typedef struct _fluid_track_t fluid_track_t; 255 256 #define fluid_track_eot(track) ((track)->cur == NULL) 257 258 259 /* 260 * fluid_playlist_item 261 * Used as the `data' elements of the fluid_player.playlist. 262 * Represents either a filename or a pre-loaded memory buffer. 263 * Exactly one of `filename' and `buffer' is non-NULL. 264 */ 265 typedef struct 266 { 267 char *filename; /** Name of file (owned); NULL if data pre-loaded */ 268 void *buffer; /** The MIDI file data (owned); NULL if filename */ 269 size_t buffer_len; /** Number of bytes in buffer; 0 if filename */ 270 } fluid_playlist_item; 271 272 /* range of tempo values */ 273 #define MIN_TEMPO_VALUE (1.0f) 274 #define MAX_TEMPO_VALUE (60000000.0f) 275 /* range of tempo multiplier values */ 276 #define MIN_TEMPO_MULTIPLIER (0.001f) 277 #define MAX_TEMPO_MULTIPLIER (1000.0f) 278 279 /* 280 * fluid_player 281 */ 282 struct _fluid_player_t 283 { 284 fluid_atomic_int_t status; 285 int ntracks; 286 fluid_track_t *track[MAX_NUMBER_OF_TRACKS]; 287 fluid_synth_t *synth; 288 fluid_timer_t *system_timer; 289 fluid_sample_timer_t *sample_timer; 290 291 int loop; /* -1 = loop infinitely, otherwise times left to loop the playlist */ 292 fluid_list_t *playlist; /* List of fluid_playlist_item* objects */ 293 fluid_list_t *currentfile; /* points to an item in files, or NULL if not playing */ 294 295 char use_system_timer; /* if zero, use sample timers, otherwise use system clock timer */ 296 char reset_synth_between_songs; /* 1 if system reset should be sent to the synth between songs. */ 297 fluid_atomic_int_t seek_ticks; /* new position in tempo ticks (midi ticks) for seeking */ 298 int start_ticks; /* the number of tempo ticks passed at the last tempo change */ 299 int cur_ticks; /* the number of tempo ticks passed */ 300 int last_callback_ticks; /* the last tick number that was passed to player->tick_callback */ 301 int begin_msec; /* the time (msec) of the beginning of the file */ 302 int start_msec; /* the start time of the last tempo change */ 303 int cur_msec; /* the current time */ 304 /* sync mode: indicates the tempo mode the player is driven by (see fluid_player_set_tempo()): 305 1, the player is driven by internal tempo (miditempo). This is the default. 306 0, the player is driven by external tempo (exttempo) 307 */ 308 int sync_mode; 309 /* miditempo: internal tempo comming from MIDI file tempo change events 310 (in micro seconds per quarter note) 311 */ 312 int miditempo; /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */ 313 /* exttempo: external tempo set by fluid_player_set_tempo() (in micro seconds per quarter note) */ 314 int exttempo; 315 /* multempo: tempo multiplier set by fluid_player_set_tempo() */ 316 float multempo; 317 float deltatime; /* milliseconds per midi tick. depends on current tempo mode (see sync_mode) */ 318 unsigned int division; 319 320 handle_midi_event_func_t playback_callback; /* function fired on each midi event as it is played */ 321 void *playback_userdata; /* pointer to user-defined data passed to playback_callback function */ 322 handle_midi_tick_func_t tick_callback; /* function fired on each tick change */ 323 void *tick_userdata; /* pointer to user-defined data passed to tick_callback function */ 324 }; 325 326 void fluid_player_settings(fluid_settings_t *settings); 327 328 329 /* 330 * fluid_midi_file 331 */ 332 typedef struct 333 { 334 const char *buffer; /* Entire contents of MIDI file (borrowed) */ 335 int buf_len; /* Length of buffer, in bytes */ 336 int buf_pos; /* Current read position in contents buffer */ 337 int eof; /* The "end of file" condition */ 338 int running_status; 339 int c; 340 int type; 341 int ntracks; 342 int uses_smpte; 343 unsigned int smpte_fps; 344 unsigned int smpte_res; 345 unsigned int division; /* If uses_SMPTE == 0 then division is 346 ticks per beat (quarter-note) */ 347 double tempo; /* Beats per second (SI rules =) */ 348 int tracklen; 349 int trackpos; 350 int eot; 351 int varlen; 352 int dtime; 353 } fluid_midi_file; 354 355 356 357 #define FLUID_MIDI_PARSER_MAX_DATA_SIZE 1024 /**< Maximum size of MIDI parameters/data (largest is SYSEX data) */ 358 359 /* 360 * fluid_midi_parser_t 361 */ 362 struct _fluid_midi_parser_t 363 { 364 unsigned char status; /* Identifies the type of event, that is currently received ('Noteon', 'Pitch Bend' etc). */ 365 unsigned char channel; /* The channel of the event that is received (in case of a channel event) */ 366 unsigned int nr_bytes; /* How many bytes have been read for the current event? */ 367 unsigned int nr_bytes_total; /* How many bytes does the current event type include? */ 368 unsigned char data[FLUID_MIDI_PARSER_MAX_DATA_SIZE]; /* The parameters or SYSEX data */ 369 fluid_midi_event_t event; /* The event, that is returned to the MIDI driver. */ 370 }; 371 372 373 #endif /* _FLUID_MIDI_H */ 374