1 /* 2 * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation 3 * 4 * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> 5 * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov <admin@wohlnet.ru> 6 * 7 * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: 8 * http://iki.fi/bisqwit/source/adlmidi.html 9 * 10 * This program is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation, either version 3 of the License, or 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef ADLMIDI_H 25 #define ADLMIDI_H 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 #define ADLMIDI_VERSION_MAJOR 1 32 #define ADLMIDI_VERSION_MINOR 4 33 #define ADLMIDI_VERSION_PATCHLEVEL 0 34 35 #define ADLMIDI_TOSTR_I(s) #s 36 #define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s) 37 #define ADLMIDI_VERSION \ 38 ADLMIDI_TOSTR(ADLMIDI_VERSION_MAJOR) "." \ 39 ADLMIDI_TOSTR(ADLMIDI_VERSION_MINOR) "." \ 40 ADLMIDI_TOSTR(ADLMIDI_VERSION_PATCHLEVEL) 41 42 43 #include <stddef.h> 44 45 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 46 #include <stdint.h> 47 typedef uint8_t ADL_UInt8; 48 typedef uint16_t ADL_UInt16; 49 typedef int8_t ADL_SInt8; 50 typedef int16_t ADL_SInt16; 51 #else 52 typedef unsigned char ADL_UInt8; 53 typedef unsigned short ADL_UInt16; 54 typedef char ADL_SInt8; 55 typedef short ADL_SInt16; 56 #endif 57 58 /* == Deprecated function markers == */ 59 60 #ifdef __GNUC__ 61 #define DEPRECATED(func) func __attribute__ ((deprecated)) 62 #elif defined(_MSC_VER) 63 #define DEPRECATED(func) __declspec(deprecated) func 64 #else 65 #define DEPRECATED(func) func 66 #endif 67 68 69 /** 70 * @brief Volume scaling models 71 */ 72 enum ADLMIDI_VolumeModels 73 { 74 /*! Automatical choice by the specific bank */ 75 ADLMIDI_VolumeModel_AUTO = 0, 76 /*! Linearized scaling model, most standard */ 77 ADLMIDI_VolumeModel_Generic = 1, 78 /*! Native OPL3's logarithmic volume scale */ 79 ADLMIDI_VolumeModel_NativeOPL3 = 2, 80 /*! Native OPL3's logarithmic volume scale. Alias. */ 81 ADLMIDI_VolumeModel_CMF = ADLMIDI_VolumeModel_NativeOPL3, 82 /*! Logarithmic volume scale, using volume map table. Used in DMX. */ 83 ADLMIDI_VolumeModel_DMX = 3, 84 /*! Logarithmic volume scale, used in Apogee Sound System. */ 85 ADLMIDI_VolumeModel_APOGEE = 4, 86 /*! Aproximated and shorted volume map table. Similar to general, but has less granularity. */ 87 ADLMIDI_VolumeModel_9X = 5 88 }; 89 90 /** 91 * @brief Sound output format 92 */ 93 enum ADLMIDI_SampleType 94 { 95 /*! signed PCM 16-bit */ 96 ADLMIDI_SampleType_S16 = 0, 97 /*! signed PCM 8-bit */ 98 ADLMIDI_SampleType_S8, 99 /*! float 32-bit */ 100 ADLMIDI_SampleType_F32, 101 /*! float 64-bit */ 102 ADLMIDI_SampleType_F64, 103 /*! signed PCM 24-bit */ 104 ADLMIDI_SampleType_S24, 105 /*! signed PCM 32-bit */ 106 ADLMIDI_SampleType_S32, 107 /*! unsigned PCM 8-bit */ 108 ADLMIDI_SampleType_U8, 109 /*! unsigned PCM 16-bit */ 110 ADLMIDI_SampleType_U16, 111 /*! unsigned PCM 24-bit */ 112 ADLMIDI_SampleType_U24, 113 /*! unsigned PCM 32-bit */ 114 ADLMIDI_SampleType_U32, 115 /*! Count of available sample format types */ 116 ADLMIDI_SampleType_Count, 117 }; 118 119 /** 120 * @brief Sound output format context 121 */ 122 struct ADLMIDI_AudioFormat 123 { 124 /*! type of sample */ 125 enum ADLMIDI_SampleType type; 126 /*! size in bytes of the storage type */ 127 unsigned containerSize; 128 /*! distance in bytes between consecutive samples */ 129 unsigned sampleOffset; 130 }; 131 132 /** 133 * @brief Instance of the library 134 */ 135 struct ADL_MIDIPlayer 136 { 137 /*! Private context descriptor */ 138 void *adl_midiPlayer; 139 }; 140 141 /* DEPRECATED */ 142 #define adl_setNumCards adl_setNumChips 143 144 /** 145 * @brief Sets number of emulated chips (from 1 to 100). Emulation of multiple chips extends polyphony limits 146 * @param device Instance of the library 147 * @param numChips Count of virtual chips to emulate 148 * @return 0 on success, <0 when any error has occurred 149 */ 150 extern int adl_setNumChips(struct ADL_MIDIPlayer *device, int numChips); 151 152 /** 153 * @brief Get current number of emulated chips 154 * @param device Instance of the library 155 * @return Count of working chip emulators 156 */ 157 extern int adl_getNumChips(struct ADL_MIDIPlayer *device); 158 159 /** 160 * @brief Sets a number of the patches bank from 0 to N banks. 161 * 162 * Is recommended to call adl_reset() to apply changes to already-loaded file player or real-time. 163 * 164 * @param device Instance of the library 165 * @param bank Number of embedded bank 166 * @return 0 on success, <0 when any error has occurred 167 */ 168 extern int adl_setBank(struct ADL_MIDIPlayer *device, int bank); 169 170 /** 171 * @brief Returns total number of available banks 172 * @return Total number of available embedded banks 173 */ 174 extern int adl_getBanksCount(); 175 176 /** 177 * @brief Returns pointer to array of names of every bank 178 * @return Array of strings containing the name of every embedded bank 179 */ 180 extern const char *const *adl_getBankNames(); 181 182 /** 183 * @brief Reference to dynamic bank 184 */ 185 typedef struct ADL_Bank 186 { 187 void *pointer[3]; 188 } ADL_Bank; 189 190 /** 191 * @brief Identifier of dynamic bank 192 */ 193 typedef struct ADL_BankId 194 { 195 /*! 0 if bank is melodic set, or 1 if bank is a percussion set */ 196 ADL_UInt8 percussive; 197 /*! Assign to MSB bank number */ 198 ADL_UInt8 msb; 199 /*! Assign to LSB bank number */ 200 ADL_UInt8 lsb; 201 } ADL_BankId; 202 203 /** 204 * @brief Flags for dynamic bank access 205 */ 206 enum ADL_BankAccessFlags 207 { 208 /*! create bank, allocating memory as needed */ 209 ADLMIDI_Bank_Create = 1, 210 /*! create bank, never allocating memory */ 211 ADLMIDI_Bank_CreateRt = 1|2, 212 }; 213 214 /* ======== Instrument structures ======== */ 215 216 /** 217 * @brief Version of the instrument data format 218 */ 219 enum 220 { 221 ADLMIDI_InstrumentVersion = 0, 222 }; 223 224 /** 225 * @brief Instrument flags 226 */ 227 typedef enum ADL_InstrumentFlags 228 { 229 /*! Is two-operator single-voice instrument (no flags) */ 230 ADLMIDI_Ins_2op = 0x00, 231 /*! Is true four-operator instrument */ 232 ADLMIDI_Ins_4op = 0x01, 233 /*! Is pseudo four-operator (two 2-operator voices) instrument */ 234 ADLMIDI_Ins_Pseudo4op = 0x02, 235 /*! Is a blank instrument entry */ 236 ADLMIDI_Ins_IsBlank = 0x04, 237 238 /*! RythmMode flags mask */ 239 ADLMIDI_Ins_RhythmModeMask = 0x38, 240 241 /*! Mask of the flags range */ 242 ADLMIDI_Ins_ALL_MASK = 0x07, 243 } ADL_InstrumentFlags; 244 245 /** 246 * @brief Rhythm-mode drum type 247 */ 248 typedef enum ADL_RhythmMode 249 { 250 /*! RythmMode: BassDrum */ 251 ADLMIDI_RM_BassDrum = 0x08, 252 /*! RythmMode: Snare */ 253 ADLMIDI_RM_Snare = 0x10, 254 /*! RythmMode: TomTom */ 255 ADLMIDI_RM_TomTom = 0x18, 256 /*! RythmMode: Cymbal */ 257 ADLMIDI_RM_Cymbal = 0x20, 258 /*! RythmMode: HiHat */ 259 ADLMIDI_RM_HiHat = 0x28 260 } ADL_RhythmMode; 261 262 263 /** 264 * @brief Operator structure, part of Instrument structure 265 */ 266 typedef struct ADL_Operator 267 { 268 /*! AM/Vib/Env/Ksr/FMult characteristics */ 269 ADL_UInt8 avekf_20; 270 /*! Key Scale Level / Total level register data */ 271 ADL_UInt8 ksl_l_40; 272 /*! Attack / Decay */ 273 ADL_UInt8 atdec_60; 274 /*! Systain and Release register data */ 275 ADL_UInt8 susrel_80; 276 /*! Wave form */ 277 ADL_UInt8 waveform_E0; 278 } ADL_Operator; 279 280 /** 281 * @brief Instrument structure 282 */ 283 typedef struct ADL_Instrument 284 { 285 /*! Version of the instrument object */ 286 int version; 287 /*! MIDI note key (half-tone) offset for an instrument (or a first voice in pseudo-4-op mode) */ 288 ADL_SInt16 note_offset1; 289 /*! MIDI note key (half-tone) offset for a second voice in pseudo-4-op mode */ 290 ADL_SInt16 note_offset2; 291 /*! MIDI note velocity offset (taken from Apogee TMB format) */ 292 ADL_SInt8 midi_velocity_offset; 293 /*! Second voice detune level (taken from DMX OP2) */ 294 ADL_SInt8 second_voice_detune; 295 /*! Percussion MIDI base tone number at which this drum will be played */ 296 ADL_UInt8 percussion_key_number; 297 /** 298 * @var inst_flags 299 * @brief Instrument flags 300 * 301 * Enums: #ADL_InstrumentFlags and #ADL_RhythmMode 302 * 303 * Bitwise flags bit map: 304 * ``` 305 * [0EEEDCBA] 306 * A) 0x00 - 2-operator mode 307 * B) 0x01 - 4-operator mode 308 * C) 0x02 - pseudo-4-operator (two 2-operator voices) mode 309 * D) 0x04 - is 'blank' instrument (instrument which has no sound) 310 * E) 0x38 - Reserved for rhythm-mode percussion type number (three bits number) 311 * -> 0x00 - Melodic or Generic drum (rhythm-mode is disabled) 312 * -> 0x08 - is Bass drum 313 * -> 0x10 - is Snare 314 * -> 0x18 - is Tom-tom 315 * -> 0x20 - is Cymbal 316 * -> 0x28 - is Hi-hat 317 * 0) Reserved / Unused 318 * ``` 319 */ 320 ADL_UInt8 inst_flags; 321 /*! Feedback&Connection register for first and second operators */ 322 ADL_UInt8 fb_conn1_C0; 323 /*! Feedback&Connection register for third and fourth operators */ 324 ADL_UInt8 fb_conn2_C0; 325 /*! Operators register data */ 326 ADL_Operator operators[4]; 327 /*! Millisecond delay of sounding while key is on */ 328 ADL_UInt16 delay_on_ms; 329 /*! Millisecond delay of sounding after key off */ 330 ADL_UInt16 delay_off_ms; 331 } ADL_Instrument; 332 333 334 /* ======== Setup ======== */ 335 336 /** 337 * @brief Preallocates a minimum number of bank slots. Returns the actual capacity 338 * @param device Instance of the library 339 * @param banks Count of bank slots to pre-allocate. 340 * @return actual capacity of reserved bank slots. 341 */ 342 extern int adl_reserveBanks(struct ADL_MIDIPlayer *device, unsigned banks); 343 /** 344 * @brief Gets the bank designated by the identifier, optionally creating if it does not exist 345 * @param device Instance of the library 346 * @param id Identifier of dynamic bank 347 * @param flags Flags for dynamic bank access (ADL_BankAccessFlags) 348 * @param bank Reference to dynamic bank 349 * @return 0 on success, <0 when any error has occurred 350 */ 351 extern int adl_getBank(struct ADL_MIDIPlayer *device, const ADL_BankId *id, int flags, ADL_Bank *bank); 352 /** 353 * @brief Gets the identifier of a bank 354 * @param device Instance of the library 355 * @param bank Reference to dynamic bank. 356 * @param id Identifier of dynamic bank 357 * @return 0 on success, <0 when any error has occurred 358 */ 359 extern int adl_getBankId(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, ADL_BankId *id); 360 /** 361 * @brief Removes a bank 362 * @param device Instance of the library 363 * @param bank Reference to dynamic bank 364 * @return 0 on success, <0 when any error has occurred 365 */ 366 extern int adl_removeBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank); 367 /** 368 * @brief Gets the first bank 369 * @param device Instance of the library 370 * @param bank Reference to dynamic bank 371 * @return 0 on success, <0 when any error has occurred 372 */ 373 extern int adl_getFirstBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank); 374 /** 375 * @brief Iterates to the next bank 376 * @param device Instance of the library 377 * @param bank Reference to dynamic bank 378 * @return 0 on success, <0 when any error has occurred or end has been reached. 379 */ 380 extern int adl_getNextBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank); 381 /** 382 * @brief Gets the nth intrument in the bank [0..127] 383 * @param device Instance of the library 384 * @param bank Reference to dynamic bank 385 * @param index Index of the instrument 386 * @param ins Instrument entry 387 * @return 0 on success, <0 when any error has occurred 388 */ 389 extern int adl_getInstrument(struct ADL_MIDIPlayer *device, const ADL_Bank *bank, unsigned index, ADL_Instrument *ins); 390 /** 391 * @brief Sets the nth intrument in the bank [0..127] 392 * @param device Instance of the library 393 * @param bank Reference to dynamic bank 394 * @param index Index of the instrument 395 * @param ins Instrument structure pointer 396 * @return 0 on success, <0 when any error has occurred 397 * 398 * This function allows to override an instrument on the fly 399 */ 400 extern int adl_setInstrument(struct ADL_MIDIPlayer *device, ADL_Bank *bank, unsigned index, const ADL_Instrument *ins); 401 /** 402 * @brief Loads the melodic or percussive part of the nth embedded bank 403 * @param device Instance of the library 404 * @param bank Reference to dynamic bank 405 * @param num Number of embedded bank to load into the current bank array 406 * @return 0 on success, <0 when any error has occurred 407 */ 408 extern int adl_loadEmbeddedBank(struct ADL_MIDIPlayer *device, ADL_Bank *bank, int num); 409 410 411 412 /** 413 * @brief Sets number of 4-operator channels between all chips 414 * 415 * By default, it is automatically re-calculating every bank change. 416 * If you want to specify custom number of four operator channels, 417 * please call this function after bank change (adl_setBank() or adl_openBank()), 418 * otherwise, value will be overwritten by auto-calculated. 419 * 420 * @param device Instance of the library 421 * @param ops4 Count of four-op channels to allocate between all emulating chips 422 * @return 0 on success, <0 when any error has occurred 423 */ 424 extern int adl_setNumFourOpsChn(struct ADL_MIDIPlayer *device, int ops4); 425 426 /** 427 * @brief Get current total count of 4-operator channels between all chips 428 * @param device Instance of the library 429 * @return 0 on success, <0 when any error has occurred 430 */ 431 extern int adl_getNumFourOpsChn(struct ADL_MIDIPlayer *device); 432 433 /** 434 * @brief Override Enable(1) or Disable(0) AdLib percussion mode. -1 - use bank default AdLib percussion mode 435 * 436 * This function forces rhythm-mode on any bank. The result will work glitchy. 437 * 438 * @param device Instance of the library 439 * @param percmod 0 - disabled, 1 - enabled 440 */ 441 extern void adl_setPercMode(struct ADL_MIDIPlayer *device, int percmod); 442 443 /** 444 * @brief Override Enable(1) or Disable(0) deep vibrato state. -1 - use bank default vibrato state 445 * @param device Instance of the library 446 * @param hvibro 0 - disabled, 1 - enabled 447 */ 448 extern void adl_setHVibrato(struct ADL_MIDIPlayer *device, int hvibro); 449 450 /** 451 * @brief Override Enable(1) or Disable(0) deep tremolo state. -1 - use bank default tremolo state 452 * @param device Instance of the library 453 * @param htremo 0 - disabled, 1 - enabled 454 */ 455 extern void adl_setHTremolo(struct ADL_MIDIPlayer *device, int htremo); 456 457 /** 458 * @brief Override Enable(1) or Disable(0) scaling of modulator volumes. -1 - use bank default scaling of modulator volumes 459 * @param device Instance of the library 460 * @param smod 0 - disabled, 1 - enabled 461 */ 462 extern void adl_setScaleModulators(struct ADL_MIDIPlayer *device, int smod); 463 464 /** 465 * @brief Enable(1) or Disable(0) full-range brightness (MIDI CC74 used in XG music to filter result sounding) scaling 466 * 467 * By default, brightness affects sound between 0 and 64. 468 * When this option is enabled, the brightness will use full range from 0 up to 127. 469 * 470 * @param device Instance of the library 471 * @param fr_brightness 0 - disabled, 1 - enabled 472 */ 473 extern void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness); 474 475 /** 476 * @brief Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part) 477 * @param device Instance of the library 478 * @param loopEn 0 - disabled, 1 - enabled 479 */ 480 extern void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn); 481 482 /** 483 * @brief [DEPRECATED] Enable or disable Logarithmic volume changer 484 * 485 * This function is deprecated. Suggested replacement: `adl_setVolumeRangeModel` with `ADLMIDI_VolumeModel_NativeOPL3` volume model value; 486 */ 487 DEPRECATED(extern void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int logvol)); 488 489 /** 490 * @brief Set different volume range model 491 * @param device Instance of the library 492 * @param volumeModel Volume model type (#ADLMIDI_VolumeModels) 493 */ 494 extern void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int volumeModel); 495 496 /** 497 * @brief Load WOPL bank file from File System 498 * 499 * Is recommended to call adl_reset() to apply changes to already-loaded file player or real-time. 500 * 501 * @param device Instance of the library 502 * @param filePath Absolute or relative path to the WOPL bank file. UTF8 encoding is required, even on Windows. 503 * @return 0 on success, <0 when any error has occurred 504 */ 505 extern int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath); 506 507 /** 508 * @brief Load WOPL bank file from memory data 509 * 510 * Is recommended to call adl_reset() to apply changes to already-loaded file player or real-time. 511 * 512 * @param device Instance of the library 513 * @param mem Pointer to memory block where is raw data of WOPL bank file is stored 514 * @param size Size of given memory block 515 * @return 0 on success, <0 when any error has occurred 516 */ 517 extern int adl_openBankData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size); 518 519 520 /** 521 * @brief [DEPRECATED] Dummy function 522 * 523 * This function is deprecated. Suggested replacement: `adl_chipEmulatorName` 524 * 525 * @return A string that contains a notice to use `adl_chipEmulatorName` instead of this function. 526 */ 527 DEPRECATED(extern const char *adl_emulatorName()); 528 529 /** 530 * @brief Returns chip emulator name string 531 * @param device Instance of the library 532 * @return Understandable name of current OPL3 emulator 533 */ 534 extern const char *adl_chipEmulatorName(struct ADL_MIDIPlayer *device); 535 536 /** 537 * @brief List of available OPL3 emulators 538 */ 539 enum ADL_Emulator 540 { 541 /*! Nuked OPL3 v. 1.8 */ 542 ADLMIDI_EMU_NUKED = 0, 543 /*! Nuked OPL3 v. 1.7.4 */ 544 ADLMIDI_EMU_NUKED_174, 545 /*! DosBox */ 546 ADLMIDI_EMU_DOSBOX, 547 /*! Count instrument on the level */ 548 ADLMIDI_EMU_end 549 }; 550 551 /** 552 * @brief Switch the emulation core 553 * @param device Instance of the library 554 * @param emulator Type of emulator (#ADL_Emulator) 555 * @return 0 on success, <0 when any error has occurred 556 */ 557 extern int adl_switchEmulator(struct ADL_MIDIPlayer *device, int emulator); 558 559 /** 560 * @brief Library version context 561 */ 562 typedef struct { 563 ADL_UInt16 major; 564 ADL_UInt16 minor; 565 ADL_UInt16 patch; 566 } ADL_Version; 567 568 /** 569 * @brief Run emulator with PCM rate to reduce CPU usage on slow devices. 570 * 571 * May decrease sounding accuracy on some chip emulators. 572 * 573 * @param device Instance of the library 574 * @param enabled 0 - disabled, 1 - enabled 575 * @return 0 on success, <0 when any error has occurred 576 */ 577 extern int adl_setRunAtPcmRate(struct ADL_MIDIPlayer *device, int enabled); 578 579 /** 580 * @brief Set 4-bit device identifier. Used by the SysEx processor. 581 * @param device Instance of the library 582 * @param id 4-bit device identifier 583 * @return 0 on success, <0 when any error has occurred 584 */ 585 extern int adl_setDeviceIdentifier(struct ADL_MIDIPlayer *device, unsigned id); 586 587 /** 588 * @section Information 589 */ 590 591 /** 592 * @brief Returns string which contains a version number 593 * @return String which contains a version of the library 594 */ 595 extern const char *adl_linkedLibraryVersion(); 596 597 /** 598 * @brief Returns structure which contains a version number of library 599 * @return Library version context structure which contains version number of the library 600 */ 601 extern const ADL_Version *adl_linkedVersion(); 602 603 604 /* ======== Error Info ======== */ 605 606 /** 607 * @brief Returns string which contains last error message of initialization 608 * 609 * Don't use this function to get info on any function except of `adl_init`! 610 * Use `adl_errorInfo()` to get error information while workflow 611 * 612 * @return String with error message related to library initialization 613 */ 614 extern const char *adl_errorString(); 615 616 /** 617 * @brief Returns string which contains last error message on specific device 618 * @param device Instance of the library 619 * @return String with error message related to last function call returned non-zero value. 620 */ 621 extern const char *adl_errorInfo(struct ADL_MIDIPlayer *device); 622 623 624 625 /* ======== Initialization ======== */ 626 627 /** 628 * @brief Initialize ADLMIDI Player device 629 * 630 * Tip 1: You can initialize multiple instances and run them in parallel 631 * Tip 2: Library is NOT thread-safe, therefore don't use same instance in different threads or use mutexes 632 * Tip 3: Changing of sample rate on the fly is not supported. Re-create the instance again. 633 * 634 * @param sample_rate Output sample rate 635 * @return Instance of the library. If NULL was returned, check the `adl_errorString` message for more info. 636 */ 637 extern struct ADL_MIDIPlayer *adl_init(long sample_rate); 638 639 /** 640 * @brief Close and delete ADLMIDI device 641 * @param device Instance of the library 642 */ 643 extern void adl_close(struct ADL_MIDIPlayer *device); 644 645 646 647 /* ======== MIDI Sequencer ======== */ 648 649 /** 650 * @brief Load MIDI (or any other supported format) file from File System 651 * 652 * Available when library is built with built-in MIDI Sequencer support. 653 * 654 * @param device Instance of the library 655 * @param filePath Absolute or relative path to the music file. UTF8 encoding is required, even on Windows. 656 * @return 0 on success, <0 when any error has occurred 657 */ 658 extern int adl_openFile(struct ADL_MIDIPlayer *device, const char *filePath); 659 660 /** 661 * @brief Load MIDI (or any other supported format) file from memory data 662 * 663 * Available when library is built with built-in MIDI Sequencer support. 664 * 665 * @param device Instance of the library 666 * @param mem Pointer to memory block where is raw data of music file is stored 667 * @param size Size of given memory block 668 * @return 0 on success, <0 when any error has occurred 669 */ 670 extern int adl_openData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size); 671 672 /** 673 * @brief Resets MIDI player (per-channel setup) into initial state 674 * @param device Instance of the library 675 */ 676 extern void adl_reset(struct ADL_MIDIPlayer *device); 677 678 /** 679 * @brief Get total time length of current song 680 * 681 * Available when library is built with built-in MIDI Sequencer support. 682 * 683 * @param device Instance of the library 684 * @return Total song length in seconds 685 */ 686 extern double adl_totalTimeLength(struct ADL_MIDIPlayer *device); 687 688 /** 689 * @brief Get loop start time if presented. 690 * 691 * Available when library is built with built-in MIDI Sequencer support. 692 * 693 * @param device Instance of the library 694 * @return Time position in seconds of loop start point, or -1 when file has no loop points 695 */ 696 extern double adl_loopStartTime(struct ADL_MIDIPlayer *device); 697 698 /** 699 * @brief Get loop endtime if presented. 700 * 701 * Available when library is built with built-in MIDI Sequencer support. 702 * 703 * @param device Instance of the library 704 * @return Time position in seconds of loop end point, or -1 when file has no loop points 705 */ 706 extern double adl_loopEndTime(struct ADL_MIDIPlayer *device); 707 708 extern void adl_setCallback(struct ADL_MIDIPlayer *device, void (*AdlMidiCallback)(void)); 709 710 /** 711 * @brief Get current time position in seconds 712 * 713 * Available when library is built with built-in MIDI Sequencer support. 714 * 715 * @param device Instance of the library 716 * @return Current time position in seconds 717 */ 718 extern double adl_positionTell(struct ADL_MIDIPlayer *device); 719 720 /** 721 * @brief Jump to absolute time position in seconds 722 * 723 * Available when library is built with built-in MIDI Sequencer support. 724 * 725 * @param device Instance of the library 726 * @param seconds Destination time position in seconds to seek 727 */ 728 extern void adl_positionSeek(struct ADL_MIDIPlayer *device, double seconds); 729 730 /** 731 * @brief Reset MIDI track position to begin 732 * 733 * Available when library is built with built-in MIDI Sequencer support. 734 * 735 * @param device Instance of the library 736 */ 737 extern void adl_positionRewind(struct ADL_MIDIPlayer *device); 738 739 /** 740 * @brief Set tempo multiplier 741 * 742 * Available when library is built with built-in MIDI Sequencer support. 743 * 744 * @param device Instance of the library 745 * @param tempo Tempo multiplier value: 1.0 - original tempo, >1 - play faster, <1 - play slower 746 */ 747 extern void adl_setTempo(struct ADL_MIDIPlayer *device, double tempo); 748 749 /** 750 * @brief Returns 1 if music position has reached end 751 * @param device Instance of the library 752 * @return 1 when end of sing has been reached, otherwise, 0 will be returned. <0 is returned on any error 753 */ 754 extern int adl_atEnd(struct ADL_MIDIPlayer *device); 755 756 /** 757 * @brief Returns the number of tracks of the current sequence 758 * @param device Instance of the library 759 * @return Count of tracks in the current sequence 760 */ 761 extern size_t adl_trackCount(struct ADL_MIDIPlayer *device); 762 763 /** 764 * @brief Track options 765 */ 766 enum ADLMIDI_TrackOptions 767 { 768 /*! Enabled track */ 769 ADLMIDI_TrackOption_On = 1, 770 /*! Disabled track */ 771 ADLMIDI_TrackOption_Off = 2, 772 /*! Solo track */ 773 ADLMIDI_TrackOption_Solo = 3, 774 }; 775 776 /** 777 * @brief Sets options on a track of the current sequence 778 * @param device Instance of the library 779 * @param trackNumber Identifier of the designated track. 780 * @return 0 on success, <0 when any error has occurred 781 */ 782 extern int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions); 783 784 785 786 /* ======== Meta-Tags ======== */ 787 788 /** 789 * @brief Returns string which contains a music title 790 * @param device Instance of the library 791 * @return A string that contains music title 792 */ 793 extern const char *adl_metaMusicTitle(struct ADL_MIDIPlayer *device); 794 795 /** 796 * @brief Returns string which contains a copyright string* 797 * @param device Instance of the library 798 * @return A string that contains copyright notice, otherwise NULL 799 */ 800 extern const char *adl_metaMusicCopyright(struct ADL_MIDIPlayer *device); 801 802 /** 803 * @brief Returns count of available track titles 804 * 805 * NOTE: There are CAN'T be associated with channel in any of event or note hooks 806 * 807 * @param device Instance of the library 808 * @return Count of available MIDI tracks, otherwise NULL 809 */ 810 extern size_t adl_metaTrackTitleCount(struct ADL_MIDIPlayer *device); 811 812 /** 813 * @brief Get track title by index 814 * @param device Instance of the library 815 * @param index Index of the track to retreive the title 816 * @return A string that contains track title, otherwise NULL. 817 */ 818 extern const char *adl_metaTrackTitle(struct ADL_MIDIPlayer *device, size_t index); 819 820 /** 821 * @brief MIDI Marker structure 822 */ 823 struct Adl_MarkerEntry 824 { 825 /*! MIDI Marker title */ 826 const char *label; 827 /*! Absolute time position of the marker in seconds */ 828 double pos_time; 829 /*! Absolute time position of the marker in MIDI ticks */ 830 unsigned long pos_ticks; 831 }; 832 833 /** 834 * @brief Returns count of available markers 835 * @param device Instance of the library 836 * @return Count of available MIDI markers 837 */ 838 extern size_t adl_metaMarkerCount(struct ADL_MIDIPlayer *device); 839 840 /** 841 * @brief Returns the marker entry 842 * @param device Instance of the library 843 * @param index Index of the marker to retreive it. 844 * @return MIDI Marker description structure. 845 */ 846 extern struct Adl_MarkerEntry adl_metaMarker(struct ADL_MIDIPlayer *device, size_t index); 847 848 849 850 851 /* ======== Audio output Generation ======== */ 852 853 /** 854 * @brief Generate PCM signed 16-bit stereo audio output and iterate MIDI timers 855 * 856 * Use this function when you are playing MIDI file loaded by `adl_openFile` or by `adl_openData` 857 * with using of built-in MIDI sequencer. 858 * 859 * Don't use count of frames, use instead count of samples. One frame is two samples. 860 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 861 * 862 * Available when library is built with built-in MIDI Sequencer support. 863 * 864 * @param device Instance of the library 865 * @param sampleCount Count of samples (not frames!) 866 * @param out Pointer to output with 16-bit stereo PCM output 867 * @return Count of given samples, otherwise, 0 or when catching an error while playing 868 */ 869 extern int adl_play(struct ADL_MIDIPlayer *device, int sampleCount, short *out); 870 871 /** 872 * @brief Generate PCM stereo audio output in sample format declared by given context and iterate MIDI timers 873 * 874 * Use this function when you are playing MIDI file loaded by `adl_openFile` or by `adl_openData` 875 * with using of built-in MIDI sequencer. 876 * 877 * Don't use count of frames, use instead count of samples. One frame is two samples. 878 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 879 * 880 * Available when library is built with built-in MIDI Sequencer support. 881 * 882 * @param device Instance of the library 883 * @param sampleCount Count of samples (not frames!) 884 * @param left Left channel buffer output (Must be casted into bytes array) 885 * @param right Right channel buffer output (Must be casted into bytes array) 886 * @param format Destination PCM format format context 887 * @return Count of given samples, otherwise, 0 or when catching an error while playing 888 */ 889 extern int adl_playFormat(struct ADL_MIDIPlayer *device, int sampleCount, ADL_UInt8 *left, ADL_UInt8 *right, const struct ADLMIDI_AudioFormat *format); 890 891 /** 892 * @brief Generate PCM signed 16-bit stereo audio output without iteration of MIDI timers 893 * 894 * Use this function when you are using library as Real-Time MIDI synthesizer or with 895 * an external MIDI sequencer. You must to request the amount of samples which is equal 896 * to the delta between of MIDI event rows. One MIDI row is a group of MIDI events 897 * are having zero delta/delay between each other. When you are receiving events in 898 * real time, request the minimal possible delay value. 899 * 900 * Don't use count of frames, use instead count of samples. One frame is two samples. 901 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 902 * 903 * @param device Instance of the library 904 * @param sampleCount 905 * @param out Pointer to output with 16-bit stereo PCM output 906 * @return Count of given samples, otherwise, 0 or when catching an error while playing 907 */ 908 extern int adl_generate(struct ADL_MIDIPlayer *device, int sampleCount, short *out); 909 910 /** 911 * @brief Generate PCM stereo audio output in sample format declared by given context without iteration of MIDI timers 912 * 913 * Use this function when you are using library as Real-Time MIDI synthesizer or with 914 * an external MIDI sequencer. You must to request the amount of samples which is equal 915 * to the delta between of MIDI event rows. One MIDI row is a group of MIDI events 916 * are having zero delta/delay between each other. When you are receiving events in 917 * real time, request the minimal possible delay value. 918 * 919 * Don't use count of frames, use instead count of samples. One frame is two samples. 920 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 921 * 922 * @param device Instance of the library 923 * @param sampleCount 924 * @param left Left channel buffer output (Must be casted into bytes array) 925 * @param right Right channel buffer output (Must be casted into bytes array) 926 * @param format Destination PCM format format context 927 * @return Count of given samples, otherwise, 0 or when catching an error while playing 928 */ 929 extern int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleCount, ADL_UInt8 *left, ADL_UInt8 *right, const struct ADLMIDI_AudioFormat *format); 930 931 /** 932 * @brief Periodic tick handler. 933 * 934 * Notice: The function is provided to use it with Hardware OPL3 mode or for the purpose to iterate 935 * MIDI playback without of sound generation. 936 * 937 * DON'T USE IT TOGETHER WITH adl_play() and adl_playFormat() calls 938 * as there are all using this function internally!!! 939 * 940 * @param device Instance of the library 941 * @param seconds Previous delay. On a first moment, pass the `0.0` 942 * @param granulality Minimal size of one MIDI tick in seconds. 943 * @return desired number of seconds until next call. Pass this value into `seconds` field in next time 944 */ 945 extern double adl_tickEvents(struct ADL_MIDIPlayer *device, double seconds, double granulality); 946 947 948 949 950 /* ======== Real-Time MIDI ======== */ 951 952 /** 953 * @brief Force Off all notes on all channels 954 * @param device Instance of the library 955 */ 956 extern void adl_panic(struct ADL_MIDIPlayer *device); 957 958 /** 959 * @brief Reset states of all controllers on all MIDI channels 960 * @param device Instance of the library 961 */ 962 extern void adl_rt_resetState(struct ADL_MIDIPlayer *device); 963 964 /** 965 * @brief Turn specific MIDI note ON 966 * @param device Instance of the library 967 * @param channel Target MIDI channel [Between 0 and 16] 968 * @param note Note number to on [Between 0 and 127] 969 * @param velocity Velocity level [Between 0 and 127] 970 * @return 1 when note was successfully started, 0 when note was rejected by any reason. 971 */ 972 extern int adl_rt_noteOn(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note, ADL_UInt8 velocity); 973 974 /** 975 * @brief Turn specific MIDI note OFF 976 * @param device Instance of the library 977 * @param channel Target MIDI channel [Between 0 and 16] 978 * @param note Note number to off [Between 0 and 127] 979 */ 980 extern void adl_rt_noteOff(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note); 981 982 /** 983 * @brief Set note after-touch 984 * @param device Instance of the library 985 * @param channel Target MIDI channel [Between 0 and 16] 986 * @param note Note number to affect by aftertouch event [Between 0 and 127] 987 * @param atVal After-Touch value [Between 0 and 127] 988 */ 989 extern void adl_rt_noteAfterTouch(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 note, ADL_UInt8 atVal); 990 991 /** 992 * @brief Set channel after-touch 993 * @param device Instance of the library 994 * @param channel Target MIDI channel [Between 0 and 16] 995 * @param atVal After-Touch level [Between 0 and 127] 996 */ 997 extern void adl_rt_channelAfterTouch(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 atVal); 998 999 /** 1000 * @brief Apply controller change 1001 * @param device Instance of the library 1002 * @param channel Target MIDI channel [Between 0 and 16] 1003 * @param type Type of the controller [Between 0 and 255] 1004 * @param value Value of the controller event [Between 0 and 127] 1005 */ 1006 extern void adl_rt_controllerChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 type, ADL_UInt8 value); 1007 1008 /** 1009 * @brief Apply patch change 1010 * @param device Instance of the library 1011 * @param channel Target MIDI channel [Between 0 and 16] 1012 * @param patch Patch number [Between 0 and 127] 1013 */ 1014 extern void adl_rt_patchChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 patch); 1015 1016 /** 1017 * @brief Apply pitch bend change 1018 * @param device Instance of the library 1019 * @param channel Target MIDI channel [Between 0 and 16] 1020 * @param pitch 24-bit pitch bend value 1021 */ 1022 extern void adl_rt_pitchBend(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt16 pitch); 1023 1024 /** 1025 * @brief Apply pitch bend change 1026 * @param device Instance of the library 1027 * @param channel Target MIDI channel [Between 0 and 16] 1028 * @param msb MSB part of 24-bit pitch bend value 1029 * @param lsb LSB part of 24-bit pitch bend value 1030 */ 1031 extern void adl_rt_pitchBendML(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 msb, ADL_UInt8 lsb); 1032 1033 /** 1034 * @brief Change LSB of the bank number (Alias to CC-32 event) 1035 * @param device Instance of the library 1036 * @param channel Target MIDI channel [Between 0 and 16] 1037 * @param lsb LSB value of the MIDI bank number 1038 */ 1039 extern void adl_rt_bankChangeLSB(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 lsb); 1040 1041 /** 1042 * @brief Change MSB of the bank (Alias to CC-0 event) 1043 * @param device Instance of the library 1044 * @param channel Target MIDI channel [Between 0 and 16] 1045 * @param msb MSB value of the MIDI bank number 1046 */ 1047 extern void adl_rt_bankChangeMSB(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 msb); 1048 1049 /** 1050 * @brief Change bank by absolute signed value 1051 * @param device Instance of the library 1052 * @param channel Target MIDI channel [Between 0 and 16] 1053 * @param bank Bank number as concoctated signed 16-bit value of MSB and LSB parts. 1054 */ 1055 1056 extern void adl_rt_bankChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_SInt16 bank); 1057 1058 /** 1059 * @brief Perform a system exclusive message 1060 * @param device Instance of the library 1061 * @param msg Raw SysEx message buffer (must begin with 0xF0 and end with 0xF7) 1062 * @param size Size of given SysEx message buffer 1063 * @return 1 when SysEx message was successfully processed, 0 when SysEx message was rejected by any reason 1064 */ 1065 extern int adl_rt_systemExclusive(struct ADL_MIDIPlayer *device, const ADL_UInt8 *msg, size_t size); 1066 1067 1068 1069 1070 /* ======== Hooks and debugging ======== */ 1071 1072 /** 1073 * @brief Raw event callback 1074 * @param userdata Pointer to user data (usually, context of someting) 1075 * @param type MIDI event type 1076 * @param subtype MIDI event sub-type (special events only) 1077 * @param channel MIDI channel 1078 * @param data Raw event data 1079 * @param len Length of event data 1080 */ 1081 typedef void (*ADL_RawEventHook)(void *userdata, ADL_UInt8 type, ADL_UInt8 subtype, ADL_UInt8 channel, const ADL_UInt8 *data, size_t len); 1082 1083 /** 1084 * @brief Note on/off callback 1085 * @param userdata Pointer to user data (usually, context of someting) 1086 * @param adlchn Chip channel where note was played 1087 * @param note Note number [between 0 and 127] 1088 * @param pressure Velocity level, or -1 when it's note off event 1089 * @param bend Pitch bend offset value 1090 */ 1091 typedef void (*ADL_NoteHook)(void *userdata, int adlchn, int note, int ins, int pressure, double bend); 1092 1093 /** 1094 * @brief Debug messages callback 1095 * @param userdata Pointer to user data (usually, context of someting) 1096 * @param fmt Format strign output (in context of `printf()` standard function) 1097 */ 1098 typedef void (*ADL_DebugMessageHook)(void *userdata, const char *fmt, ...); 1099 1100 /** 1101 * @brief Set raw MIDI event hook 1102 * @param device Instance of the library 1103 * @param rawEventHook Pointer to the callback function which will be called on every MIDI event 1104 * @param userData Pointer to user data which will be passed through the callback. 1105 */ 1106 extern void adl_setRawEventHook(struct ADL_MIDIPlayer *device, ADL_RawEventHook rawEventHook, void *userData); 1107 1108 /** 1109 * @brief Set note hook 1110 * @param device Instance of the library 1111 * @param noteHook Pointer to the callback function which will be called on every noteOn MIDI event 1112 * @param userData Pointer to user data which will be passed through the callback. 1113 */ 1114 extern void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_NoteHook noteHook, void *userData); 1115 1116 /** 1117 * @brief Set debug message hook 1118 * @param device Instance of the library 1119 * @param debugMessageHook Pointer to the callback function which will be called on every debug message 1120 * @param userData Pointer to user data which will be passed through the callback. 1121 */ 1122 extern void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData); 1123 1124 /** 1125 * @brief Get a textual description of the channel state. For display only. 1126 * @param device Instance of the library 1127 * @param text Destination char buffer for channel usage state. Every entry is assigned to the chip channel. 1128 * @param attr Destination char buffer for additional attributes like MIDI channel number that uses this chip channel. 1129 * @param size Size of given buffers (both text and attr are must have same size!) 1130 * @return 0 on success, <0 when any error has occurred 1131 * 1132 * Every character in the `text` buffer means the type of usage: 1133 * ``` 1134 * `-` - channel is unused (free) 1135 * `+` - channel is used by two-operator voice 1136 * `#` - channel is used by four-operator voice 1137 * `@` - channel is used to play automatic arpeggio on chip channels overflow 1138 * `r` - rhythm-mode channel note 1139 * ``` 1140 * 1141 * The `attr` field receives the MIDI channel from which the chip channel is used. 1142 * To get the valid MIDI channel you will need to apply the & 0x0F mask to every value. 1143 */ 1144 extern int adl_describeChannels(struct ADL_MIDIPlayer *device, char *text, char *attr, size_t size); 1145 1146 #ifdef __cplusplus 1147 } 1148 #endif 1149 1150 #endif /* ADLMIDI_H */ 1151