In the early days of PC gaming, music and sound effects were largely produced using the Yamaha OPL2 snythesiser chip, which was present on most sound cards since being popularised by the AdLib and Sound Blaster sound cards.
The Linux kernel has support for using the OPL2 (and its successor, the OPL3) on soundcards
which still support them, and ALSA
exposes them both as a MIDI device and via a direct hwdep
interface.
liboplhw is a library which provides access to OPL2 chips via this
hwdep interface. It converts raw OPL2 register writes into the appropriate ALSA hwdep ioctl
calls. This allows it to easily be used as a drop in replacement for OPL2 emulators.
Note that, unlike many other projects which provide direct access to the OPL2 under Linux, oplhw
does not require access to the direct I/O ports, and so applications do not need to run as root (so long as
the user has permission to access the sound card, e.g. by being in the audio group).
liboplhw's source code is available on GitHub.
It can be built as a shared library, static library, or its files can be directly included into a project
which links against ALSA.
git clone https://github.com/sulix/liboplhw.gitmkdir build/ ; cd buildcmake ..makesudo make installYou can use liboplhw really easily. There are only three functions to worry about:
oplhw_OpenDevice(const char *dev_name)oplhw_Write(oplhw_device *dev, uint8_t reg, uint8_t val)val to OPL2 register reg on device devoplhw_CloseDevice(oplhw_device *dev)Just #include <oplhw.h>, and link against liboplhw with
pkg-config --cflags --libs oplhw
To find the device name to use on your system, you'll need the card and hwdep numbers for your device.
The card number is the index of the soundcard (you can often find it in aplay -l), and the hwdep
number is almost always 0. To make sure, just look in /proc/asound/hwdep and look for an entry titled
OPL3 FM or OPL2 FM. The card number and hwdep number will be printed beforehand.
The device name is then just hw:card,hwdep. For example, hw:0,0
Alternatively, leave the device name blank (you may need to explicitly put an empty string — "" —
for some programs to recognise this), and liboplhw will automatically use the first OPL2 or OPL3
device in your system.
liboplhw comes with an example program, oplhw_imfplay, which plays
IMF files using liboplhw. It also serves
as a simple reference for the API, so check out the source code,
and the ModdingWiki documentation for the IMF format.
If you want to play DOS games using liboplhw, here's a patch for the
DOSBox emulator. Once applied, configure DOSBox with:
./configure --enable-oplhw=yes
You can then compile DOSBox as normal. You'll then want to change your dosbox.conf file to include, in the [sblaster]
section:
oplmode=opl2 oplemu=oplhw opldev=[device]
Where device is the hwdep device name described earlier. You can also leave it as the empty string to use the device autodetection. Note that, if you're using ALSA's MIDI support as well, you may encounter a conflict if the OPL2's MIDI device is used. Both MIDI and direct OPL2 access can't be used at the same time.