fluid_midi.h
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:12k
源码类别:

midi

开发平台:

C/C++

  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 Library General Public License
  7.  * as published by the Free Software Foundation; either version 2 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.  * Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18.  * 02111-1307, USA
  19.  */
  20. #ifndef _FLUID_MIDI_H
  21. #define _FLUID_MIDI_H
  22. #include "fluidsynth_priv.h"
  23. #include "fluid_sys.h"
  24. #include "fluid_list.h"
  25. typedef struct _fluid_midi_parser_t fluid_midi_parser_t;
  26. fluid_midi_parser_t* new_fluid_midi_parser(void);
  27. int delete_fluid_midi_parser(fluid_midi_parser_t* parser);
  28. fluid_midi_event_t* fluid_midi_parser_parse(fluid_midi_parser_t* parser, unsigned char c);
  29. /***************************************************************
  30.  *
  31.  *                   CONSTANTS & ENUM
  32.  */
  33. #define MAX_NUMBER_OF_TRACKS 128
  34. enum fluid_midi_event_type {
  35.   /* channel messages */
  36.   NOTE_OFF = 0x80,
  37.   NOTE_ON = 0x90,
  38.   KEY_PRESSURE = 0xa0,
  39.   CONTROL_CHANGE = 0xb0,
  40.   PROGRAM_CHANGE = 0xc0,
  41.   CHANNEL_PRESSURE = 0xd0,
  42.   PITCH_BEND = 0xe0,
  43.   /* system exclusive */
  44.   MIDI_SYSEX = 0xf0,
  45.   /* system common - never in midi files */
  46.   MIDI_TIME_CODE = 0xf1,
  47.   MIDI_SONG_POSITION = 0xf2,
  48.   MIDI_SONG_SELECT = 0xf3,
  49.   MIDI_TUNE_REQUEST = 0xf6,
  50.   MIDI_EOX = 0xf7,
  51.   /* system real-time - never in midi files */
  52.   MIDI_SYNC = 0xf8,
  53.   MIDI_TICK = 0xf9,
  54.   MIDI_START = 0xfa,
  55.   MIDI_CONTINUE = 0xfb,
  56.   MIDI_STOP = 0xfc,
  57.   MIDI_ACTIVE_SENSING = 0xfe,
  58.   MIDI_SYSTEM_RESET = 0xff,
  59.   /* meta event - for midi files only */
  60.   MIDI_META_EVENT = 0xff
  61. };
  62. enum fluid_midi_control_change {
  63.   BANK_SELECT_MSB = 0x00,
  64.   MODULATION_MSB = 0x01,
  65.   BREATH_MSB = 0x02,
  66.   FOOT_MSB = 0x04,
  67.   PORTAMENTO_TIME_MSB = 0x05,
  68.   DATA_ENTRY_MSB = 0x06,
  69.   VOLUME_MSB = 0x07,
  70.   BALANCE_MSB = 0x08,
  71.   PAN_MSB = 0x0A,
  72.   EXPRESSION_MSB = 0x0B,
  73.   EFFECTS1_MSB = 0x0C,
  74.   EFFECTS2_MSB = 0x0D,
  75.   GPC1_MSB = 0x10, /* general purpose controller */
  76.   GPC2_MSB = 0x11,
  77.   GPC3_MSB = 0x12,
  78.   GPC4_MSB = 0x13,
  79.   BANK_SELECT_LSB = 0x20,
  80.   MODULATION_WHEEL_LSB = 0x21,
  81.   BREATH_LSB = 0x22,
  82.   FOOT_LSB = 0x24,
  83.   PORTAMENTO_TIME_LSB = 0x25,
  84.   DATA_ENTRY_LSB = 0x26,
  85.   VOLUME_LSB = 0x27,
  86.   BALANCE_LSB = 0x28,
  87.   PAN_LSB = 0x2A,
  88.   EXPRESSION_LSB = 0x2B,
  89.   EFFECTS1_LSB = 0x2C,
  90.   EFFECTS2_LSB = 0x2D,
  91.   GPC1_LSB = 0x30,
  92.   GPC2_LSB = 0x31,
  93.   GPC3_LSB = 0x32,
  94.   GPC4_LSB = 0x33,
  95.   SUSTAIN_SWITCH = 0x40,
  96.   PORTAMENTO_SWITCH = 0x41,
  97.   SOSTENUTO_SWITCH = 0x42,
  98.   SOFT_PEDAL_SWITCH = 0x43,
  99.   LEGATO_SWITCH = 0x45,
  100.   HOLD2_SWITCH = 0x45,
  101.   SOUND_CTRL1 = 0x46,
  102.   SOUND_CTRL2 = 0x47,
  103.   SOUND_CTRL3 = 0x48,
  104.   SOUND_CTRL4 = 0x49,
  105.   SOUND_CTRL5 = 0x4A,
  106.   SOUND_CTRL6 = 0x4B,
  107.   SOUND_CTRL7 = 0x4C,
  108.   SOUND_CTRL8 = 0x4D,
  109.   SOUND_CTRL9 = 0x4E,
  110.   SOUND_CTRL10 = 0x4F,
  111.   GPC5 = 0x50,
  112.   GPC6 = 0x51,
  113.   GPC7 = 0x52,
  114.   GPC8 = 0x53,
  115.   PORTAMENTO_CTRL = 0x54,
  116.   EFFECTS_DEPTH1 = 0x5B,
  117.   EFFECTS_DEPTH2 = 0x5C,
  118.   EFFECTS_DEPTH3 = 0x5D,
  119.   EFFECTS_DEPTH4 = 0x5E,
  120.   EFFECTS_DEPTH5 = 0x5F,
  121.   DATA_ENTRY_INCR = 0x60,
  122.   DATA_ENTRY_DECR = 0x61,
  123.   NRPN_LSB = 0x62,
  124.   NRPN_MSB = 0x63,
  125.   RPN_LSB = 0x64,
  126.   RPN_MSB = 0x65,
  127.   ALL_SOUND_OFF = 0x78,
  128.   ALL_CTRL_OFF = 0x79,
  129.   LOCAL_CONTROL = 0x7A,
  130.   ALL_NOTES_OFF = 0x7B,
  131.   OMNI_OFF = 0x7C,
  132.   OMNI_ON = 0x7D,
  133.   POLY_OFF = 0x7E,
  134.   POLY_ON = 0x7F
  135. };
  136. /* General MIDI RPN event numbers (LSB, MSB = 0) */
  137. enum midi_rpn_event {
  138.   RPN_PITCH_BEND_RANGE = 0x00,
  139.   RPN_CHANNEL_FINE_TUNE = 0x01,
  140.   RPN_CHANNEL_COARSE_TUNE = 0x02,
  141.   RPN_TUNING_PROGRAM_CHANGE = 0x03,
  142.   RPN_TUNING_BANK_SELECT = 0x04,
  143.   RPN_MODULATION_DEPTH_RANGE = 0x05
  144. };
  145. enum midi_meta_event {
  146.   MIDI_COPYRIGHT = 0x02,
  147.   MIDI_TRACK_NAME = 0x03,
  148.   MIDI_INST_NAME = 0x04,
  149.   MIDI_LYRIC = 0x05,
  150.   MIDI_MARKER = 0x06,
  151.   MIDI_CUE_POINT = 0x07,
  152.   MIDI_EOT = 0x2f,
  153.   MIDI_SET_TEMPO = 0x51,
  154.   MIDI_SMPTE_OFFSET = 0x54,
  155.   MIDI_TIME_SIGNATURE = 0x58,
  156.   MIDI_KEY_SIGNATURE = 0x59,
  157.   MIDI_SEQUENCER_EVENT = 0x7f
  158. };
  159. /* MIDI SYSEX useful manufacturer values */
  160. enum midi_sysex_manuf {
  161.   MIDI_SYSEX_MANUF_ROLAND       = 0x41,         /**< Roland manufacturer ID */
  162.   MIDI_SYSEX_UNIV_NON_REALTIME  = 0x7E,         /**< Universal non realtime message */
  163.   MIDI_SYSEX_UNIV_REALTIME      = 0x7F          /**< Universal realtime message */
  164. };
  165. #define MIDI_SYSEX_DEVICE_ID_ALL        0x7F    /**< Device ID used in SYSEX messages to indicate all devices */
  166. /* SYSEX sub-ID #1 which follows device ID */
  167. #define MIDI_SYSEX_MIDI_TUNING_ID       0x08    /**< Sysex sub-ID #1 for MIDI tuning messages */
  168. #define MIDI_SYSEX_GM_ID                0x09    /**< Sysex sub-ID #1 for General MIDI messages */
  169. /**
  170.  * SYSEX tuning message IDs.
  171.  */
  172. enum midi_sysex_tuning_msg_id {
  173.   MIDI_SYSEX_TUNING_BULK_DUMP_REQ       = 0x00, /**< Bulk tuning dump request (non-realtime) */
  174.   MIDI_SYSEX_TUNING_BULK_DUMP           = 0x01, /**< Bulk tuning dump response (non-realtime) */
  175.   MIDI_SYSEX_TUNING_NOTE_TUNE           = 0x02, /**< Tuning note change message (realtime) */
  176.   MIDI_SYSEX_TUNING_BULK_DUMP_REQ_BANK  = 0x03, /**< Bulk tuning dump request (with bank, non-realtime) */
  177.   MIDI_SYSEX_TUNING_BULK_DUMP_BANK      = 0x04, /**< Bulk tuning dump resonse (with bank, non-realtime) */
  178.   MIDI_SYSEX_TUNING_OCTAVE_DUMP_1BYTE   = 0x05, /**< Octave tuning dump using 1 byte values (non-realtime) */
  179.   MIDI_SYSEX_TUNING_OCTAVE_DUMP_2BYTE   = 0x06, /**< Octave tuning dump using 2 byte values (non-realtime) */ 
  180.   MIDI_SYSEX_TUNING_NOTE_TUNE_BANK      = 0x07, /**< Tuning note change message (with bank, realtime/non-realtime) */
  181.   MIDI_SYSEX_TUNING_OCTAVE_TUNE_1BYTE   = 0x08, /**< Octave tuning message using 1 byte values (realtime/non-realtime) */
  182.   MIDI_SYSEX_TUNING_OCTAVE_TUNE_2BYTE   = 0x09  /**< Octave tuning message using 2 byte values (realtime/non-realtime) */
  183. };
  184. /* General MIDI sub-ID #2 */
  185. #define MIDI_SYSEX_GM_ON                0x01    /**< Enable GM mode */
  186. #define MIDI_SYSEX_GM_OFF               0x02    /**< Disable GM mode */
  187. enum fluid_driver_status
  188. {
  189.   FLUID_MIDI_READY,
  190.   FLUID_MIDI_LISTENING,
  191.   FLUID_MIDI_DONE
  192. };
  193. /***************************************************************
  194.  *
  195.  *         TYPE DEFINITIONS & FUNCTION DECLARATIONS
  196.  */
  197. /* From ctype.h */
  198. #define fluid_isascii(c)    (((c) & ~0x7f) == 0)
  199. /*
  200.  * fluid_midi_event_t
  201.  */
  202. struct _fluid_midi_event_t {
  203.   fluid_midi_event_t* next; /* Link to next event */
  204.   void *paramptr;           /* Pointer parameter (for SYSEX data), size is stored to param1, param2 indicates if pointer should be freed (dynamic if TRUE) */
  205.   unsigned int dtime;       /* Delay (ticks) between this and previous event. midi tracks. */
  206.   unsigned int param1;      /* First parameter */
  207.   unsigned int param2;      /* Second parameter */
  208.   unsigned char type;       /* MIDI event type */
  209.   unsigned char channel;    /* MIDI channel */
  210. };
  211. /*
  212.  * fluid_track_t
  213.  */
  214. struct _fluid_track_t {
  215.   char* name;
  216.   int num;
  217.   fluid_midi_event_t *first;
  218.   fluid_midi_event_t *cur;
  219.   fluid_midi_event_t *last;
  220.   unsigned int ticks;
  221. };
  222. typedef struct _fluid_track_t fluid_track_t;
  223. fluid_track_t* new_fluid_track(int num);
  224. int delete_fluid_track(fluid_track_t* track);
  225. int fluid_track_set_name(fluid_track_t* track, char* name);
  226. char* fluid_track_get_name(fluid_track_t* track);
  227. int fluid_track_add_event(fluid_track_t* track, fluid_midi_event_t* evt);
  228. fluid_midi_event_t* fluid_track_first_event(fluid_track_t* track);
  229. fluid_midi_event_t* fluid_track_next_event(fluid_track_t* track);
  230. int fluid_track_get_duration(fluid_track_t* track);
  231. int fluid_track_reset(fluid_track_t* track);
  232. int fluid_track_send_events(fluid_track_t* track,
  233.    fluid_synth_t* synth,
  234.    fluid_player_t* player,
  235.    unsigned int ticks);
  236. #define fluid_track_eot(track)  ((track)->cur == NULL)
  237. /*
  238.  * fluid_player
  239.  */
  240. struct _fluid_player_t {
  241.   int status;
  242.   int ntracks;
  243.   fluid_track_t *track[MAX_NUMBER_OF_TRACKS];
  244.   fluid_synth_t* synth;
  245.   fluid_timer_t* system_timer;
  246.   fluid_sample_timer_t* sample_timer;
  247.   int loop; /* -1 = loop infinitely, otherwise times left to loop the playlist */
  248.   fluid_list_t* playlist; /* List of file names */
  249.   fluid_list_t* currentfile; /* points to an item in files, or NULL if not playing */
  250.   char send_program_change; /* should we ignore the program changes? */
  251.   char use_system_timer;   /* if zero, use sample timers, otherwise use system clock timer */
  252.   char reset_synth_between_songs; /* 1 if system reset should be sent to the synth between songs. */
  253.   int start_ticks;          /* the number of tempo ticks passed at the last tempo change */
  254.   int cur_ticks;            /* the number of tempo ticks passed */
  255.   int begin_msec;           /* the time (msec) of the beginning of the file */
  256.   int start_msec;           /* the start time of the last tempo change */
  257.   int cur_msec;             /* the current time */
  258.   int miditempo;            /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */
  259.   double deltatime;         /* milliseconds per midi tick. depends on set-tempo */
  260.   unsigned int division;
  261. };
  262. int fluid_player_add_track(fluid_player_t* player, fluid_track_t* track);
  263. int fluid_player_callback(void* data, unsigned int msec);
  264. int fluid_player_count_tracks(fluid_player_t* player);
  265. fluid_track_t* fluid_player_get_track(fluid_player_t* player, int i);
  266. int fluid_player_reset(fluid_player_t* player);
  267. int fluid_player_load(fluid_player_t* player, char *filename);
  268. void fluid_player_settings(fluid_settings_t* settings);
  269. /*
  270.  * fluid_midi_file
  271.  */
  272. typedef struct {
  273.   fluid_file fp;
  274.   int running_status;
  275.   int c;
  276.   int type;
  277.   int ntracks;
  278.   int uses_smpte;
  279.   unsigned int smpte_fps;
  280.   unsigned int smpte_res;
  281.   unsigned int division;       /* If uses_SMPTE == 0 then division is
  282.   ticks per beat (quarter-note) */
  283.   double tempo;                /* Beats per second (SI rules =) */
  284.   int tracklen;
  285.   int trackpos;
  286.   int eot;
  287.   int varlen;
  288.   int dtime;
  289. } fluid_midi_file;
  290. fluid_midi_file* new_fluid_midi_file(char* filename);
  291. void delete_fluid_midi_file(fluid_midi_file* mf);
  292. int fluid_midi_file_read_mthd(fluid_midi_file* midifile);
  293. int fluid_midi_file_load_tracks(fluid_midi_file* midifile, fluid_player_t* player);
  294. int fluid_midi_file_read_track(fluid_midi_file* mf, fluid_player_t* player, int num);
  295. int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track);
  296. int fluid_midi_file_read_varlen(fluid_midi_file* mf);
  297. int fluid_midi_file_getc(fluid_midi_file* mf);
  298. int fluid_midi_file_push(fluid_midi_file* mf, int c);
  299. int fluid_midi_file_read(fluid_midi_file* mf, void* buf, int len);
  300. int fluid_midi_file_skip(fluid_midi_file* mf, int len);
  301. int fluid_midi_file_read_tracklen(fluid_midi_file* mf);
  302. int fluid_midi_file_eot(fluid_midi_file* mf);
  303. int fluid_midi_file_get_division(fluid_midi_file* midifile);
  304. #define FLUID_MIDI_PARSER_MAX_DATA_SIZE 1024    /**< Maximum size of MIDI parameters/data (largest is SYSEX data) */
  305. /*
  306.  * fluid_midi_parser_t
  307.  */
  308. struct _fluid_midi_parser_t {
  309.   unsigned char status;           /* Identifies the type of event, that is currently received ('Noteon', 'Pitch Bend' etc). */
  310.   unsigned char channel;          /* The channel of the event that is received (in case of a channel event) */
  311.   unsigned int nr_bytes;          /* How many bytes have been read for the current event? */
  312.   unsigned int nr_bytes_total;    /* How many bytes does the current event type include? */
  313.   unsigned char data[FLUID_MIDI_PARSER_MAX_DATA_SIZE]; /* The parameters or SYSEX data */
  314.   fluid_midi_event_t event;        /* The event, that is returned to the MIDI driver. */
  315. };
  316. int fluid_isasciistring(char* s);
  317. long fluid_getlength(unsigned char *s);
  318. #endif /* _FLUID_MIDI_H */