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.git
mkdir build/ ; cd build
cmake ..
make
sudo make install
You 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 dev
oplhw_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.