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