ymfmidi is a MIDI player based on the OPL3 emulation core from ymfm.
- Supports both 4-operator and 2-operator instruments
- Supports some Roland GS, Yamaha XG, and GM Level 2 features (e.g. multiple instrument banks and percussion channels)
- Can emulate multiple chips at once to increase polyphony
- Can output to WAV files
- Can play files containing multiple songs (XMI, MIDI format 2)
- Supported sequence formats:
.hmi,.hmpHMI Sound Operating System.midStandard MIDI files.musDMX sound system / Doom engine.rmiMicrosoft RIFF MIDI.xmiMiles Sound System / Audio Interface Library
- Supported instrument patch formats:
.ad,.oplMiles Sound System / Audio Interface Library.op2DMX sound system / Doom engine.tmbApogee Sound System.woplWohlstand OPL3 editor
More sequence and instrument file formats will probably be supported in the future.
ymfmidi can be used as a standalone program (with SDL2), or incorporated into other software to provide easy OPL3-based MIDI playback.
For standalone usage instructions, run the player with no arguments. The player uses patches from DMXOPL by default, but an alternate patch set can be specified as a command-line argument.
To incorporate ymfmidi into your own programs, include everything in the src and ymfm directories (except for src/main.cpp and src/console.*), preferably in its own subdirectory somewhere. After that, somewhere in your code:
#include "player.h"- Create an instance of
OPLPlayer, optionally specifying a type of chip (the default isOPLPlayer::ChipOPL3) and number of chips to emulate (the default is 1) - Call the
loadSequenceandloadPatchesmethods to load music and instrument data from a path, an existingFILE*, or a buffer in memory - (Optional) Call the
setLoop,setSampleRate,setGain, andsetFiltermethods to set up playback parameters - Periodically call one of the
generatemethods to output audio in either signed 16-bit or floating-point format - (Optional) Call the
resetmethod to restart playback at the beginning
A proper static lib build method will be available sooner or later.
In addition to loading a MIDI file, it's also possible to send MIDI messages to an OPLPlayer instance in real time using some of its public methods.
To send a standard two- or three-byte MIDI message:
void midiEvent(uint8_t status, uint8_t data0, uint8_t data1 = 0);
Helper methods are also available for the most common messages:
void midiNoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
void midiNoteOff(uint8_t channel, uint8_t note);
void midiPitchControl(uint8_t channel, double pitch); // range is -1.0 to 1.0
void midiProgramChange(uint8_t channel, uint8_t patchNum);
void midiControlChange(uint8_t channel, uint8_t control, uint8_t value);
void midiSetBendRange(uint8_t channel, uint8_t semitones);
System Exclusive messages can also be sent directly to the player (primarily for enabling supported GS or XG features):
void midiSysEx(const uint8_t *data, uint32_t length);
It is not required to include the opening 0xF0 byte that normally precedes a sysex event; this is due mainly to the way that these events are stored in MIDI files. If data includes this opening byte, it should also be included in length, but will otherwise be ignored.
ymfmidi and the underlying ymfm library are both released under the 3-clause BSD license.