Awesome
libOPNMIDI
libOPNMIDI is a free Software MIDI synthesizer library with OPN2 (YM2612) and OPNA (YM2608) emulation.
OPNMIDI Library: Copyright (c) 2017-2024 Vitaly Novichkov admin@wohlnet.ru
Library is based on core of the libADLMIDI, a MIDI playing library with OPL3 emulation.
Tested on platforms
- Linux GCC 4.8, 4.9, 5.4 / CLang
- Mac OS X CLang (Xcode 7.x)
- Windows MinGW 4.9.x, 5.2
- Android NDK 12b/13
- OpenBSD
- Haiku
- Emscripten
Key features
- OPN2 emulation
- Rudimentary OPNA emulation
- Customizable bank of FM patches (You have to use the bank editor to create own soundbank)
- Stereo sound
- Number of simulated OPN2/OPNA chips can be specified as 1-100 (maximum 600 channels!)
- Pan (binary panning, i.e. left/right side on/off)
- Pitch-bender with adjustable range
- Vibrato that responds to RPN/NRPN parameters
- Sustain (a.k.a. Pedal hold) and Sostenuto enable/disable
- MIDI and RMI file support
- Real-Time MIDI API support
- MIDI and RMI file support
- loopStart / loopEnd tag support (Final Fantasy VII)
- 111'th controller based loop start (RPG-Maker)
- Use automatic arpeggio with chords to relieve channel pressure
- Support for multiple concurrent MIDI synthesizers (per-track device/port select FF 09 message), can be used to overcome 16 channel limit
- Partial support for GS and XG standards (having more instruments than in one 128:128 GM set and ability to use multiple channels for percussion purposes, and support for some GS/XG exclusive controllers)
- CC74 "Brightness" affects a modulator scale (to simulate frequency cut-off on WT synths)
- Portamento support (CC5, CC37, and CC65)
- SysEx support that supports some generic, GS, and XG features
- Full-panning stereo option (works for emulators only)
How to build
To build libOPNMIDI you need to use CMake:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
sudo make install
License
The library is licensed under in it's parts LGPL 2.1+, GPL v2+, GPL v3+, and MIT.
- Nuked OPN2 emulator is licensed under LGPL v2.1+.
- GENS 2.10 emulator is licensed under LGPL v2.1+.
- MAME YM2612 emulator is licensed under GPL v2+.
- Genesis Plus GX emulator is licensed under GPL v2+.
- Neko Project II Kai (fmgen, developed by "cisc" cisc@retropc.net) OPNA emulator is licensed under MIT-compatible license.
- PMDWin emulator OPNA emulator is licensed under BSD 2-Clause.
- MAME YM2608 emulator is licensed under GPL v2+.
- Chip interfaces are licensed under LGPL v2.1+.
- File Reader class and MIDI Sequencer is licensed under MIT.
- Other parts of library are licensed under GPLv3+.
Available CMake options
-
CMAKE_INSTALL_PREFIX - destination folder where libOPNMIDI will be installed. On Linux it is /usr/local/ by default.
-
CMAKE_BUILD_TYPE - Build types: Debug or Release. Also MinSizeRel or RelWithDebInfo.
-
WITH_MIDIPLAY - (ON/OFF, default OFF) Build demo MIDI player (Requires SDL2 and also pthread on Windows with MinGW)
-
WITH_VLC_PLUGIN - (ON/OFF, default OFF) Compile VLC plugin. For now, works on Linux and VLC. Support for other platforms comming soon!
-
WITH_WINMMDRV - (ON/OFF, default OFF) (Windows platform only) Compile the WinMM MIDI driver to use libOPNMIDI as a system MIDI device.
- WITH_WINMMDRV_PTHREADS - (ON/OFF, default ON) Link libwinpthreads statically (when using pthread-based builds).
- WITH_WINMMDRV_MINGWEX - (ON/OFF, default OFF) Link libmingwex statically (when using vanilla MinGW builds). Useful for targetting to pre-XP Windows versions.
-
WITH_MIDI2VGM - (ON/OFF, default OFF) Build MIDI to VGM converter tool.
-
WITH_DAC_UTIL - (ON/OFF, default OFF) Build YM2612 CH6 DAC testing utility.
-
WITH_MIDI_SEQUENCER - (ON/OFF, default ON) Enable built-in MIDI sequencer to play loaded MIDI files. When you will disable MIDI sequencer, Real-Time functions only will work. Use this option when you are making MIDI plugin or real-time MIDI driver.
-
USE_MAME_EMULATOR - (ON/OFF, default ON) Enable support for MAME YM2612 emulator. Well-accurate and fast on slow devices.
-
USE_NUKED_EMULATOR - (ON/OFF, default ON) Enable support for Nuked OPN2 emulator. Very accurate, however, requires a very powerful CPU. Is not recommended for mobile devices!.
-
USE_GENS_EMULATOR - (ON/OFF, default ON) Enable support for GENS 2.10 emulator. Very outdated and inaccurate, but fastest.
-
USE_GX_EMULATOR - (ON/OFF, default OFF) Enable support for Genesis Plus GX emulator. (experimental!)
-
USE_NP2_EMULATOR - (ON/OFF, default ON) Enable support for Neko Project 2 YM2608 emulator. Semi-accurate, but fast on slow devices.
-
USE_MAME_2608_EMULATOR - (ON/OFF, default ON) Enable support for MAME YM2608 emulator. Well-accurate and fast on slow devices.
-
WITH_HQ_RESAMPLER - (ON/OFF, default OFF) Build with support for high quality resampling (requires zita-resampler to be installed.
-
WITH_MUS_SUPPORT - (ON/OFF, default ON) Enable support for DMX MUS format in built-in MIDI sequencer.
-
WITH_XMI_SUPPORT - (ON/OFF, default ON) Enable support for AIL XMI format in built-in MIDI sequencer.
-
WITH_UNIT_TESTS - (ON/OFF, default OFF) Also compile unit-tests of internal features.
-
libOPNMIDI_STATIC - (ON/OFF, default ON) Build static library
-
libOPNMIDI_SHARED - (ON/OFF, default OFF) Build shared library
You also can build library manually:
You need to make in the any IDE a library project and put into it next files (or include those files into subfolder of your exist project instead if you want to use it statically):
Useful macros
BWMIDI_DISABLE_XMI_SUPPORT
- Disables XMI to MIDI converterBWMIDI_DISABLE_MUS_SUPPORT
- Disables MUS to MIDI converterOPNMIDI_DISABLE_MIDI_SEQUENCER
- Completely disables built-in MIDI sequencer.OPNMIDI_USE_LEGACY_EMULATOR
- Enables Gens 2.10 YM2612 emulator to be used. Nuked OPN2 is used by default if macro is not defined.
Public header (include)
- opnmidi.h - Library API, use it to control library
Internal code (src)
-
opnbank.h - bank structures definition
-
opnmidi_private.hpp - header of internal private APIs
-
opnmidi.cpp - code of library
-
opnmidi_load.cpp - Source of file loading and parsing processing
-
opnmidi_midiplay.cpp - MIDI event sequencer
-
opnmidi_opn2.cpp - OPN2 chips manager
-
opnmidi_private.cpp - some internal functions sources
-
opnmidi_bankmap.h - MIDI bank hash table
-
opnmidi_bankmap.tcc - MIDI bank hash table (Implementation)
-
opnmidi_cvt.hpp - Instrument conversion template
-
opnmidi_ptr.hpp - Custom implementations of smart pointers for C++98
-
file_reader.hpp - Generic file and memory reader
-
chips/opn_chip_base.h
- Header of base class over all emulation cores -
chips/opn_chip_base.tcc
- Code of base class over all emulation cores -
chips/gens_opn2.h - Header of emulator frontent over Gens 2.10 emulator
-
chips/gens_opn2.cpp - Code of emulator frontent over Gens 2.10 emulator
-
chips/gens/Ym2612_ChipEmu.h - Gens 2.10 OPN2 Emulation header
-
chips/gens/Ym2612_ChipEmu.cpp - Code of Gens 2.10 OPN2 emulator by Stéphane Dallongeville, improved by Shay Green
-
chips/mame_opn2.h - Header of emulator frontent over MAME YM2612 emulator
-
chips/mame_opn2.cpp - Code of emulator frontent over MAME YM2612 emulator
-
chips/mame/mame_ym2612fm.h - MAME YM2612 Emulation header
-
chips/mame/mame_ym2612fm.cpp - Code of MAME YM2612 emulator by Jarek Burczyński and Tatsuyuki Satoh, improved by Eke-Eke
-
chips/nuked_opn2.h - Header of emulator frontent over Nuked OPN2 emulator
-
chips/nuked_opn2.cpp - Code of emulator frontent over Nuked OPN2 emulator
-
chips/nuked/ym3438.h - Nuked OPN2 Emulation header
-
chips/nuked/ym3438.cpp - Code of Nuked OPN2 emulator by Alexey Khokholov
-
chips/np2/* - Code of Neko Project 2 YM2608 emulator by cisc.
-
chips/mamefm/* - Code of MAME YM2608 emulator by Jarek Burczynski and Tatsuyuki Satoh.
-
wopn/* - WOPN bank format library
MIDI Sequencer
To remove MIDI Sequencer, define OPNMIDI_DISABLE_MIDI_SEQUENCER
macro and remove all those files
- adlmidi_sequencer.cpp - MIDI Sequencer related source
- cvt_mus2mid.hpp - MUS2MID converter source (define
BWMIDI_DISABLE_MUS_SUPPORT
macro to remove MUS support) - cvt_xmi2mid.hpp - XMI2MID converter source (define
BWMIDI_DISABLE_XMI_SUPPORT
macro to remove XMI support) - fraction.hpp - Fraction number handling (Used by Sequencer only)
- midi_sequencer.h - MIDI Sequencer C bindings
- midi_sequencer.hpp - MIDI Sequencer C++ declaration
- midi_sequencer_impl.hpp - MIDI Sequencer C++ implementation (must be once included into one of CPP together with interfaces initializations)
Important: Please use GENS emulator only on mobile or any non-power devices because it requires very small CPU power. Nuked OPN2 emulator is very accurate (compared to real OPN2 chip), however, it requires a VERY POWERFUL device even for a single chip emulation and is a high probability that your device will lag and playback will be dirty and choppy. Use of MAME OPN2 is recommended in such cases.
Working demos
- Moondust MusPlay for Win32 and Win64 (also available for other platforms as part of Moondust Project) - a little music player which uses SDL Mixer X library (fork of the SDL Mixer 2.0) which has embedded libOPNMIDI to play MIDI files independently from operating system's settings and drivers. <br>(source code of player can be find here and source code of SDL Mixer X here)
- OPNMIDI Player for Android - a little MIDI-player for Android which uses libOPNMIDI to play MIDI files and provides flexible GUI with ability to change bank, flags, number of emulated chips, etc.
Changelog
dev
- Fixed the work on big endian processors
- Fixed ARM64 build on some platforms
- Improved support of the EA-MUS files (Thanks to dashodanger)
- Fixed crash on attempt to change the volume of a blank note
- Removed PMDwin and Genesis Plus GX emulatirs because of their very low quality
- Added new YMFM emulators for the OPN2 and for the OPNA (will be available for C++14 compilers only. If your compiler doesn't supports C++14, you can disable these emulators by defining the -DOPNMIDI_DISABLE_YMFM_EMULATOR macro if you build the code of libOPNMIDI at your own build tree)
- OPNMIDI player tool now has the ganining factor to change the output volume
- OPNMIDI player tool now is able to output WAV files of different sample formats
1.5.1 2022-10-31
- Added an ability to disable the automatical arpeggio
- Updated the GENS chip emulator from the 2.10 into GS/II (thanks to @freq-mod for the help)
- Added an ability to set number of loops
- Added an ability to disable/enable playing of selected MIDI channels
- Fixed memory damages and crashes while playing XMI files
- Added the chip channels allocation mode option
- Fixed the playback of multi-song XMI files
- Added an ability to switch the XMI song on the fly
1.5.0.1 2020-10-11
- Fixed an incorrect timer processing when using a real-time interface
1.5.0 2020-09-28
- Drum note length expanding is now supported in real-time mode (Thanks to Jean Pierre Cimalando for a work!)
- Added support for OPNA chip with Neko Project II Kai YM2602 emulator usage (Thanks to Jean Pierre Cimalando for a work!)
- Added VGM file dumper which allows to output OPN2 commands into VGM file. (A new MIDI to VGM tool is now created with basing on libOPNMIDI)
- Fixed an incorrect work of CC-121 (See https://github.com/Wohlstand/libADLMIDI/issues/227 for details)
- Internality has been refactored and improved
1.4.0 2018-10-01
- Implemented a full support for Portamento! (Thanks to Jean Pierre Cimalando for a work!)
- Added support for SysEx event handling! (Thanks to Jean Pierre Cimalando for a work!)
- Added support for GS way of custom drum channels (through SysEx events)
- Ignore some NRPN events and lsb bank number when using GS standard (after catching of GS Reset SysEx call)
- Added support for CC66-Sostenuto controller (Pedal hold of currently-pressed notes only while CC64 holds also all next notes)
- Added support for CC67-SoftPedal controller (SoftPedal lowers the volume of notes played)
- Resolved a trouble which sometimes makes a junk noise sound and unnecessary overuse of chip channels
- Volume models support taken from libADLMIDI has been adapted to OPN2's chip speficis
- Fixed inability to play high notes due physical tone frequency out of range on the OPN2 chip
- Added support for full-panning stereo option
1.3.0 2018-06-19
- Optimizing the MIDI banks management system for MultiBanks (Thanks to Jean Pierre Cimalando for a work!)
- Fixed incorrect initial MIDI tempo when MIDI file doesn't includes the tempo event
- Fixed an incorrect processing of auto-flags
- MAME YM2612 now results a more accurate sound as internal using of native sample rate makes more correct sound generation
- Channel and Note Aftertouch features are now supported correctly! Aftertouch is the tremolo / vibrato, NOT A VOLUME!
- Added optional HQ resampler for Nuked OPL3 emulators which does usage of Zita-Resampler library (Thanks to Jean Pierre Cimalando for a work!)
1.2.0 2018-04-24
- Added ability to disable MUS and XMI converters
- Added ability to disable embedded MIDI sequencer to use library as RealTime synthesizer only or use any custom MIDI sequencer plugins.
- Fixed blank instruments fallback in multi-bank support. When using non-zero bank, if instrument is blank, then, instrument will be taken from a root (I.e. zero bank).
- Added support for real-time switching the emulator
- Added support for MAME YM2612 Emulator
- Added support for CC-120 - "All sound off" on the MIDI channel
- Changed logic of CC-74 Brightness to affect sound only between 0 and 64 like real XG synthesizers. Ability to turn on a full-ranged brightness (to use full 0...127 range) is kept.
- Added support for different output sample formats (PCM8, PCM8U, PCM16, PCM16U, PCM32, PCM32U, Float32, and Float64) (Thanks to Jean Pierre Cimalando for a work!)
- Reworked MIDI channels management to avoid any memory reallocations while music processing for a hard real time. (Thanks to Jean Pierre Cimalando for a work!)
1.1.0 2018-01-21
- First stable release
- Contains all features are made in libADLMIDI 1.3.1
1.0.0-beta 2017-05-06
- First experimental release