Last modified: 2024-01-21 14:01
This page describes how to play MIDI (.MID) files on Linux/ALSA to certain sound card synths that do not have a MIDI interpreter. Comparable results can be obtained with less trouble using a softsynth.
In sections below, the tags OPL2/3 EMU8000 EMU10K1 indicate to which of the synths the information applies.
OPL2/3 The program sbiload from package alsa-tools. It is bundled under the seq subdirectory, has its own configure script and can be built separately.
EMU8000 EMU10K1 The program asfxload from package awesfx. (asfxload is for ALSA; sfxload is for OSS.)
OPL2/3 EMU8000 EMU10K1 The programs aplaymidi and alsamixer from package alsa-utils.
The following two kernel bugs can result in avoidable "sfxload: no memory left" errors.
The EMU8000 driver in the Linux kernel for a long time had a bug that reduced the amount of soundfont memory by 512 KiB. This bug prevented loading the nominally 4 MiB E-mu soundfont provided by Creative, 4GMGSMT.SF2 (4174814 B), into the on-board RAM of an AWE64 Gold. The problem was corrected in kernel version 3.7.
As described in detail here, the 32-bit PCI DMA zone that the kernel provides to the EMU10K1 driver is at a location that the EMU10K1 hardware cannot address. As a result, the driver falls back to the 16 MiB ISA memory region, which is not always a problem but it does fill up.
The linked article includes a kernel patch to relocate the 32-bit PCI DMA zone as a workaround. The relevant code has changed in more recent kernels so that the patch no longer applies. Following is an equivalent patch for more recent kernels.
diff -ur linux-5.10.12/arch/x86/include/asm/dma.h linux-5.10.12-sblive/arch/x86/include/asm/dma.h --- linux-5.10.12/arch/x86/include/asm/dma.h 2021-01-30 07:55:20.000000000 -0500 +++ linux-5.10.12-sblive/arch/x86/include/asm/dma.h 2021-01-31 10:35:41.265073281 -0500 @@ -74,7 +74,7 @@ #define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT) /* 4GB broken PCI/AGP hardware bus master zone */ -#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT)) +#define MAX_DMA32_PFN (1UL << (31 - PAGE_SHIFT)) #ifdef CONFIG_X86_32 /* The maximum address that we can perform a DMA transfer to on this platform */
OPL2/3 modprobe snd-opl3-synth
EMU8000 modprobe snd-emu8000-synth
EMU10K1 modprobe snd-emu10k1-synth
In alsamixer, make sure the Synth volume is unmuted and set to 100 and that the Master volume is at some audible level.
Running sbiload with no options should initialize the sound correctly. Do sbiload -v 1 to see evidence that it has loaded std.o3 and drums.o3 for OPL3 or std.sb and drums.sb for OPL2.
bash-4.1$ sbiload -v 1 Loading from /usr/local/sbiload-1.0.25/share/std.o3 Loaded instrument 000, bank 000: Acoustic Grand Loaded instrument 001, bank 000: Bright Acoustic ... Loading from /usr/local/sbiload-1.0.25/share/drums.o3 000: wrong instrument key! 001: wrong instrument key! ... Loaded instrument 035, bank 128: Ac Bass Drum Loaded instrument 036, bank 128: Bass Drum 1 ...
You can argue pedantically that this is not really loading a sound font since it is FM synthesis and there are no samples. Whatever, you have to load the thing before it will work.
Asfxload is used to load an .SF2 or .SBK soundfont file. For ISA cards the soundfont goes in on-board RAM, while for PCI cards it goes in the 32-bit PCI DMA zone of main memory.
The first attempt to load a soundfont often fails this way:
bash-4.3$ asfxload -i -M 8MBGMSFX.SF2 No Emux synth hwdep device is found
The problem magically goes away if you first enumerate the devices with aplaymidi:
bash-4.3$ aplaymidi -l Port Client name Port name 24:0 SB Live! 5.1 EMU10K1 MPU-401 (UART) 25:0 Emu10k1 WaveTable Emu10k1 Port 0 25:1 Emu10k1 WaveTable Emu10k1 Port 1 25:2 Emu10k1 WaveTable Emu10k1 Port 2 25:3 Emu10k1 WaveTable Emu10k1 Port 3 bash-4.3$ asfxload -i -M 8MBGMSFX.SF2 DRAM memory left = 123833 kB
Attempts to load sound fonts larger than the available RAM or the apparent hard limit of 128 MiB (131072 KiB) fail with "sfxload: no memory left."
AWE cards come with a 1 MiB sample ROM. To use it, you have to asfxload SYNTHGM.SBK (provided in SB16/SFBANK of an installation of Creative's DOS drivers). It doesn't consume any RAM. The resulting sound is cheesier than with the larger soundfonts.
bash-4.3$ asfxload -i -M SYNTHGM.SBK
On EMU10K1 cards, which lack the sample ROM, the command will succeed but no music will play.
Play a .MID file to the OPL2/3 FM port or any of the WaveTable ports listed by aplaymidi -l.
OPL2/3 Sound Blaster 16 with only an OPL3.bash-4.3$ aplaymidi -l Port Client name Port name 16:0 Sound Blaster 16 Sound Blaster 16 MIDI 17:0 OPL3 FM synth OPL3 FM Port bash-4.3$ aplaymidi -p 17:0 I_Got_You.mid
Don't get your hopes up. It sounds like this.
OPL2/3 EMU8000 AWE with both an EMU8000 synth and an OPL3 clone.bash-4.3$ aplaymidi -l Port Client name Port name 16:0 Sound Blaster 16 Sound Blaster 16 MIDI 17:0 Emu8000 WaveTable Emu8000 Port 0 17:1 Emu8000 WaveTable Emu8000 Port 1 17:2 Emu8000 WaveTable Emu8000 Port 2 17:3 Emu8000 WaveTable Emu8000 Port 3 18:0 OPL3 FM synth OPL3 FM Port bash-4.3$ aplaymidi -p 17:0 I_Got_You.mid bash-4.3$ aplaymidi -p 18:0 I_Got_You.midEMU10K1 Live! with only an EMU10K1 synth. (OPL3 in DOS and Windows was emulated, very poorly, by the drivers.)
bash-4.3$ aplaymidi -l Port Client name Port name 24:0 SB Live! 5.1 EMU10K1 MPU-401 (UART) 25:0 Emu10k1 WaveTable Emu10k1 Port 0 25:1 Emu10k1 WaveTable Emu10k1 Port 1 25:2 Emu10k1 WaveTable Emu10k1 Port 2 25:3 Emu10k1 WaveTable Emu10k1 Port 3 bash-4.3$ aplaymidi -p 25:0 I_Got_You.mid
ISA sound cards
PCI sound cards
Playing MIDI files to OPL3, GUS, EMU8000, ES137x, or EMU10K1 on baremetal DOS
KB
Home