1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
|
/*
* libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
*
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru>
*
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ADLMIDI_H
#define ADLMIDI_H
#ifdef __cplusplus
extern "C" {
#endif
#define ADLMIDI_VERSION_MAJOR 1
#define ADLMIDI_VERSION_MINOR 4
#define ADLMIDI_VERSION_PATCHLEVEL 0
#define ADLMIDI_TOSTR_I(s) #s
#define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s)
#define ADLMIDI_VERSION \
ADLMIDI_TOSTR(ADLMIDI_VERSION_MAJOR) "." \
ADLMIDI_TOSTR(ADLMIDI_VERSION_MINOR) "." \
ADLMIDI_TOSTR(ADLMIDI_VERSION_PATCHLEVEL)
#include <stddef.h>
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#include <stdint.h>
typedef uint8_t ADL_UInt8;
typedef uint16_t ADL_UInt16;
typedef int8_t ADL_SInt8;
typedef int16_t ADL_SInt16;
#else
typedef unsigned char ADL_UInt8;
typedef unsigned short ADL_UInt16;
typedef char ADL_SInt8;
typedef short ADL_SInt16;
#endif
/**
* @brief Volume scaling models
*/
enum ADLMIDI_VolumeModels
{
/*! Automatical choice by the specific bank */
ADLMIDI_VolumeModel_AUTO = 0,
/*! Linearized scaling model, most standard */
ADLMIDI_VolumeModel_Generic = 1,
/*! Native OPL3's logarithmic volume scale */
ADLMIDI_VolumeModel_NativeOPL3 = 2,
/*! Native OPL3's logarithmic volume scale. Alias. */
ADLMIDI_VolumeModel_CMF = ADLMIDI_VolumeModel_NativeOPL3,
/*! Logarithmic volume scale, using volume map table. Used in DMX. */
ADLMIDI_VolumeModel_DMX = 3,
/*! Logarithmic volume scale, used in Apogee Sound System. */
ADLMIDI_VolumeModel_APOGEE = 4,
/*! Aproximated and shorted volume map table. Similar to general, but has less granularity. */
ADLMIDI_VolumeModel_9X = 5
};
/**
* @brief Sound output format
*/
enum ADLMIDI_SampleType
{
/*! signed PCM 16-bit */
ADLMIDI_SampleType_S16 = 0,
/*! signed PCM 8-bit */
ADLMIDI_SampleType_S8,
/*! float 32-bit */
ADLMIDI_SampleType_F32,
/*! float 64-bit */
ADLMIDI_SampleType_F64,
/*! signed PCM 24-bit */
ADLMIDI_SampleType_S24,
/*! signed PCM 32-bit */
ADLMIDI_SampleType_S32,
/*! unsigned PCM 8-bit */
ADLMIDI_SampleType_U8,
/*! unsigned PCM 16-bit */
ADLMIDI_SampleType_U16,
/*! unsigned PCM 24-bit */
ADLMIDI_SampleType_U24,
/*! unsigned PCM 32-bit */
ADLMIDI_SampleType_U32,
/*! Count of available sample format types */
ADLMIDI_SampleType_Count,
};
/**
* @brief Sound output format context
*/
struct ADLMIDI_AudioFormat
{
/*! type of sample */
enum ADLMIDI_SampleType type;
/*! size in bytes of the storage type */
unsigned containerSize;
/*! distance in bytes between consecutive samples */
unsigned sampleOffset;
};
/**
* @brief Instance of the library
*/
struct ADL_MIDIPlayer
{
/*! Private context descriptor */
void *adl_midiPlayer;
};
/* DEPRECATED */
#define adl_setNumCards adl_setNumChips
/**
* @brief Sets number of emulated chips (from 1 to 100). Emulation of multiple chips exchanges polyphony limits
* @param device Instance of the library
* @param numChips Count of virtual chips to emulate
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_setNumChips(struct ADL_MIDIPlayer *device, int numChips);
/**
* @brief Get current number of emulated chips
* @param device Instance of the library
* @return Count of working chip emulators
*/
extern int adl_getNumChips(struct ADL_MIDIPlayer *device);
/**
* @brief Sets a number of the patches bank from 0 to N banks.
* @param device Instance of the library
* @param bank Number of embedded bank
* @return 0 on success, <0 when any error has occurred
*
* Is recommended to call adl_reset() to apply changes to already-loaded file player or real-time.
*/
extern int adl_setBank(struct ADL_MIDIPlayer *device, int bank);
/**
* @brief Returns total number of available banks
* @return Total number of available embedded banks
*/
extern int adl_getBanksCount();
/**
* @brief Returns pointer to array of names of every bank
* @return Array of strings are containing names of every embedded bank
*/
extern const char *const *adl_getBankNames();
/**
* @brief Reference to dynamic bank
*/
typedef struct ADL_Bank
{
void *pointer[3];
} ADL_Bank;
/**
* @brief Identifier of dynamic bank
*/
typedef struct ADL_BankId
{
/*! 0 if bank is melodic set, or 1 if bank is a percussion set */
ADL_UInt8 percussive;
/*! Assign to MSB bank number */
ADL_UInt8 msb;
/*! Assign to LSB bank number */
ADL_UInt8 lsb;
} ADL_BankId;
/**
* @brief Flags for dynamic bank access
*/
enum ADL_BankAccessFlags
{
/*! create bank, allocating memory as needed */
ADLMIDI_Bank_Create = 1,
/*! create bank, never allocating memory */
ADLMIDI_Bank_CreateRt = 1|2,
};
typedef struct ADL_Instrument ADL_Instrument;
/**
* @brief Preallocates a minimum number of bank slots. Returns the actual capacity
* @param device Instance of the library
* @param banks Count of bank slots to pre-allocate.
* @return actual capacity of reserved bank slots.
*/
extern int adl_reserveBanks(struct ADL_MIDIPlayer *device, unsigned banks);
/**
* @brief Gets the bank designated by the identifier, optionally creating if it does not exist
* @param device Instance of the library
* @param id Identifier of dynamic bank
* @param flags Flags for dynamic bank access (ADL_BankAccessFlags)
* @param bank Reference to dynamic bank
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_getBank(struct ADL_MIDIPlayer *device, const ADL_BankId *id, int flags, ADL_Bank *bank);
/**
* @brief Gets the identifier of a bank
* @param device Instance of the library
* @param bank Reference to dynamic bank.
* @param id Identifier of dynamic bank
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_getBankId(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, ADL_BankId *id);
/**
* @brief Removes a bank
* @param device Instance of the library
* @param bank Reference to dynamic bank
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_removeBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank);
/**
* @brief Gets the first bank
* @param device Instance of the library
* @param bank Reference to dynamic bank
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_getFirstBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank);
/**
* @brief Iterates to the next bank
* @param device Instance of the library
* @param bank Reference to dynamic bank
* @return 0 on success, <0 when any error has occurred or end has been reached.
*/
extern int adl_getNextBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank);
/**
* @brief Gets the nth intrument in the bank [0..127]
* @param device Instance of the library
* @param bank Reference to dynamic bank
* @param index Index of the instrument
* @param ins Instrument entry
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_getInstrument(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, unsigned index, ADL_Instrument *ins);
/**
* @brief Sets the nth intrument in the bank [0..127]
* @param device Instance of the library
* @param bank Reference to dynamic bank
* @param index Index of the instrument
* @param ins Instrument structure pointer
* @return 0 on success, <0 when any error has occurred
*
* This function allows to override an instrument on the fly
*/
extern int adl_setInstrument(struct ADL_MIDIPlayer *device, ADL_Bank *bank, unsigned index, const ADL_Instrument *ins);
/**
* @brief Loads the melodic or percussive part of the nth embedded bank
* @param device Instance of the library
* @param bank Reference to dynamic bank
* @param num Number of embedded bank to load into the current bank array
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_loadEmbeddedBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank, int num);
/**
* @brief Sets number of 4-operator channels between all chips
* @param device Instance of the library
* @param ops4 Count of four-op channels to allocate between all emulating chips
* @return 0 on success, <0 when any error has occurred
*
* By default, it is automatically re-calculating every bank change.
* If you want to specify custom number of four operator channels,
* please call this function after bank change (adl_setBank() or adl_openBank()),
* otherwise, value will be overwritten by auto-calculated.
*/
extern int adl_setNumFourOpsChn(struct ADL_MIDIPlayer *device, int ops4);
/**
* @brief Get current total count of 4-operator channels between all chips
* @param device Instance of the library
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_getNumFourOpsChn(struct ADL_MIDIPlayer *device);
/**
* @brief Override Enable(1) or Disable(0) AdLib percussion mode. -1 - use bank default AdLib percussion mode
* @param device Instance of the library
* @param percmod 0 - disabled, 1 - enabled
*
* This function forces rhythm-mode on any bank. The result will wrork glitchy.
*/
extern void adl_setPercMode(struct ADL_MIDIPlayer *device, int percmod);
/**
* @brief Override Enable(1) or Disable(0) deep vibrato state. -1 - use bank default vibrato state
* @param device Instance of the library
* @param hvibro 0 - disabled, 1 - enabled
*/
extern void adl_setHVibrato(struct ADL_MIDIPlayer *device, int hvibro);
/**
* @brief Override Enable(1) or Disable(0) deep tremolo state. -1 - use bank default tremolo state
* @param device Instance of the library
* @param hvibro 0 - disabled, 1 - enabled
*/
extern void adl_setHTremolo(struct ADL_MIDIPlayer *device, int htremo);
/**
* @brief Override Enable(1) or Disable(0) scaling of modulator volumes. -1 - use bank default scaling of modulator volumes
* @param device Instance of the library
* @param hvibro 0 - disabled, 1 - enabled
*/
extern void adl_setScaleModulators(struct ADL_MIDIPlayer *device, int smod);
/**
* @brief Enable(1) or Disable(0) full-range brightness (MIDI CC74 used in XG music to filter result sounding) scaling
* @param device Instance of the library
* @param fr_brightness 0 - disabled, 1 - enabled
*
* By default, brightness affects sound between 0 and 64.
* When this option is enabled, the range will use a full range from 0 up to 127.
*/
extern void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness);
/*Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part)*/
extern void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn);
/* !!!DEPRECATED!!! Enable or disable Logariphmic volume changer */
extern void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol);
/*Set different volume range model */
extern void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int volumeModel);
/*Load WOPL bank file from File System. Is recommended to call adl_reset() to apply changes to already-loaded file player or real-time.*/
extern int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath);
/*Load WOPL bank file from memory data*/
extern int adl_openBankData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size);
/* DEPRECATED */
extern const char *adl_emulatorName();
/**
* @brief Returns chip emulator name string
* @param device Instance of the library
* @return Understandible name of current OPL3 emulator
*/
extern const char *adl_chipEmulatorName(struct ADL_MIDIPlayer *device);
/**
* @brief List of available OPL3 emulators
*/
enum ADL_Emulator
{
/*! Nuked OPL3 v. 1.8 */
ADLMIDI_EMU_NUKED = 0,
/*! Nuked OPL3 v. 1.7.4 */
ADLMIDI_EMU_NUKED_174,
/*! DosBox */
ADLMIDI_EMU_DOSBOX,
/*! Count instrument on the level */
ADLMIDI_EMU_end
};
/**
* @brief Switch the emulation core
* @param device Instance of the library
* @param emulator Type of emulator (ADL_Emulator)
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_switchEmulator(struct ADL_MIDIPlayer *device, int emulator);
/**
* @brief Library version context
*/
typedef struct {
ADL_UInt16 major;
ADL_UInt16 minor;
ADL_UInt16 patch;
} ADL_Version;
/**
* @brief Run emulator with PCM rate to reduce CPU usage on slow devices. May decrease sounding accuracy.
* @param device Instance of the library
* @param enabled 0 - disabled, 1 - enabled
* @return 0 on success, <0 when any error has occurred
*/
extern int adl_setRunAtPcmRate(struct ADL_MIDIPlayer *device, int enabled);
/*Returns string which contains a version number*/
extern const char *adl_linkedLibraryVersion();
/*Returns structure which contains a version number of library */
extern const ADL_Version *adl_linkedVersion();
/*Returns string which contains last error message of initialization*/
extern const char *adl_errorString();
/*Returns string which contains last error message on specific device*/
extern const char *adl_errorInfo(struct ADL_MIDIPlayer *device);
/*Initialize ADLMIDI Player device*/
extern struct ADL_MIDIPlayer *adl_init(long sample_rate);
/*Set 4-bit device identifier*/
extern int adl_setDeviceIdentifier(struct ADL_MIDIPlayer *device, unsigned id);
/*Load MIDI file from File System*/
extern int adl_openFile(struct ADL_MIDIPlayer *device, const char *filePath);
/*Load MIDI file from memory data*/
extern int adl_openData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size);
/*Resets MIDI player*/
extern void adl_reset(struct ADL_MIDIPlayer *device);
/*Get total time length of current song*/
extern double adl_totalTimeLength(struct ADL_MIDIPlayer *device);
/*Get loop start time if presented. -1 means MIDI file has no loop points */
extern double adl_loopStartTime(struct ADL_MIDIPlayer *device);
/*Get loop end time if presented. -1 means MIDI file has no loop points */
extern double adl_loopEndTime(struct ADL_MIDIPlayer *device);
/*Get current time position in seconds*/
extern double adl_positionTell(struct ADL_MIDIPlayer *device);
/*Jump to absolute time position in seconds*/
extern void adl_positionSeek(struct ADL_MIDIPlayer *device, double seconds);
/*Reset MIDI track position to begin */
extern void adl_positionRewind(struct ADL_MIDIPlayer *device);
/*Set tempo multiplier: 1.0 - original tempo, >1 - play faster, <1 - play slower */
extern void adl_setTempo(struct ADL_MIDIPlayer *device, double tempo);
/*Get a textual description of the channel state. For display only.*/
extern int adl_describeChannels(struct ADL_MIDIPlayer *device, char *text, char *attr, size_t size);
/*Close and delete ADLMIDI device*/
extern void adl_close(struct ADL_MIDIPlayer *device);
/**META**/
/*Returns string which contains a music title*/
extern const char *adl_metaMusicTitle(struct ADL_MIDIPlayer *device);
/*Returns string which contains a copyright string*/
extern const char *adl_metaMusicCopyright(struct ADL_MIDIPlayer *device);
/*Returns count of available track titles: NOTE: there are CAN'T be associated with channel in any of event or note hooks */
extern size_t adl_metaTrackTitleCount(struct ADL_MIDIPlayer *device);
/*Get track title by index*/
extern const char *adl_metaTrackTitle(struct ADL_MIDIPlayer *device, size_t index);
struct Adl_MarkerEntry
{
const char *label;
double pos_time;
unsigned long pos_ticks;
};
/*Returns count of available markers*/
extern size_t adl_metaMarkerCount(struct ADL_MIDIPlayer *device);
/*Returns the marker entry*/
extern struct Adl_MarkerEntry adl_metaMarker(struct ADL_MIDIPlayer *device, size_t index);
/*Take a sample buffer and iterate MIDI timers */
extern int adl_play(struct ADL_MIDIPlayer *device, int sampleCount, short *out);
/*Take a sample buffer and iterate MIDI timers */
extern int adl_playFormat(struct ADL_MIDIPlayer *device, int sampleCount, ADL_UInt8 *left, ADL_UInt8 *right, const struct ADLMIDI_AudioFormat *format);
/*Generate audio output from chip emulators without iteration of MIDI timers.*/
extern int adl_generate(struct ADL_MIDIPlayer *device, int sampleCount, short *out);
/*Generate audio output from chip emulators without iteration of MIDI timers.*/
extern int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleCount, ADL_UInt8 *left, ADL_UInt8 *right, const struct ADLMIDI_AudioFormat *format);
/**
* @brief Periodic tick handler.
* @param device
* @param seconds seconds since last call
* @param granularity don't expect intervals smaller than this, in seconds
* @return desired number of seconds until next call
*
* Use it for Hardware OPL3 mode or when you want to process events differently from adl_play() function.
* DON'T USE IT TOGETHER WITH adl_play()!!!
*/
extern double adl_tickEvents(struct ADL_MIDIPlayer *device, double seconds, double granuality);
/*Returns 1 if music position has reached end*/
extern int adl_atEnd(struct ADL_MIDIPlayer *device);
/**RealTime**/
/*Force Off all notes on all channels*/
extern void adl_panic(struct ADL_MIDIPlayer *device);
/*Reset states of all controllers on all MIDI channels*/
extern void adl_rt_resetState(struct ADL_MIDIPlayer *device);
/*Turn specific MIDI note ON*/
extern int adl_rt_noteOn(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note, ADL_UInt8 velocity);
/*Turn specific MIDI note OFF*/
extern void adl_rt_noteOff(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note);
/*Set note after-touch*/
extern void adl_rt_noteAfterTouch(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note, ADL_UInt8 atVal);
/*Set channel after-touch*/
extern void adl_rt_channelAfterTouch(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 atVal);
/*Apply controller change*/
extern void adl_rt_controllerChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 type, ADL_UInt8 value);
/*Apply patch change*/
extern void adl_rt_patchChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 patch);
/*Apply pitch bend change*/
extern void adl_rt_pitchBend(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt16 pitch);
/*Apply pitch bend change*/
extern void adl_rt_pitchBendML(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 msb, ADL_UInt8 lsb);
/*Change LSB of the bank*/
extern void adl_rt_bankChangeLSB(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 lsb);
/*Change MSB of the bank*/
extern void adl_rt_bankChangeMSB(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 msb);
/*Change bank by absolute signed value*/
extern void adl_rt_bankChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_SInt16 bank);
/*Perform a system exclusive message*/
extern int adl_rt_systemExclusive(struct ADL_MIDIPlayer *device, const ADL_UInt8 *msg, size_t size);
/**Hooks**/
typedef void (*ADL_RawEventHook)(void *userdata, ADL_UInt8 type, ADL_UInt8 subtype, ADL_UInt8 channel, const ADL_UInt8 *data, size_t len);
typedef void (*ADL_NoteHook)(void *userdata, int adlchn, int note, int ins, int pressure, double bend);
typedef void (*ADL_DebugMessageHook)(void *userdata, const char *fmt, ...);
/* Set raw MIDI event hook */
extern void adl_setRawEventHook(struct ADL_MIDIPlayer *device, ADL_RawEventHook rawEventHook, void *userData);
/* Set note hook */
extern void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_NoteHook noteHook, void *userData);
/* Set debug message hook */
extern void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData);
/** Instrument structures **/
enum
{
ADLMIDI_InstrumentVersion = 0,
};
/**
* @brief Instrument flags
*/
typedef enum ADL_InstrumentFlags
{
/*! Is two-operator single-voice instrument (no flags) */
ADLMIDI_Ins_2op = 0x00,
/*! Is true four-operator instrument */
ADLMIDI_Ins_4op = 0x01,
/*! Is pseudo four-operator (two 2-operator voices) instrument */
ADLMIDI_Ins_Pseudo4op = 0x02,
/*! Is a blank instrument entry */
ADLMIDI_Ins_IsBlank = 0x04,
/*! RythmMode flags mask */
ADLMIDI_Ins_RhythmModeMask = 0x38,
/*! Mask of the flags range */
ADLMIDI_Ins_ALL_MASK = 0x07,
} ADL_InstrumentFlags;
/**
* @brief Rhythm-mode drum type
*/
typedef enum ADL_RhythmMode
{
/*! RythmMode: BassDrum */
ADLMIDI_RM_BassDrum = 0x08,
/*! RythmMode: Snare */
ADLMIDI_RM_Snare = 0x10,
/*! RythmMode: TomTom */
ADLMIDI_RM_TomTom = 0x18,
/*! RythmMode: Cymbal */
ADLMIDI_RM_Cymbal = 0x20,
/*! RythmMode: HiHat */
ADLMIDI_RM_HiHat = 0x28
} ADL_RhythmMode;
/**
* @brief Operator structure, part of Instrument structure
*/
typedef struct ADL_Operator
{
/*! AM/Vib/Env/Ksr/FMult characteristics */
ADL_UInt8 avekf_20;
/*! Key Scale Level / Total level register data */
ADL_UInt8 ksl_l_40;
/*! Attack / Decay */
ADL_UInt8 atdec_60;
/*! Systain and Release register data */
ADL_UInt8 susrel_80;
/*! Wave form */
ADL_UInt8 waveform_E0;
} ADL_Operator;
/**
* @brief Instrument structure
*/
typedef struct ADL_Instrument
{
/*! Version of the instrument object */
int version;
/*! MIDI note key (half-tone) offset for an instrument (or a first voice in pseudo-4-op mode) */
ADL_SInt16 note_offset1;
/*! MIDI note key (half-tone) offset for a second voice in pseudo-4-op mode */
ADL_SInt16 note_offset2;
/*! MIDI note velocity offset (taken from Apogee TMB format) */
ADL_SInt8 midi_velocity_offset;
/*! Second voice detune level (taken from DMX OP2) */
ADL_SInt8 second_voice_detune;
/*! Percussion MIDI base tone number at which this drum will be played */
ADL_UInt8 percussion_key_number;
/*! Enum ADL_InstrumentFlags */
ADL_UInt8 inst_flags;
/*! Feedback&Connection register for first and second operators */
ADL_UInt8 fb_conn1_C0;
/*! Feedback&Connection register for third and fourth operators */
ADL_UInt8 fb_conn2_C0;
/*! Operators register data */
ADL_Operator operators[4];
/*! Millisecond delay of sounding while key is on */
ADL_UInt16 delay_on_ms;
/*! Millisecond delay of sounding after key off */
ADL_UInt16 delay_off_ms;
} ADL_Instrument;
#ifdef __cplusplus
}
#endif
#endif /* ADLMIDI_H */
|