Path: blob/master/libs/fluidsynth/src/midi/fluid_midi.h
4396 views
/* FluidSynth - A Software Synthesizer1*2* Copyright (C) 2003 Peter Hanappe and others.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public License6* as published by the Free Software Foundation; either version 2.1 of7* the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful, but10* WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* You should have received a copy of the GNU Lesser General Public15* License along with this library; if not, write to the Free16* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA17* 02110-1301, USA18*/1920#ifndef _FLUID_MIDI_H21#define _FLUID_MIDI_H2223#include "fluidsynth_priv.h"24#include "fluid_sys.h"25#include "fluid_list.h"2627typedef struct _fluid_midi_parser_t fluid_midi_parser_t;2829fluid_midi_parser_t *new_fluid_midi_parser(void);30void delete_fluid_midi_parser(fluid_midi_parser_t *parser);31fluid_midi_event_t *fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigned char c);323334/***************************************************************35*36* CONSTANTS & ENUM37*/383940#define MAX_NUMBER_OF_TRACKS 12841#define MAX_NUMBER_OF_CHANNELS 164243enum fluid_midi_event_type44{45/* channel messages */46NOTE_OFF = 0x80,47NOTE_ON = 0x90,48KEY_PRESSURE = 0xa0,49CONTROL_CHANGE = 0xb0,50PROGRAM_CHANGE = 0xc0,51CHANNEL_PRESSURE = 0xd0,52PITCH_BEND = 0xe0,53/* system exclusive */54MIDI_SYSEX = 0xf0,55/* system common - never in midi files */56MIDI_TIME_CODE = 0xf1,57MIDI_SONG_POSITION = 0xf2,58MIDI_SONG_SELECT = 0xf3,59MIDI_TUNE_REQUEST = 0xf6,60MIDI_EOX = 0xf7,61/* system real-time - never in midi files */62MIDI_SYNC = 0xf8,63MIDI_TICK = 0xf9,64MIDI_START = 0xfa,65MIDI_CONTINUE = 0xfb,66MIDI_STOP = 0xfc,67MIDI_ACTIVE_SENSING = 0xfe,68MIDI_SYSTEM_RESET = 0xff,69/* meta event - for midi files only */70MIDI_META_EVENT = 0xff71};7273enum fluid_midi_control_change74{75BANK_SELECT_MSB = 0x00,76MODULATION_MSB = 0x01,77BREATH_MSB = 0x02,78FOOT_MSB = 0x04,79PORTAMENTO_TIME_MSB = 0x05,80DATA_ENTRY_MSB = 0x06,81VOLUME_MSB = 0x07,82BALANCE_MSB = 0x08,83PAN_MSB = 0x0A,84EXPRESSION_MSB = 0x0B,85EFFECTS1_MSB = 0x0C,86EFFECTS2_MSB = 0x0D,87GPC1_MSB = 0x10, /* general purpose controller */88GPC2_MSB = 0x11,89GPC3_MSB = 0x12,90GPC4_MSB = 0x13,91BANK_SELECT_LSB = 0x20,92MODULATION_WHEEL_LSB = 0x21,93BREATH_LSB = 0x22,94FOOT_LSB = 0x24,95PORTAMENTO_TIME_LSB = 0x25,96DATA_ENTRY_LSB = 0x26,97VOLUME_LSB = 0x27,98BALANCE_LSB = 0x28,99PAN_LSB = 0x2A,100EXPRESSION_LSB = 0x2B,101EFFECTS1_LSB = 0x2C,102EFFECTS2_LSB = 0x2D,103GPC1_LSB = 0x30,104GPC2_LSB = 0x31,105GPC3_LSB = 0x32,106GPC4_LSB = 0x33,107SUSTAIN_SWITCH = 0x40,108PORTAMENTO_SWITCH = 0x41,109SOSTENUTO_SWITCH = 0x42,110SOFT_PEDAL_SWITCH = 0x43,111LEGATO_SWITCH = 0x44,112HOLD2_SWITCH = 0x45,113SOUND_CTRL1 = 0x46,114SOUND_CTRL2 = 0x47,115SOUND_CTRL3 = 0x48,116SOUND_CTRL4 = 0x49,117SOUND_CTRL5 = 0x4A,118SOUND_CTRL6 = 0x4B,119SOUND_CTRL7 = 0x4C,120SOUND_CTRL8 = 0x4D,121SOUND_CTRL9 = 0x4E,122SOUND_CTRL10 = 0x4F,123GPC5 = 0x50,124GPC6 = 0x51,125GPC7 = 0x52,126GPC8 = 0x53,127PORTAMENTO_CTRL = 0x54,128EFFECTS_DEPTH1 = 0x5B,129EFFECTS_DEPTH2 = 0x5C,130EFFECTS_DEPTH3 = 0x5D,131EFFECTS_DEPTH4 = 0x5E,132EFFECTS_DEPTH5 = 0x5F,133DATA_ENTRY_INCR = 0x60,134DATA_ENTRY_DECR = 0x61,135NRPN_LSB = 0x62,136NRPN_MSB = 0x63,137RPN_LSB = 0x64,138RPN_MSB = 0x65,139ALL_SOUND_OFF = 0x78,140ALL_CTRL_OFF = 0x79,141LOCAL_CONTROL = 0x7A,142ALL_NOTES_OFF = 0x7B,143OMNI_OFF = 0x7C,144OMNI_ON = 0x7D,145POLY_OFF = 0x7E,146POLY_ON = 0x7F147};148149/* General MIDI RPN event numbers (LSB, MSB = 0) */150enum midi_rpn_event151{152RPN_PITCH_BEND_RANGE = 0x00,153RPN_CHANNEL_FINE_TUNE = 0x01,154RPN_CHANNEL_COARSE_TUNE = 0x02,155RPN_TUNING_PROGRAM_CHANGE = 0x03,156RPN_TUNING_BANK_SELECT = 0x04,157RPN_MODULATION_DEPTH_RANGE = 0x05158};159160enum midi_meta_event161{162MIDI_TEXT = 0x01,163MIDI_COPYRIGHT = 0x02,164MIDI_TRACK_NAME = 0x03,165MIDI_INST_NAME = 0x04,166MIDI_LYRIC = 0x05,167MIDI_MARKER = 0x06,168MIDI_CUE_POINT = 0x07,169MIDI_EOT = 0x2f,170MIDI_SET_TEMPO = 0x51,171MIDI_SMPTE_OFFSET = 0x54,172MIDI_TIME_SIGNATURE = 0x58,173MIDI_KEY_SIGNATURE = 0x59,174MIDI_SEQUENCER_EVENT = 0x7f175};176177/* MIDI SYSEX useful manufacturer values */178enum midi_sysex_manuf179{180MIDI_SYSEX_MANUF_ROLAND = 0x41, /**< Roland manufacturer ID */181MIDI_SYSEX_MANUF_YAMAHA = 0x43,182MIDI_SYSEX_UNIV_NON_REALTIME = 0x7E, /**< Universal non realtime message */183MIDI_SYSEX_UNIV_REALTIME = 0x7F /**< Universal realtime message */184};185186#define MIDI_SYSEX_DEVICE_ID_ALL 0x7F /**< Device ID used in SYSEX messages to indicate all devices */187188/* SYSEX sub-ID #1 which follows device ID */189#define MIDI_SYSEX_MIDI_TUNING_ID 0x08 /**< Sysex sub-ID #1 for MIDI tuning messages */190#define MIDI_SYSEX_GM_ID 0x09 /**< Sysex sub-ID #1 for General MIDI messages */191#define MIDI_SYSEX_GS_ID 0x42 /**< Model ID (GS) serving as sub-ID #1 for GS messages*/192#define MIDI_SYSEX_XG_ID 0x4C /**< Model ID (XG) serving as sub-ID #1 for XG messages*/193194/**195* SYSEX tuning message IDs.196*/197enum midi_sysex_tuning_msg_id198{199MIDI_SYSEX_TUNING_BULK_DUMP_REQ = 0x00, /**< Bulk tuning dump request (non-realtime) */200MIDI_SYSEX_TUNING_BULK_DUMP = 0x01, /**< Bulk tuning dump response (non-realtime) */201MIDI_SYSEX_TUNING_NOTE_TUNE = 0x02, /**< Tuning note change message (realtime) */202MIDI_SYSEX_TUNING_BULK_DUMP_REQ_BANK = 0x03, /**< Bulk tuning dump request (with bank, non-realtime) */203MIDI_SYSEX_TUNING_BULK_DUMP_BANK = 0x04, /**< Bulk tuning dump response (with bank, non-realtime) */204MIDI_SYSEX_TUNING_OCTAVE_DUMP_1BYTE = 0x05, /**< Octave tuning dump using 1 byte values (non-realtime) */205MIDI_SYSEX_TUNING_OCTAVE_DUMP_2BYTE = 0x06, /**< Octave tuning dump using 2 byte values (non-realtime) */206MIDI_SYSEX_TUNING_NOTE_TUNE_BANK = 0x07, /**< Tuning note change message (with bank, realtime/non-realtime) */207MIDI_SYSEX_TUNING_OCTAVE_TUNE_1BYTE = 0x08, /**< Octave tuning message using 1 byte values (realtime/non-realtime) */208MIDI_SYSEX_TUNING_OCTAVE_TUNE_2BYTE = 0x09 /**< Octave tuning message using 2 byte values (realtime/non-realtime) */209};210211/* General MIDI sub-ID #2 */212#define MIDI_SYSEX_GM_ON 0x01 /**< Enable GM mode */213#define MIDI_SYSEX_GM_OFF 0x02 /**< Disable GM mode */214#define MIDI_SYSEX_GM2_ON 0x03 /**< Enable GM2 mode */215#define MIDI_SYSEX_GS_DT1 0x12 /**< GS DT1 command */216217enum fluid_driver_status218{219FLUID_MIDI_READY,220FLUID_MIDI_LISTENING,221FLUID_MIDI_DONE222};223224/***************************************************************225*226* TYPE DEFINITIONS & FUNCTION DECLARATIONS227*/228229/*230* fluid_midi_event_t231*/232struct _fluid_midi_event_t233{234fluid_midi_event_t *next; /* Link to next event */235void *paramptr; /* Pointer parameter (for SYSEX data), size is stored to param1, param2 indicates if pointer should be freed (dynamic if TRUE) */236unsigned int dtime; /* Delay (ticks) between this and previous event. midi tracks. */237unsigned int param1; /* First parameter */238unsigned int param2; /* Second parameter */239unsigned char type; /* MIDI event type */240unsigned char channel; /* MIDI channel */241};242243244/*245* fluid_track_t246*/247struct _fluid_track_t248{249char *name;250int num;251fluid_midi_event_t *first;252fluid_midi_event_t *cur;253fluid_midi_event_t *last;254unsigned int ticks;255};256257typedef struct _fluid_track_t fluid_track_t;258259#define fluid_track_eot(track) ((track)->cur == NULL)260261262/*263* fluid_playlist_item264* Used as the `data' elements of the fluid_player.playlist.265* Represents either a filename or a pre-loaded memory buffer.266* Exactly one of `filename' and `buffer' is non-NULL.267*/268typedef struct269{270char *filename; /** Name of file (owned); NULL if data pre-loaded */271void *buffer; /** The MIDI file data (owned); NULL if filename */272size_t buffer_len; /** Number of bytes in buffer; 0 if filename */273} fluid_playlist_item;274275/* range of tempo values */276#define MIN_TEMPO_VALUE (1.0f)277#define MAX_TEMPO_VALUE (60000000.0f)278/* range of tempo multiplier values */279#define MIN_TEMPO_MULTIPLIER (0.001f)280#define MAX_TEMPO_MULTIPLIER (1000.0f)281282/*283* fluid_player284*/285struct _fluid_player_t286{287fluid_atomic_int_t status;288fluid_atomic_int_t stopping; /* Flag for sending all_notes_off when player is stopped */289int ntracks;290fluid_track_t *track[MAX_NUMBER_OF_TRACKS];291fluid_synth_t *synth;292fluid_timer_t *system_timer;293fluid_sample_timer_t *sample_timer;294295int loop; /* -1 = loop infinitely, otherwise times left to loop the playlist */296fluid_list_t *playlist; /* List of fluid_playlist_item* objects */297fluid_list_t *currentfile; /* points to an item in files, or NULL if not playing */298299char use_system_timer; /* if zero, use sample timers, otherwise use system clock timer */300char reset_synth_between_songs; /* 1 if system reset should be sent to the synth between songs. */301fluid_atomic_int_t seek_ticks; /* new position in tempo ticks (midi ticks) for seeking */302int start_ticks; /* the number of tempo ticks passed at the last tempo change */303int cur_ticks; /* the number of tempo ticks passed */304int last_callback_ticks; /* the last tick number that was passed to player->tick_callback */305int begin_msec; /* the time (msec) of the beginning of the file */306int start_msec; /* the start time of the last tempo change */307unsigned int cur_msec; /* the current time */308int end_msec; /* when >=0, playback is extended until this time (for, e.g., reverb) */309char end_pedals_disabled; /* 1 once the pedals have been released after the last midi event, 0 otherwise */310/* sync mode: indicates the tempo mode the player is driven by (see fluid_player_set_tempo()):3111, the player is driven by internal tempo (miditempo). This is the default.3120, the player is driven by external tempo (exttempo)313*/314int sync_mode;315/* miditempo: internal tempo coming from MIDI file tempo change events316(in micro seconds per quarter note)317*/318int miditempo; /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */319/* exttempo: external tempo set by fluid_player_set_tempo() (in micro seconds per quarter note) */320int exttempo;321/* multempo: tempo multiplier set by fluid_player_set_tempo() */322float multempo;323float deltatime; /* milliseconds per midi tick. depends on current tempo mode (see sync_mode) */324unsigned int division;325326handle_midi_event_func_t playback_callback; /* function fired on each midi event as it is played */327void *playback_userdata; /* pointer to user-defined data passed to playback_callback function */328handle_midi_tick_func_t tick_callback; /* function fired on each tick change */329void *tick_userdata; /* pointer to user-defined data passed to tick_callback function */330331int channel_isplaying[MAX_NUMBER_OF_CHANNELS]; /* flags indicating channels on which notes have played */332};333334#define FLUID_PLAYER_STOP_GRACE_MS 2000335336void fluid_player_settings(fluid_settings_t *settings);337338339/*340* fluid_midi_file341*/342typedef struct343{344const char *buffer; /* Entire contents of MIDI file (borrowed) */345int buf_len; /* Length of buffer, in bytes */346int buf_pos; /* Current read position in contents buffer */347int eof; /* The "end of file" condition */348int running_status;349int c;350int type;351int ntracks;352int uses_smpte;353unsigned int smpte_fps;354unsigned int smpte_res;355unsigned int division; /* If uses_SMPTE == 0 then division is356ticks per beat (quarter-note) */357double tempo; /* Beats per second (SI rules =) */358int tracklen;359int trackpos;360int eot;361int varlen;362int dtime;363} fluid_midi_file;364365366367#define FLUID_MIDI_PARSER_MAX_DATA_SIZE 1024 /**< Maximum size of MIDI parameters/data (largest is SYSEX data) */368369/*370* fluid_midi_parser_t371*/372struct _fluid_midi_parser_t373{374unsigned char status; /* Identifies the type of event, that is currently received ('Noteon', 'Pitch Bend' etc). */375unsigned char channel; /* The channel of the event that is received (in case of a channel event) */376unsigned int nr_bytes; /* How many bytes have been read for the current event? */377unsigned int nr_bytes_total; /* How many bytes does the current event type include? */378unsigned char data[FLUID_MIDI_PARSER_MAX_DATA_SIZE]; /* The parameters or SYSEX data */379fluid_midi_event_t event; /* The event, that is returned to the MIDI driver. */380};381382383#endif /* _FLUID_MIDI_H */384385386