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