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
,.hmp
HMI Sound Operating System.mid
Standard MIDI files.mus
DMX sound system / Doom engine.rmi
Microsoft RIFF MIDI.xmi
Miles Sound System / Audio Interface Library
- Supported instrument patch formats:
.ad
,.opl
Miles Sound System / Audio Interface Library.op2
DMX sound system / Doom engine.tmb
Apogee Sound System.wopl
Wohlstand 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
loadSequence
andloadPatches
methods to load music and instrument data from a path, an existingFILE*
, or a buffer in memory - (Optional) Call the
setLoop
,setSampleRate
,setGain
, andsetFilter
methods to set up playback parameters - Periodically call one of the
generate
methods to output audio in either signed 16-bit or floating-point format - (Optional) Call the
reset
method 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.