Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/fluidsynth/src/midi/fluid_midi.h
4396 views
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
unsigned int cur_msec; /* the current time */
309
int end_msec; /* when >=0, playback is extended until this time (for, e.g., reverb) */
310
char end_pedals_disabled; /* 1 once the pedals have been released after the last midi event, 0 otherwise */
311
/* sync mode: indicates the tempo mode the player is driven by (see fluid_player_set_tempo()):
312
1, the player is driven by internal tempo (miditempo). This is the default.
313
0, the player is driven by external tempo (exttempo)
314
*/
315
int sync_mode;
316
/* miditempo: internal tempo coming from MIDI file tempo change events
317
(in micro seconds per quarter note)
318
*/
319
int miditempo; /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */
320
/* exttempo: external tempo set by fluid_player_set_tempo() (in micro seconds per quarter note) */
321
int exttempo;
322
/* multempo: tempo multiplier set by fluid_player_set_tempo() */
323
float multempo;
324
float deltatime; /* milliseconds per midi tick. depends on current tempo mode (see sync_mode) */
325
unsigned int division;
326
327
handle_midi_event_func_t playback_callback; /* function fired on each midi event as it is played */
328
void *playback_userdata; /* pointer to user-defined data passed to playback_callback function */
329
handle_midi_tick_func_t tick_callback; /* function fired on each tick change */
330
void *tick_userdata; /* pointer to user-defined data passed to tick_callback function */
331
332
int channel_isplaying[MAX_NUMBER_OF_CHANNELS]; /* flags indicating channels on which notes have played */
333
};
334
335
#define FLUID_PLAYER_STOP_GRACE_MS 2000
336
337
void fluid_player_settings(fluid_settings_t *settings);
338
339
340
/*
341
* fluid_midi_file
342
*/
343
typedef struct
344
{
345
const char *buffer; /* Entire contents of MIDI file (borrowed) */
346
int buf_len; /* Length of buffer, in bytes */
347
int buf_pos; /* Current read position in contents buffer */
348
int eof; /* The "end of file" condition */
349
int running_status;
350
int c;
351
int type;
352
int ntracks;
353
int uses_smpte;
354
unsigned int smpte_fps;
355
unsigned int smpte_res;
356
unsigned int division; /* If uses_SMPTE == 0 then division is
357
ticks per beat (quarter-note) */
358
double tempo; /* Beats per second (SI rules =) */
359
int tracklen;
360
int trackpos;
361
int eot;
362
int varlen;
363
int dtime;
364
} fluid_midi_file;
365
366
367
368
#define FLUID_MIDI_PARSER_MAX_DATA_SIZE 1024 /**< Maximum size of MIDI parameters/data (largest is SYSEX data) */
369
370
/*
371
* fluid_midi_parser_t
372
*/
373
struct _fluid_midi_parser_t
374
{
375
unsigned char status; /* Identifies the type of event, that is currently received ('Noteon', 'Pitch Bend' etc). */
376
unsigned char channel; /* The channel of the event that is received (in case of a channel event) */
377
unsigned int nr_bytes; /* How many bytes have been read for the current event? */
378
unsigned int nr_bytes_total; /* How many bytes does the current event type include? */
379
unsigned char data[FLUID_MIDI_PARSER_MAX_DATA_SIZE]; /* The parameters or SYSEX data */
380
fluid_midi_event_t event; /* The event, that is returned to the MIDI driver. */
381
};
382
383
384
#endif /* _FLUID_MIDI_H */
385
386