oplhw — A library for using real OPL2 synth chips via ALSA's hwdep interface

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.

Installing liboplhw should be pretty simple:
  1. Clone the git repository: git clone https://github.com/sulix/liboplhw.git
  2. Make a build directory: mkdir build/ ; cd build
  3. Configure it with CMake: cmake ..
  4. Compile it: make
  5. Install it: sudo make install

You can use liboplhw really easily. There are only three functions to worry about:

oplhw_OpenDevice(const char *dev_name)
Opens an OPL2 device. Returns an oplhw_device pointer, and accepts the ALSA hwdep name as input.
oplhw_Write(oplhw_device *dev, uint8_t reg, uint8_t val)
Writes the byte val to OPL2 register reg on device dev
oplhw_CloseDevice(oplhw_device *dev)
Closes the device once you've finished using it.

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.