A User's Guide to ALSA
The observant reader might wonder how I can route MIDI data without the benefit of MIDI hardware. Thanks to ALSA's virmidi module, my system has four virtual devices usable as raw MIDI I/O ports for any other ALSA sequencer clients. The sequencer of what is known as the ALSA sequencer API is not a sequencing application such as MusE or Rosegarden. This sequencer manages the merging and timing of freely interconnected MIDI data streams, including multiple connections to single ports. Compliance with the ALSA sequencer API allows each client to interconnect freely to one or more other clients, and it has become an expected capability of modern Linux audio software.
The ALSA aconnect utility tells me what ports are available for connection via the ALSA sequencer:
aconnect -i client 0: 'System' [type=kernel] 0 'Timer ' 1 'Announce ' client 72: 'Virtual Raw MIDI 1-0' [type=kernel] 0 'VirMIDI 1-0 ' client 73: 'Virtual Raw MIDI 1-1' [type=kernel] 0 'VirMIDI 1-1 ' client 74: 'Virtual Raw MIDI 1-2' [type=kernel] 0 'VirMIDI 1-2 ' client 75: 'Virtual Raw MIDI 1-3' [type=kernel] 0 'VirMIDI 1-3 '
This report indicates that I have four virtual MIDI ports. Whatever software I assign to those ports then can be connected to any other ALSA sequencer clients:
aconnect -o client 65: 'OPL3 FM synth' [type=kernel] 0 'OPL3 FM Port ' client 72: 'Virtual Raw MIDI 1-0' [type=kernel] 0 'VirMIDI 1-0 ' client 73: 'Virtual Raw MIDI 1-1' [type=kernel] 0 'VirMIDI 1-1 ' client 74: 'Virtual Raw MIDI 1-2' [type=kernel] 0 'VirMIDI 1-2 ' client 75: 'Virtual Raw MIDI 1-3' [type=kernel] 0 'VirMIDI 1-3 '
This report shows my available receiving ports. Thus, the following command connects the first virmidi port to my onboard FM synth:
aconnect 72:0 65:0
The kconnect, alsa-patch-bay and QJackCtl programs provide graphic interfaces for device identification and connection.
Figure 3 shows off a small but powerful MIDI sequencing system. The main program is Rob Buse's seq24, a lightweight looping sequencer designed in the style of the hardware sequencers of the 1980s and 90s. seq24 manages its connections internally, and the figure conceals the connections between the virtual keyboard and seq24 as well as the output targets for the individual sequences. Some of the sequences have been routed to the OPL3 synth; others have been sent to an instance of TiMidity running as a Soundfont server.
Like many other laptop owners, I've hooked up a USB device to my machine, in this case a MIDIman 2x2 MidiSport. The MidiSport provides two independent I/O ports, and yes, ALSA supports multiport MIDI hardware. However, I don't always have my MidiSport with me when I use this machine, so I prefer to load the USB module after setting up my CS4232 and virmidi cards. To defeat the autoloading of my USB MIDI module, I added these lines to /etc/hotplug/blacklist:
# So I can keep my preferred order of sound cards: snd-usb-audio # uhci ... usb-uhci handles the same pci class: usb-uhci
Next, I wrote the following script to configure and activate the MidiSport 2x2:
echo "Loading MidiSport firmware..." modprobe snd-usb-audio sfxload -I \ /usr/share/usb/ezusbmidi/ezusbmidi2x2.ihx \ -D /proc/bus/usb/001/003 echo "Done !"
The firmware and loader are included with the ALSA installation. You may need to query the /proc/bus/usb filesystem for your available USB identifiers, and you may need to try each identifier to find which one applies to your hardware. Use the cat command to list your identifier numbers:
$ cat /proc/bus/usb/001/ 001 003
The system reports an error if you select the wrong identifier, so at least in my case the trial-and-error process didn't last long.
As though I hadn't already stuffed my little system full of ALSA drivers, I also wanted to use the Core Sound PDAudioCF card, a high-quality digital audio input card made for handheld computers, such as the Zaurus, but quite usable with a CF-to-PCMCIA adapter. Again, I want to have my other devices configured before setting up the PDAudioCF, so I simply wait until I have everything else working as desired before inserting the card. The system autodetects the new hardware and loads the appropriate module (snd-pdaudiocf), a procedure totally transparent to the end user.
Using this card is easy. The following example illustrates the use of ALSA's arecord utility to record a 30-second stereo digital audio stream from the S/PDIF digital output of my desktop system's SBLive to the PDAudioCF card:
arecord -f dat -D hw:3,0 -d 30 foo.wav
The -f dat option sets the recording format to include a sample rate of 48kHz, which is the only output sample rate supported by the SBLive. I substituted -f cd for the DAT option and recorded again from the S/PDIF output of my Delta 66, this time with the standard redbook CD audio values, that is, 16-bit stereo audio with a sample rate of 44.1kHz. In both cases, the recording and playback was flawless and had beautiful audio quality, thanks to the PDAudioCD card. For more details regarding ALSA's playback and record utilities, see man aplay and man arecord.
Linux laptop sound support is a weird world, and I spent considerable time getting things working properly. However, my machine now has a sound system supporting stereo analog PCM I/O, a CD audio channel, a MIDI-accessible onboard synthesizer, four virtual MIDI I/O ports, an external 2x2 MIDI interface and a high-quality digital audio input port. Not too shabby a set of capabilities for a PII 366, and, of course, the real thanks go to ALSA.
By the way, if I forget the ordered numbering of my cards, I always can query the proc filesystem for their numbers and status:
$ cat /proc/asound/cards 0 [CS4231 ]: CS4231 - CS4231 CS4231 at 0x534, irq 5, dma 1&0 1 [VirMIDI ]: VirMIDI - VirMIDI Virtual MIDI Card 1 2 [M2x2 ]: USB-Audio - Midisport 2x2 Midiman Midisport 2x2 at usb-00:07.2-1, full speed 3 [PDAudioCF ]: PDAudio-CF - Core Sound PDAudio-CF Core Sound PDAudio-CF at 0x100, irq 11
Thus, the specific hardware definitions would be hw:0, hw:1, hw:2 and hw:3. hw:1 and hw:2 are MIDI-only devices and cannot be used for audio purposes. And yes, proc is reporting a CS4231 where I've configured a CS4232, but Takashi Iwai assured me that this behavior is normal for the chipset. I know, it's weird.
Similis sum folio de quo ludunt venti.