1 /* 2 * libOPNMIDI is a free Software MIDI synthesizer library with OPN2 (YM2612) emulation 3 * 4 * MIDI parser and player (Original code from ADLMIDI): Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> 5 * OPNMIDI Library and YM2612 support: Copyright (c) 2017-2020 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 OPNMIDI_H 25 #define OPNMIDI_H 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 #define OPNMIDI_VERSION_MAJOR 1 32 #define OPNMIDI_VERSION_MINOR 5 33 #define OPNMIDI_VERSION_PATCHLEVEL 0 34 35 #define OPNMIDI_TOSTR_I(s) #s 36 #define OPNMIDI_TOSTR(s) OPNMIDI_TOSTR_I(s) 37 #define OPNMIDI_VERSION \ 38 OPNMIDI_TOSTR(OPNMIDI_VERSION_MAJOR) "." \ 39 OPNMIDI_TOSTR(OPNMIDI_VERSION_MINOR) "." \ 40 OPNMIDI_TOSTR(OPNMIDI_VERSION_PATCHLEVEL) 41 42 #define OPN_OPN2_SAMPLE_RATE 53267 43 #define OPN_OPNA_SAMPLE_RATE 55466 44 45 #include <stddef.h> 46 47 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 48 #include <stdint.h> 49 typedef uint8_t OPN2_UInt8; 50 typedef uint16_t OPN2_UInt16; 51 typedef int8_t OPN2_SInt8; 52 typedef int16_t OPN2_SInt16; 53 #else 54 typedef unsigned char OPN2_UInt8; 55 typedef unsigned short OPN2_UInt16; 56 typedef char OPN2_SInt8; 57 typedef short OPN2_SInt16; 58 #endif 59 60 61 /* == Deprecated function markers == */ 62 63 #if defined(_MSC_VER) /* MSVC */ 64 # if _MSC_VER >= 1500 /* MSVC 2008 */ 65 /*! Indicates that the following function is deprecated. */ 66 # define OPNMIDI_DEPRECATED(message) __declspec(deprecated(message)) 67 # endif 68 #endif /* defined(_MSC_VER) */ 69 70 #ifdef __clang__ 71 # if __has_extension(attribute_deprecated_with_message) 72 # define OPNMIDI_DEPRECATED(message) __attribute__((deprecated(message))) 73 # endif 74 #elif defined __GNUC__ /* not clang (gcc comes later since clang emulates gcc) */ 75 # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 76 # define OPNMIDI_DEPRECATED(message) __attribute__((deprecated(message))) 77 # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 78 # define OPNMIDI_DEPRECATED(message) __attribute__((__deprecated__)) 79 # endif /* GNUC version */ 80 #endif /* __clang__ || __GNUC__ */ 81 82 #if !defined(OPNMIDI_DEPRECATED) 83 # define OPNMIDI_DEPRECATED(message) 84 #endif /* if !defined(OPNMIDI_DEPRECATED) */ 85 86 87 #ifdef OPNMIDI_BUILD 88 # ifndef OPNMIDI_DECLSPEC 89 # if defined (_WIN32) && defined(OPNMIDI_BUILD_DLL) 90 # define OPNMIDI_DECLSPEC __declspec(dllexport) 91 # else 92 # define OPNMIDI_DECLSPEC 93 # endif 94 # endif 95 #else 96 # define OPNMIDI_DECLSPEC 97 #endif 98 99 /** 100 * @brief Chip types 101 */ 102 enum OPNMIDI_ChipType 103 { 104 /*! The Yamaha OPN2, alias YM2612 YM3438 */ 105 OPNMIDI_ChipType_OPN2 = 0, 106 /*! The Yamaha OPNA, alias YM2608 */ 107 OPNMIDI_ChipType_OPNA 108 }; 109 110 /** 111 * @brief Volume scaling models 112 */ 113 enum OPNMIDI_VolumeModels 114 { 115 /*! Automatical choice by the specific bank */ 116 OPNMIDI_VolumeModel_AUTO = 0, 117 /*! Linearized scaling model, most standard */ 118 OPNMIDI_VolumeModel_Generic, 119 /*! Native OPN2's logarithmic volume scale */ 120 OPNMIDI_VolumeModel_NativeOPN2, 121 /*! Logarithmic volume scale, using volume map table. Used in DMX. */ 122 OPNMIDI_VolumeModel_DMX, 123 /*! Logarithmic volume scale, used in Apogee Sound System. */ 124 OPNMIDI_VolumeModel_APOGEE, 125 /*! Aproximated and shorted volume map table. Similar to general, but has less granularity. */ 126 OPNMIDI_VolumeModel_9X 127 }; 128 129 /** 130 * @brief Sound output format 131 */ 132 enum OPNMIDI_SampleType 133 { 134 /*! signed PCM 16-bit */ 135 OPNMIDI_SampleType_S16 = 0, 136 /*! signed PCM 8-bit */ 137 OPNMIDI_SampleType_S8, 138 /*! float 32-bit */ 139 OPNMIDI_SampleType_F32, 140 /*! float 64-bit */ 141 OPNMIDI_SampleType_F64, 142 /*! signed PCM 24-bit */ 143 OPNMIDI_SampleType_S24, 144 /*! signed PCM 32-bit */ 145 OPNMIDI_SampleType_S32, 146 /*! unsigned PCM 8-bit */ 147 OPNMIDI_SampleType_U8, 148 /*! unsigned PCM 16-bit */ 149 OPNMIDI_SampleType_U16, 150 /*! unsigned PCM 24-bit */ 151 OPNMIDI_SampleType_U24, 152 /*! unsigned PCM 32-bit */ 153 OPNMIDI_SampleType_U32, 154 /*! Count of available sample format types */ 155 OPNMIDI_SampleType_Count 156 }; 157 158 /** 159 * @brief Sound output format context 160 */ 161 struct OPNMIDI_AudioFormat 162 { 163 /*! type of sample */ 164 enum OPNMIDI_SampleType type; 165 /*! size in bytes of the storage type */ 166 unsigned containerSize; 167 /*! distance in bytes between consecutive samples */ 168 unsigned sampleOffset; 169 }; 170 171 /** 172 * @brief Instance of the library 173 */ 174 struct OPN2_MIDIPlayer 175 { 176 /*! Private context descriptor */ 177 void *opn2_midiPlayer; 178 }; 179 180 /* DEPRECATED */ 181 #define opn2_setNumCards opn2_setNumChips 182 183 /** 184 * @brief Sets number of emulated chips (from 1 to 100). Emulation of multiple chips extends polyphony limits 185 * @param device Instance of the library 186 * @param numChips Count of virtual chips to emulate 187 * @return 0 on success, <0 when any error has occurred 188 */ 189 extern OPNMIDI_DECLSPEC int opn2_setNumChips(struct OPN2_MIDIPlayer *device, int numCards); 190 191 /** 192 * @brief Get current number of emulated chips 193 * @param device Instance of the library 194 * @return Count of working chip emulators 195 */ 196 extern OPNMIDI_DECLSPEC int opn2_getNumChips(struct OPN2_MIDIPlayer *device); 197 198 /** 199 * @brief Get obtained number of emulated chips 200 * @param device Instance of the library 201 * @return Count of working chip emulators 202 */ 203 extern OPNMIDI_DECLSPEC int opn2_getNumChipsObtained(struct OPN2_MIDIPlayer *device); 204 205 /** 206 * @brief Reference to dynamic bank 207 */ 208 typedef struct OPN2_Bank 209 { 210 void *pointer[3]; 211 } OPN2_Bank; 212 213 /** 214 * @brief Identifier of dynamic bank 215 */ 216 typedef struct OPN2_BankId 217 { 218 /*! 0 if bank is melodic set, or 1 if bank is a percussion set */ 219 OPN2_UInt8 percussive; 220 /*! Assign to MSB bank number */ 221 OPN2_UInt8 msb; 222 /*! Assign to LSB bank number */ 223 OPN2_UInt8 lsb; 224 } OPN2_BankId; 225 226 /** 227 * @brief Flags for dynamic bank access 228 */ 229 enum OPN2_BankAccessFlags 230 { 231 /*! create bank, allocating memory as needed */ 232 OPNMIDI_Bank_Create = 1, 233 /*! create bank, never allocating memory */ 234 OPNMIDI_Bank_CreateRt = 1|2 235 }; 236 237 238 239 /* ======== Instrument structures ======== */ 240 241 /** 242 * @brief Version of the instrument data format 243 */ 244 enum 245 { 246 OPNMIDI_InstrumentVersion = 0 247 }; 248 249 /** 250 * @brief Instrument flags 251 */ 252 typedef enum OPN2_InstrumentFlags 253 { 254 OPNMIDI_Ins_Pseudo8op = 0x01, /*Reserved for future use, not implemented yet*/ 255 OPNMIDI_Ins_IsBlank = 0x02 256 } OPN2_InstrumentFlags; 257 258 /** 259 * @brief Operator structure, part of Instrument structure 260 */ 261 typedef struct OPN2_Operator 262 { 263 /* Detune and frequency multiplication register data */ 264 OPN2_UInt8 dtfm_30; 265 /* Total level register data */ 266 OPN2_UInt8 level_40; 267 /* Rate scale and attack register data */ 268 OPN2_UInt8 rsatk_50; 269 /* Amplitude modulation enable and Decay-1 register data */ 270 OPN2_UInt8 amdecay1_60; 271 /* Decay-2 register data */ 272 OPN2_UInt8 decay2_70; 273 /* Sustain and Release register data */ 274 OPN2_UInt8 susrel_80; 275 /* SSG-EG register data */ 276 OPN2_UInt8 ssgeg_90; 277 } OPN2_Operator; 278 279 /** 280 * @brief Instrument structure 281 */ 282 typedef struct OPN2_Instrument 283 { 284 /*! Version of the instrument object */ 285 int version; 286 /* MIDI note key (half-tone) offset for an instrument (or a first voice in pseudo-4-op mode) */ 287 OPN2_SInt16 note_offset; 288 /* Reserved */ 289 OPN2_SInt8 midi_velocity_offset; 290 /* Percussion MIDI base tone number at which this drum will be played */ 291 OPN2_UInt8 percussion_key_number; 292 /* Instrument flags */ 293 OPN2_UInt8 inst_flags; 294 /* Feedback and Algorithm register data */ 295 OPN2_UInt8 fbalg; 296 /* LFO Sensitivity register data */ 297 OPN2_UInt8 lfosens; 298 /* Operators register data */ 299 OPN2_Operator operators[4]; 300 /* Millisecond delay of sounding while key is on */ 301 OPN2_UInt16 delay_on_ms; 302 /* Millisecond delay of sounding after key off */ 303 OPN2_UInt16 delay_off_ms; 304 } OPN2_Instrument; 305 306 307 308 309 /* ======== Setup ======== */ 310 311 #ifdef OPNMIDI_UNSTABLE_API 312 313 /** 314 * @brief Preallocates a minimum number of bank slots. Returns the actual capacity 315 * @param device Instance of the library 316 * @param banks Count of bank slots to pre-allocate. 317 * @return actual capacity of reserved bank slots. 318 */ 319 extern OPNMIDI_DECLSPEC int opn2_reserveBanks(struct OPN2_MIDIPlayer *device, unsigned banks); 320 /** 321 * @brief Gets the bank designated by the identifier, optionally creating if it does not exist 322 * @param device Instance of the library 323 * @param id Identifier of dynamic bank 324 * @param flags Flags for dynamic bank access (OPN2_BankAccessFlags) 325 * @param bank Reference to dynamic bank 326 * @return 0 on success, <0 when any error has occurred 327 */ 328 extern OPNMIDI_DECLSPEC int opn2_getBank(struct OPN2_MIDIPlayer *device, const OPN2_BankId *id, int flags, OPN2_Bank *bank); 329 /** 330 * @brief Gets the identifier of a bank 331 * @param device Instance of the library 332 * @param bank Reference to dynamic bank. 333 * @param id Identifier of dynamic bank 334 * @return 0 on success, <0 when any error has occurred 335 */ 336 extern OPNMIDI_DECLSPEC int opn2_getBankId(struct OPN2_MIDIPlayer *device, const OPN2_Bank *bank, OPN2_BankId *id); 337 /** 338 * @brief Removes a bank 339 * @param device Instance of the library 340 * @param bank Reference to dynamic bank 341 * @return 0 on success, <0 when any error has occurred 342 */ 343 extern OPNMIDI_DECLSPEC int opn2_removeBank(struct OPN2_MIDIPlayer *device, OPN2_Bank *bank); 344 /** 345 * @brief Gets the first bank 346 * @param device Instance of the library 347 * @param bank Reference to dynamic bank 348 * @return 0 on success, <0 when any error has occurred 349 */ 350 extern OPNMIDI_DECLSPEC int opn2_getFirstBank(struct OPN2_MIDIPlayer *device, OPN2_Bank *bank); 351 /** 352 * @brief Iterates to the next bank 353 * @param device Instance of the library 354 * @param bank Reference to dynamic bank 355 * @return 0 on success, <0 when any error has occurred or end has been reached. 356 */ 357 extern OPNMIDI_DECLSPEC int opn2_getNextBank(struct OPN2_MIDIPlayer *device, OPN2_Bank *bank); 358 /** 359 * @brief Gets the nth intrument in the bank [0..127] 360 * @param device Instance of the library 361 * @param bank Reference to dynamic bank 362 * @param index Index of the instrument 363 * @param ins Instrument entry 364 * @return 0 on success, <0 when any error has occurred 365 */ 366 extern OPNMIDI_DECLSPEC int opn2_getInstrument(struct OPN2_MIDIPlayer *device, const OPN2_Bank *bank, unsigned index, OPN2_Instrument *ins); 367 /** 368 * @brief Sets the nth intrument in the bank [0..127] 369 * @param device Instance of the library 370 * @param bank Reference to dynamic bank 371 * @param index Index of the instrument 372 * @param ins Instrument structure pointer 373 * @return 0 on success, <0 when any error has occurred 374 * 375 * This function allows to override an instrument on the fly 376 */ 377 extern OPNMIDI_DECLSPEC int opn2_setInstrument(struct OPN2_MIDIPlayer *device, OPN2_Bank *bank, unsigned index, const OPN2_Instrument *ins); 378 379 #endif /* OPNMIDI_UNSTABLE_API */ 380 381 382 383 /*Override Enable(1) or Disable(0) LFO. -1 - use bank default state*/ 384 extern OPNMIDI_DECLSPEC void opn2_setLfoEnabled(struct OPN2_MIDIPlayer *device, int lfoEnable); 385 386 /*Get the LFO state*/ 387 extern OPNMIDI_DECLSPEC int opn2_getLfoEnabled(struct OPN2_MIDIPlayer *device); 388 389 /*Override LFO frequency. -1 - use bank default state*/ 390 extern OPNMIDI_DECLSPEC void opn2_setLfoFrequency(struct OPN2_MIDIPlayer *device, int lfoFrequency); 391 392 /*Get the LFO frequency*/ 393 extern OPNMIDI_DECLSPEC int opn2_getLfoFrequency(struct OPN2_MIDIPlayer *device); 394 395 /*Override chip type. -1 - use bank default state*/ 396 extern OPNMIDI_DECLSPEC void opn2_setChipType(struct OPN2_MIDIPlayer *device, int chipType); 397 398 /*Get the chip type*/ 399 extern OPNMIDI_DECLSPEC int opn2_getChipType(struct OPN2_MIDIPlayer *device); 400 401 /** 402 * @brief Override Enable(1) or Disable(0) scaling of modulator volumes. -1 - use bank default scaling of modulator volumes 403 * @param device Instance of the library 404 * @param smod 0 - disabled, 1 - enabled 405 */ 406 extern OPNMIDI_DECLSPEC void opn2_setScaleModulators(struct OPN2_MIDIPlayer *device, int smod); 407 408 /** 409 * @brief Enable(1) or Disable(0) full-range brightness (MIDI CC74 used in XG music to filter result sounding) scaling 410 * 411 * By default, brightness affects sound between 0 and 64. 412 * When this option is enabled, the brightness will use full range from 0 up to 127. 413 * 414 * @param device Instance of the library 415 * @param fr_brightness 0 - disabled, 1 - enabled 416 */ 417 extern OPNMIDI_DECLSPEC void opn2_setFullRangeBrightness(struct OPN2_MIDIPlayer *device, int fr_brightness); 418 419 /** 420 * @brief Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part) 421 * @param device Instance of the library 422 * @param loopEn 0 - disabled, 1 - enabled 423 */ 424 extern OPNMIDI_DECLSPEC void opn2_setLoopEnabled(struct OPN2_MIDIPlayer *device, int loopEn); 425 426 /** 427 * @brief Enable or disable soft panning with chip emulators 428 * @param device Instance of the library 429 * @param softPanEn 0 - disabled, 1 - enabled 430 */ 431 extern OPNMIDI_DECLSPEC void opn2_setSoftPanEnabled(struct OPN2_MIDIPlayer *device, int softPanEn); 432 433 /** 434 * @brief [DEPRECATED] Enable or disable Logarithmic volume changer 435 * 436 * This function is deprecated. Suggested replacement: `opn2_setVolumeRangeModel` with `OPNMIDI_VolumeModel_NativeOPN2` volume model value; 437 */ 438 OPNMIDI_DEPRECATED("Use `opn2_setVolumeRangeModel(device, OPNMIDI_VolumeModel_NativeOPN2)` instead") 439 extern OPNMIDI_DECLSPEC void opn2_setLogarithmicVolumes(struct OPN2_MIDIPlayer *device, int logvol); 440 441 /** 442 * @brief Set different volume range model 443 * @param device Instance of the library 444 * @param volumeModel Volume model type (#OPNMIDI_VolumeModels) 445 */ 446 extern OPNMIDI_DECLSPEC void opn2_setVolumeRangeModel(struct OPN2_MIDIPlayer *device, int volumeModel); 447 448 /** 449 * @brief Get the volume range model 450 * @param device Instance of the library 451 * @return volume model on success, <0 when any error has occurred 452 */ 453 extern OPNMIDI_DECLSPEC int opn2_getVolumeRangeModel(struct OPN2_MIDIPlayer *device); 454 455 /** 456 * @brief Load WOPN bank file from File System 457 * 458 * Is recommended to call adl_reset() to apply changes to already-loaded file player or real-time. 459 * 460 * @param device Instance of the library 461 * @param filePath Absolute or relative path to the WOPL bank file. UTF8 encoding is required, even on Windows. 462 * @return 0 on success, <0 when any error has occurred 463 */ 464 extern OPNMIDI_DECLSPEC int opn2_openBankFile(struct OPN2_MIDIPlayer *device, const char *filePath); 465 466 /** 467 * @brief Load WOPN bank file from memory data 468 * 469 * Is recommended to call adl_reset() to apply changes to already-loaded file player or real-time. 470 * 471 * @param device Instance of the library 472 * @param mem Pointer to memory block where is raw data of WOPL bank file is stored 473 * @param size Size of given memory block 474 * @return 0 on success, <0 when any error has occurred 475 */ 476 extern OPNMIDI_DECLSPEC int opn2_openBankData(struct OPN2_MIDIPlayer *device, const void *mem, long size); 477 478 479 /** 480 * @brief [DEPRECATED] Dummy function 481 * 482 * This function is deprecated. Suggested replacement: `opn2_chipEmulatorName` 483 * 484 * @return A string that contains a notice to use `opn2_chipEmulatorName` instead of this function. 485 */ 486 OPNMIDI_DEPRECATED("Use `adl_chipEmulatorName(device)` instead") 487 extern OPNMIDI_DECLSPEC const char *opn2_emulatorName(); 488 489 /** 490 * @brief Returns chip emulator name string 491 * @param device Instance of the library 492 * @return Understandable name of current OPN2 emulator 493 */ 494 extern OPNMIDI_DECLSPEC const char *opn2_chipEmulatorName(struct OPN2_MIDIPlayer *device); 495 496 /** 497 * @brief List of available OPN2 emulators 498 */ 499 enum Opn2_Emulator 500 { 501 /*! Mame YM2612 */ 502 OPNMIDI_EMU_MAME = 0, 503 /*! Nuked OPN2 */ 504 OPNMIDI_EMU_NUKED, 505 /*! GENS */ 506 OPNMIDI_EMU_GENS, 507 /*! Genesis Plus GX (a fork of Mame YM2612) */ 508 OPNMIDI_EMU_GX, 509 /*! Neko Project II OPNA */ 510 OPNMIDI_EMU_NP2, 511 /*! Mame YM2608 */ 512 OPNMIDI_EMU_MAME_2608, 513 /*! PMDWin OPNA */ 514 OPNMIDI_EMU_PMDWIN, 515 /*! VGM file dumper (required for MIDI2VGM) */ 516 OPNMIDI_VGM_DUMPER, 517 /*! Count instrument on the level */ 518 OPNMIDI_EMU_end 519 }; 520 521 /** 522 * @brief Switch the emulation core 523 * @param device Instance of the library 524 * @param emulator Type of emulator (#Opn2_Emulator) 525 * @return 0 on success, <0 when any error has occurred 526 */ 527 extern OPNMIDI_DECLSPEC int opn2_switchEmulator(struct OPN2_MIDIPlayer *device, int emulator); 528 529 /** 530 * @brief Library version context 531 */ 532 typedef struct { 533 OPN2_UInt16 major; 534 OPN2_UInt16 minor; 535 OPN2_UInt16 patch; 536 } OPN2_Version; 537 538 /** 539 * @brief Run emulator with PCM rate to reduce CPU usage on slow devices. 540 * 541 * May decrease sounding accuracy on some chip emulators. 542 * 543 * @param device Instance of the library 544 * @param enabled 0 - disabled, 1 - enabled 545 * @return 0 on success, <0 when any error has occurred 546 */ 547 extern OPNMIDI_DECLSPEC int opn2_setRunAtPcmRate(struct OPN2_MIDIPlayer *device, int enabled); 548 549 /** 550 * @brief Set 4-bit device identifier. Used by the SysEx processor. 551 * @param device Instance of the library 552 * @param id 4-bit device identifier 553 * @return 0 on success, <0 when any error has occurred 554 */ 555 extern OPNMIDI_DECLSPEC int opn2_setDeviceIdentifier(struct OPN2_MIDIPlayer *device, unsigned id); 556 557 558 /** 559 * @section Information 560 */ 561 562 /** 563 * @brief Returns string which contains a version number 564 * @return String which contains a version of the library 565 */ 566 extern OPNMIDI_DECLSPEC const char *opn2_linkedLibraryVersion(); 567 568 /** 569 * @brief Returns structure which contains a version number of library 570 * @return Library version context structure which contains version number of the library 571 */ 572 extern OPNMIDI_DECLSPEC const OPN2_Version *opn2_linkedVersion(); 573 574 /** 575 * @brief Returns string which contains last error message of initialization 576 * 577 * Don't use this function to get info on any function except of `opn2_init`! 578 * Use `opn2_errorInfo()` to get error information while workflow 579 * 580 * @return String with error message related to library initialization 581 */ 582 extern OPNMIDI_DECLSPEC const char *opn2_errorString(); 583 584 /** 585 * @brief Returns string which contains last error message on specific device 586 * @param device Instance of the library 587 * @return String with error message related to last function call returned non-zero value. 588 */ 589 extern OPNMIDI_DECLSPEC const char *opn2_errorInfo(struct OPN2_MIDIPlayer *device); 590 591 592 /* ======== Initialization ======== */ 593 594 /** 595 * @brief Initialize OPNMIDI Player device 596 * 597 * Tip 1: You can initialize multiple instances and run them in parallel 598 * Tip 2: Library is NOT thread-safe, therefore don't use same instance in different threads or use mutexes 599 * Tip 3: Changing of sample rate on the fly is not supported. Re-create the instance again. 600 * Top 4: To generate output in OPN2 or OPNA chip native sample rate, please initialize it with sample rate 601 * value as `OPN_OPN2_SAMPLE_RATE` or `OPN_OPNA_SAMPLE_RATE` in dependence on the chip 602 * 603 * @param sample_rate Output sample rate 604 * @return Instance of the library. If NULL was returned, check the `adl_errorString` message for more info. 605 */ 606 extern OPNMIDI_DECLSPEC struct OPN2_MIDIPlayer *opn2_init(long sample_rate); 607 608 /** 609 * @brief Close and delete OPNMIDI device 610 * @param device Instance of the library 611 */ 612 extern OPNMIDI_DECLSPEC void opn2_close(struct OPN2_MIDIPlayer *device); 613 614 615 /* ======== MIDI Sequencer ======== */ 616 617 /** 618 * @brief Load MIDI (or any other supported format) file from File System 619 * 620 * Available when library is built with built-in MIDI Sequencer support. 621 * 622 * @param device Instance of the library 623 * @param filePath Absolute or relative path to the music file. UTF8 encoding is required, even on Windows. 624 * @return 0 on success, <0 when any error has occurred 625 */ 626 extern OPNMIDI_DECLSPEC int opn2_openFile(struct OPN2_MIDIPlayer *device, const char *filePath); 627 628 /** 629 * @brief Load MIDI (or any other supported format) file from memory data 630 * 631 * Available when library is built with built-in MIDI Sequencer support. 632 * 633 * @param device Instance of the library 634 * @param mem Pointer to memory block where is raw data of music file is stored 635 * @param size Size of given memory block 636 * @return 0 on success, <0 when any error has occurred 637 */ 638 extern OPNMIDI_DECLSPEC int opn2_openData(struct OPN2_MIDIPlayer *device, const void *mem, unsigned long size); 639 640 /** 641 * @brief Resets MIDI player (per-channel setup) into initial state 642 * @param device Instance of the library 643 */ 644 extern OPNMIDI_DECLSPEC void opn2_reset(struct OPN2_MIDIPlayer *device); 645 646 /** 647 * @brief Get total time length of current song 648 * 649 * Available when library is built with built-in MIDI Sequencer support. 650 * 651 * @param device Instance of the library 652 * @return Total song length in seconds 653 */ 654 extern OPNMIDI_DECLSPEC double opn2_totalTimeLength(struct OPN2_MIDIPlayer *device); 655 656 /** 657 * @brief Get loop start time if presented. 658 * 659 * Available when library is built with built-in MIDI Sequencer support. 660 * 661 * @param device Instance of the library 662 * @return Time position in seconds of loop start point, or -1 when file has no loop points 663 */ 664 extern OPNMIDI_DECLSPEC double opn2_loopStartTime(struct OPN2_MIDIPlayer *device); 665 666 /** 667 * @brief Get loop endtime if presented. 668 * 669 * Available when library is built with built-in MIDI Sequencer support. 670 * 671 * @param device Instance of the library 672 * @return Time position in seconds of loop end point, or -1 when file has no loop points 673 */ 674 extern OPNMIDI_DECLSPEC double opn2_loopEndTime(struct OPN2_MIDIPlayer *device); 675 676 /** 677 * @brief Get current time position in seconds 678 * 679 * Available when library is built with built-in MIDI Sequencer support. 680 * 681 * @param device Instance of the library 682 * @return Current time position in seconds 683 */ 684 extern OPNMIDI_DECLSPEC double opn2_positionTell(struct OPN2_MIDIPlayer *device); 685 686 /** 687 * @brief Jump to absolute time position in seconds 688 * 689 * Available when library is built with built-in MIDI Sequencer support. 690 * 691 * @param device Instance of the library 692 * @param seconds Destination time position in seconds to seek 693 */ 694 extern OPNMIDI_DECLSPEC void opn2_positionSeek(struct OPN2_MIDIPlayer *device, double seconds); 695 696 /** 697 * @brief Reset MIDI track position to begin 698 * 699 * Available when library is built with built-in MIDI Sequencer support. 700 * 701 * @param device Instance of the library 702 */ 703 extern OPNMIDI_DECLSPEC void opn2_positionRewind(struct OPN2_MIDIPlayer *device); 704 705 /** 706 * @brief Set tempo multiplier 707 * 708 * Available when library is built with built-in MIDI Sequencer support. 709 * 710 * @param device Instance of the library 711 * @param tempo Tempo multiplier value: 1.0 - original tempo, >1 - play faster, <1 - play slower 712 */ 713 extern OPNMIDI_DECLSPEC void opn2_setTempo(struct OPN2_MIDIPlayer *device, double tempo); 714 715 /** 716 * @brief Returns 1 if music position has reached end 717 * @param device Instance of the library 718 * @return 1 when end of sing has been reached, otherwise, 0 will be returned. <0 is returned on any error 719 */ 720 extern OPNMIDI_DECLSPEC int opn2_atEnd(struct OPN2_MIDIPlayer *device); 721 722 /** 723 * @brief Returns the number of tracks of the current sequence 724 * @param device Instance of the library 725 * @return Count of tracks in the current sequence 726 */ 727 extern OPNMIDI_DECLSPEC size_t opn2_trackCount(struct OPN2_MIDIPlayer *device); 728 729 730 731 /* ======== Meta-Tags ======== */ 732 733 /** 734 * @brief Returns string which contains a music title 735 * @param device Instance of the library 736 * @return A string that contains music title 737 */ 738 extern OPNMIDI_DECLSPEC const char *opn2_metaMusicTitle(struct OPN2_MIDIPlayer *device); 739 740 /** 741 * @brief Returns string which contains a copyright string* 742 * @param device Instance of the library 743 * @return A string that contains copyright notice, otherwise NULL 744 */ 745 extern OPNMIDI_DECLSPEC const char *opn2_metaMusicCopyright(struct OPN2_MIDIPlayer *device); 746 747 /** 748 * @brief Returns count of available track titles 749 * 750 * NOTE: There are CAN'T be associated with channel in any of event or note hooks 751 * 752 * @param device Instance of the library 753 * @return Count of available MIDI tracks, otherwise NULL 754 */ 755 extern OPNMIDI_DECLSPEC size_t opn2_metaTrackTitleCount(struct OPN2_MIDIPlayer *device); 756 757 /** 758 * @brief Get track title by index 759 * @param device Instance of the library 760 * @param index Index of the track to retreive the title 761 * @return A string that contains track title, otherwise NULL. 762 */ 763 extern OPNMIDI_DECLSPEC const char *opn2_metaTrackTitle(struct OPN2_MIDIPlayer *device, size_t index); 764 765 /** 766 * @brief MIDI Marker structure 767 */ 768 struct Opn2_MarkerEntry 769 { 770 /*! MIDI Marker title */ 771 const char *label; 772 /*! Absolute time position of the marker in seconds */ 773 double pos_time; 774 /*! Absolute time position of the marker in MIDI ticks */ 775 unsigned long pos_ticks; 776 }; 777 778 /** 779 * @brief Returns count of available markers 780 * @param device Instance of the library 781 * @return Count of available MIDI markers 782 */ 783 extern OPNMIDI_DECLSPEC size_t opn2_metaMarkerCount(struct OPN2_MIDIPlayer *device); 784 785 /** 786 * @brief Returns the marker entry 787 * @param device Instance of the library 788 * @param index Index of the marker to retreive it. 789 * @return MIDI Marker description structure. 790 */ 791 extern OPNMIDI_DECLSPEC struct Opn2_MarkerEntry opn2_metaMarker(struct OPN2_MIDIPlayer *device, size_t index); 792 793 794 795 796 /* ======== Audio output Generation ======== */ 797 798 /** 799 * @brief Generate PCM signed 16-bit stereo audio output and iterate MIDI timers 800 * 801 * Use this function when you are playing MIDI file loaded by `adl_openFile` or by `adl_openData` 802 * with using of built-in MIDI sequencer. 803 * 804 * Don't use count of frames, use instead count of samples. One frame is two samples. 805 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 806 * 807 * Available when library is built with built-in MIDI Sequencer support. 808 * 809 * @param device Instance of the library 810 * @param sampleCount Count of samples (not frames!) 811 * @param out Pointer to output with 16-bit stereo PCM output 812 * @return Count of given samples, otherwise, 0 or when catching an error while playing 813 */ 814 extern OPNMIDI_DECLSPEC int opn2_play(struct OPN2_MIDIPlayer *device, int sampleCount, short *out); 815 816 /** 817 * @brief Generate PCM stereo audio output in sample format declared by given context and iterate MIDI timers 818 * 819 * Use this function when you are playing MIDI file loaded by `adl_openFile` or by `adl_openData` 820 * with using of built-in MIDI sequencer. 821 * 822 * Don't use count of frames, use instead count of samples. One frame is two samples. 823 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 824 * 825 * Available when library is built with built-in MIDI Sequencer support. 826 * 827 * @param device Instance of the library 828 * @param sampleCount Count of samples (not frames!) 829 * @param left Left channel buffer output (Must be casted into bytes array) 830 * @param right Right channel buffer output (Must be casted into bytes array) 831 * @param format Destination PCM format format context 832 * @return Count of given samples, otherwise, 0 or when catching an error while playing 833 */ 834 extern OPNMIDI_DECLSPEC int opn2_playFormat(struct OPN2_MIDIPlayer *device, int sampleCount, OPN2_UInt8 *left, OPN2_UInt8 *right, const struct OPNMIDI_AudioFormat *format); 835 836 /** 837 * @brief Generate PCM signed 16-bit stereo audio output without iteration of MIDI timers 838 * 839 * Use this function when you are using library as Real-Time MIDI synthesizer or with 840 * an external MIDI sequencer. You must to request the amount of samples which is equal 841 * to the delta between of MIDI event rows. One MIDI row is a group of MIDI events 842 * are having zero delta/delay between each other. When you are receiving events in 843 * real time, request the minimal possible delay value. 844 * 845 * Don't use count of frames, use instead count of samples. One frame is two samples. 846 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 847 * 848 * @param device Instance of the library 849 * @param sampleCount 850 * @param out Pointer to output with 16-bit stereo PCM output 851 * @return Count of given samples, otherwise, 0 or when catching an error while playing 852 */ 853 extern OPNMIDI_DECLSPEC int opn2_generate(struct OPN2_MIDIPlayer *device, int sampleCount, short *out); 854 855 /** 856 * @brief Generate PCM stereo audio output in sample format declared by given context without iteration of MIDI timers 857 * 858 * Use this function when you are using library as Real-Time MIDI synthesizer or with 859 * an external MIDI sequencer. You must to request the amount of samples which is equal 860 * to the delta between of MIDI event rows. One MIDI row is a group of MIDI events 861 * are having zero delta/delay between each other. When you are receiving events in 862 * real time, request the minimal possible delay value. 863 * 864 * Don't use count of frames, use instead count of samples. One frame is two samples. 865 * So, for example, if you want to take 10 frames, you must to request amount of 20 samples! 866 * 867 * @param device Instance of the library 868 * @param sampleCount 869 * @param left Left channel buffer output (Must be casted into bytes array) 870 * @param right Right channel buffer output (Must be casted into bytes array) 871 * @param format Destination PCM format format context 872 * @return Count of given samples, otherwise, 0 or when catching an error while playing 873 */ 874 extern OPNMIDI_DECLSPEC int opn2_generateFormat(struct OPN2_MIDIPlayer *device, int sampleCount, OPN2_UInt8 *left, OPN2_UInt8 *right, const struct OPNMIDI_AudioFormat *format); 875 876 /** 877 * @brief Periodic tick handler. 878 * @param device 879 * @param seconds seconds since last call 880 * @param granularity don't expect intervals smaller than this, in seconds 881 * @return desired number of seconds until next call 882 * 883 * Use it for Hardware OPL3 mode or when you want to process events differently from opn2_play() function. 884 * DON'T USE IT TOGETHER WITH opn2_play()!!! 885 */ 886 extern OPNMIDI_DECLSPEC double opn2_tickEvents(struct OPN2_MIDIPlayer *device, double seconds, double granuality); 887 888 /** 889 * @brief Track options 890 */ 891 enum OPNMIDI_TrackOptions 892 { 893 /*! Enabled track */ 894 OPNMIDI_TrackOption_On = 1, 895 /*! Disabled track */ 896 OPNMIDI_TrackOption_Off = 2, 897 /*! Solo track */ 898 OPNMIDI_TrackOption_Solo = 3 899 }; 900 901 /** 902 * @brief Sets options on a track of the current sequence 903 * @param device Instance of the library 904 * @param trackNumber Identifier of the designated track. 905 * @return 0 on success, <0 when any error has occurred 906 */ 907 extern OPNMIDI_DECLSPEC int opn2_setTrackOptions(struct OPN2_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions); 908 909 910 911 912 /* ======== Real-Time MIDI ======== */ 913 914 /** 915 * @brief Force Off all notes on all channels 916 * @param device Instance of the library 917 */ 918 extern OPNMIDI_DECLSPEC void opn2_panic(struct OPN2_MIDIPlayer *device); 919 920 /** 921 * @brief Reset states of all controllers on all MIDI channels 922 * @param device Instance of the library 923 */ 924 extern OPNMIDI_DECLSPEC void opn2_rt_resetState(struct OPN2_MIDIPlayer *device); 925 926 /** 927 * @brief Turn specific MIDI note ON 928 * @param device Instance of the library 929 * @param channel Target MIDI channel [Between 0 and 16] 930 * @param note Note number to on [Between 0 and 127] 931 * @param velocity Velocity level [Between 0 and 127] 932 * @return 1 when note was successfully started, 0 when note was rejected by any reason. 933 */ 934 extern OPNMIDI_DECLSPEC int opn2_rt_noteOn(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 note, OPN2_UInt8 velocity); 935 936 /** 937 * @brief Turn specific MIDI note OFF 938 * @param device Instance of the library 939 * @param channel Target MIDI channel [Between 0 and 16] 940 * @param note Note number to off [Between 0 and 127] 941 */ 942 extern OPNMIDI_DECLSPEC void opn2_rt_noteOff(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 note); 943 944 /** 945 * @brief Set note after-touch 946 * @param device Instance of the library 947 * @param channel Target MIDI channel [Between 0 and 16] 948 * @param note Note number to affect by aftertouch event [Between 0 and 127] 949 * @param atVal After-Touch value [Between 0 and 127] 950 */ 951 extern OPNMIDI_DECLSPEC void opn2_rt_noteAfterTouch(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 note, OPN2_UInt8 atVal); 952 953 /** 954 * @brief Set channel after-touch 955 * @param device Instance of the library 956 * @param channel Target MIDI channel [Between 0 and 16] 957 * @param atVal After-Touch level [Between 0 and 127] 958 */ 959 extern OPNMIDI_DECLSPEC void opn2_rt_channelAfterTouch(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 atVal); 960 961 /** 962 * @brief Apply controller change 963 * @param device Instance of the library 964 * @param channel Target MIDI channel [Between 0 and 16] 965 * @param type Type of the controller [Between 0 and 255] 966 * @param value Value of the controller event [Between 0 and 127] 967 */ 968 extern OPNMIDI_DECLSPEC void opn2_rt_controllerChange(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 type, OPN2_UInt8 value); 969 970 /** 971 * @brief Apply patch change 972 * @param device Instance of the library 973 * @param channel Target MIDI channel [Between 0 and 16] 974 * @param patch Patch number [Between 0 and 127] 975 */ 976 extern OPNMIDI_DECLSPEC void opn2_rt_patchChange(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 patch); 977 978 /** 979 * @brief Apply pitch bend change 980 * @param device Instance of the library 981 * @param channel Target MIDI channel [Between 0 and 16] 982 * @param pitch 24-bit pitch bend value 983 */ 984 extern OPNMIDI_DECLSPEC void opn2_rt_pitchBend(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt16 pitch); 985 986 /** 987 * @brief Apply pitch bend change 988 * @param device Instance of the library 989 * @param channel Target MIDI channel [Between 0 and 16] 990 * @param msb MSB part of 24-bit pitch bend value 991 * @param lsb LSB part of 24-bit pitch bend value 992 */ 993 extern OPNMIDI_DECLSPEC void opn2_rt_pitchBendML(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 msb, OPN2_UInt8 lsb); 994 995 /** 996 * @brief Change LSB of the bank number (Alias to CC-32 event) 997 * @param device Instance of the library 998 * @param channel Target MIDI channel [Between 0 and 16] 999 * @param lsb LSB value of the MIDI bank number 1000 */ 1001 extern OPNMIDI_DECLSPEC void opn2_rt_bankChangeLSB(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 lsb); 1002 1003 /** 1004 * @brief Change MSB of the bank (Alias to CC-0 event) 1005 * @param device Instance of the library 1006 * @param channel Target MIDI channel [Between 0 and 16] 1007 * @param msb MSB value of the MIDI bank number 1008 */ 1009 extern OPNMIDI_DECLSPEC void opn2_rt_bankChangeMSB(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_UInt8 msb); 1010 1011 /** 1012 * @brief Change bank by absolute signed value 1013 * @param device Instance of the library 1014 * @param channel Target MIDI channel [Between 0 and 16] 1015 * @param bank Bank number as concoctated signed 16-bit value of MSB and LSB parts. 1016 */ 1017 extern OPNMIDI_DECLSPEC void opn2_rt_bankChange(struct OPN2_MIDIPlayer *device, OPN2_UInt8 channel, OPN2_SInt16 bank); 1018 1019 /** 1020 * @brief Perform a system exclusive message 1021 * @param device Instance of the library 1022 * @param msg Raw SysEx message buffer (must begin with 0xF0 and end with 0xF7) 1023 * @param size Size of given SysEx message buffer 1024 * @return 1 when SysEx message was successfully processed, 0 when SysEx message was rejected by any reason 1025 */ 1026 extern OPNMIDI_DECLSPEC int opn2_rt_systemExclusive(struct OPN2_MIDIPlayer *device, const OPN2_UInt8 *msg, size_t size); 1027 1028 /* ======== Hooks and debugging ======== */ 1029 1030 /** 1031 * @brief Raw event callback 1032 * @param userdata Pointer to user data (usually, context of someting) 1033 * @param type MIDI event type 1034 * @param subtype MIDI event sub-type (special events only) 1035 * @param channel MIDI channel 1036 * @param data Raw event data 1037 * @param len Length of event data 1038 */ 1039 typedef void (*OPN2_RawEventHook)(void *userdata, OPN2_UInt8 type, OPN2_UInt8 subtype, OPN2_UInt8 channel, const OPN2_UInt8 *data, size_t len); 1040 /** 1041 * @brief Note on/off callback 1042 * @param userdata Pointer to user data (usually, context of someting) 1043 * @param adlchn Chip channel where note was played 1044 * @param note Note number [between 0 and 127] 1045 * @param pressure Velocity level, or -1 when it's note off event 1046 * @param bend Pitch bend offset value 1047 */ 1048 typedef void (*OPN2_NoteHook)(void *userdata, int adlchn, int note, int ins, int pressure, double bend); 1049 1050 /** 1051 * @brief Debug messages callback 1052 * @param userdata Pointer to user data (usually, context of someting) 1053 * @param fmt Format strign output (in context of `printf()` standard function) 1054 */ 1055 typedef void (*OPN2_DebugMessageHook)(void *userdata, const char *fmt, ...); 1056 1057 /** 1058 * @brief Set raw MIDI event hook 1059 * @param device Instance of the library 1060 * @param rawEventHook Pointer to the callback function which will be called on every MIDI event 1061 * @param userData Pointer to user data which will be passed through the callback. 1062 */ 1063 extern OPNMIDI_DECLSPEC void opn2_setRawEventHook(struct OPN2_MIDIPlayer *device, OPN2_RawEventHook rawEventHook, void *userData); 1064 1065 /** 1066 * @brief Set note hook 1067 * @param device Instance of the library 1068 * @param noteHook Pointer to the callback function which will be called on every noteOn MIDI event 1069 * @param userData Pointer to user data which will be passed through the callback. 1070 */ 1071 extern OPNMIDI_DECLSPEC void opn2_setNoteHook(struct OPN2_MIDIPlayer *device, OPN2_NoteHook noteHook, void *userData); 1072 1073 /** 1074 * @brief Set debug message hook 1075 * @param device Instance of the library 1076 * @param debugMessageHook Pointer to the callback function which will be called on every debug message 1077 * @param userData Pointer to user data which will be passed through the callback. 1078 */ 1079 extern OPNMIDI_DECLSPEC void opn2_setDebugMessageHook(struct OPN2_MIDIPlayer *device, OPN2_DebugMessageHook debugMessageHook, void *userData); 1080 1081 1082 /** 1083 * @brief Get a textual description of the channel state. For display only. 1084 * @param device Instance of the library 1085 * @param text Destination char buffer for channel usage state. Every entry is assigned to the chip channel. 1086 * @param attr Destination char buffer for additional attributes like MIDI channel number that uses this chip channel. 1087 * @param size Size of given buffers (both text and attr are must have same size!) 1088 * @return 0 on success, <0 when any error has occurred 1089 * 1090 * Every character in the `text` buffer means the type of usage: 1091 * ``` 1092 * `-` - channel is unused (free) 1093 * `+` - channel is used by regular voice 1094 * `@` - channel is used to play automatic arpeggio on chip channels overflow 1095 * ``` 1096 * 1097 * The `attr` field receives the MIDI channel from which the chip channel is used. 1098 * To get the valid MIDI channel you will need to apply the & 0x0F mask to every value. 1099 */ 1100 extern OPNMIDI_DECLSPEC int opn2_describeChannels(struct OPN2_MIDIPlayer *device, char *text, char *attr, size_t size); 1101 1102 #ifdef __cplusplus 1103 } 1104 #endif 1105 1106 #endif /* OPNMIDI_H */ 1107