Softsynth and Midi Howto

This QuickHowto describes the needed setup to control a midi capable software synthesizer from a midi sequencer through a virtual midi connection using ALSA. This document can be freely translated and distributed. It's released under the GNU Free Documentation License.

Introduction

Software synthesizers like Csound, Pd, jMax or Spiral Synth Modular offer nearly endless freedom to create known or unknown, common or unusual sound experiences. They can also replace pricy hardware synths or the inexpensive, often bad sounding midi synths on some soundcards, if these are supported under Linux at all. On the other hand, composing inside those softsynths can be a tedious task: In Csound for example one has to write endless rows of numbers in a spread sheet like manner - not a comfortable way to make music.

Midi sequencer applications are more suitable for this task. They provide an interface to insert notes and control data in convenient ways: as notes in a real score, as marks in a piano roll or as a list of midi events, if you prefer this view. Another kind of midi sequencers offer a tracker like way of entering notes, like many people are used to from the good old days, when that was the state of art in the Scene. And last but not least some midi sequencers allow you to record your own playing on a keyboard or on another physical device, which is to many the most natural way of writing music.

But midi sequencers like to output their notes to midi devices, that normally route their events to the outside world: to hardware synths and samplers. With virtual midi devices, one can keep the midi data inside the computer and let it control other software, running on the same machine. This QuickHowto describes all that is necessary to achieve this goal.

Device Setup

In our setup we use the ALSA sound architecture, as this is (or should be) the standard way of doing serious audio and midi on Linux. The tutorial assumes, we are running the 0.9.0 branch of ALSA, but the virtual midi module was present in ALSA 0.5.x as well, so most of the following should apply for this as well. In the OSS sound architecture the v_midi module can be used, but this is beyond the scope of this document.

To use ALSA's virtual midi card, the snd-virmidi module has to be present. Make sure, that you did build this module, it might be missing if you configured ALSA to build only the modules for your actual card[s].

The virmidi module has to be loaded to make the virtual midi ports available. You can test-load it by hand with:

$ modprobe snd-virmidi index=1

where index is set appropriatly to the first free card index (=1 if you have only one card, that has index 0). (This option was called "snd_index" in older versions of ALSA.) But it is more convenient to adapt your modules configuration to have it sitting around already when you need it. For that we need to extend the ALSA section in /etc/modules.conf (or in another location, depending on your distribution) with the following:

# Configure card 1 (second card) as a virtual midi card
alias sound-service-1-1 snd-seq-oss 
alias sound-service-1-8 snd-seq-oss 
alias sound-slot-1 snd-card-1 
alias snd-card-1 snd-virmidi

This configures a virtual midi card as the second card with index 1, assuming you have one real soundcard, which would be very useful. If you already have a real second card like I do, you change above to read:

# Configure card 2 (third card) as a virtual midi card
alias sound-service-2-1 snd-seq-oss 
alias sound-service-2-8 snd-seq-oss
alias sound-slot-2 snd-card-2
alias snd-card-2 snd-card-virmidi

If you have even more cards, well, you should know the deal by now... It might be necessary to restart the ALSA sound system. After that you should have added the virtual midi card, as can be seen in /proc/asound/cards:

$ cat /proc/asound/cards 
0 [card0          ]: ICE1712 - M Audio Audiophile 24/96
M Audio Audiophile 24/96 at 0xb800, irq 5
1 [card1          ]: EMU10K1 - Sound Blaster Live!
Sound Blaster Live! at 0xc800, irq 11
2 [card2          ]: VirMIDI - VirMIDI
Virtual MIDI Card 1

In this example of my own machine, I have the VirMIDI card as third card, index 2. This setup results in the following raw midi devices, found in /proc/asound/devices [showing only the midi devices]:

$ cat /proc/asound/devices 
8: [0- 0]: raw midi
41: [1- 1]: raw midi
42: [1- 2]: raw midi
75: [2- 3]: raw midi
74: [2- 2]: raw midi
73: [2- 1]: raw midi
72: [2- 0]: raw midi

The devices starting with '2-' are my virtual midi devices, yours might start with '1-' if you only had one physical card in your system.

You can get a nicer listing with ALSA's own aconnect utility, which we will need anyways. Called with option -o (or -lo) it will show the midi devices capaple of midi output, a call with -i shows those with midi input capabilities:

$ aconnect -o
[...]
client 80: 'Virtual Raw MIDI 2-0' [type=kernel]
0 'VirMIDI 2-0     '
client 81: 'Virtual Raw MIDI 2-1' [type=kernel]
0 'VirMIDI 2-1     '
client 82: 'Virtual Raw MIDI 2-2' [type=kernel]
0 'VirMIDI 2-2     '
client 83: 'Virtual Raw MIDI 2-3' [type=kernel]
0 'VirMIDI 2-3     '
$ aconnect -i
[...]
client 80: 'Virtual Raw MIDI 2-0' [type=kernel]
0 'VirMIDI 2-0     '
client 81: 'Virtual Raw MIDI 2-1' [type=kernel]
0 'VirMIDI 2-1     '
client 82: 'Virtual Raw MIDI 2-2' [type=kernel]
0 'VirMIDI 2-2     '
client 83: 'Virtual Raw MIDI 2-3' [type=kernel]
0 'VirMIDI 2-3     '

The shown devices correspond to ALSA's own OSS compatible raw midi devices in the /proc/asound/dev directory tree. For example /proc/asound/dev/midiC2D0 is the first midi device of our virtual midi card at index 2, called Virtual Raw MIDI 2-0 by aconnect. In Debian those devices are available in /dev/snd/ as well, and they also are internally linked with the old OSS device locations: /dev/midiXX. To make sure, that I can get the ALSA raw midi ports from /dev/midiXX I symlinked them with:

$ ln -s /dev/snd/midiC2D0 /dev/midi20
$ ln -s /dev/snd/midiC2D1 /dev/midi21
[...]

but this should not be necessary, so don't do this at home, kids!

Now that we have created and configured a VirtualMIDI card, we can use it in our applications like any other Midi devices. Just insert the needed device, be it a OSS compatible /dev/midi20 or an ALSA midi port like 80:0, at the correct configure location of your favourite sequencer and synthesizer application.

Routing Midi Events

aconnect

But without further arrangements we will not be able to send the midi events from our sequencer to a softsynth. For that, we first need to connect two ports with, you guessed it, the utility aconnect. This tool connects two or more ports. Its -i and -o output above already showed us the available ports. With a simple syntax these can now be connected in a one-way fashion:

$ aconnect [sender port] [receiver port]
$ aconnect 80:0 81:0

This routes all midi data sent to port 80:0 over to port 80:1. In our setup this means, that every event coming in at /dev/midi20 gets sent to /dev/midi21, from where it can be read ('received') by another application.

If you had configured the VirMIDI card as second card with card index 1, you would probably have these ports: :

$ aconnect -lo 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

Here you can connect for example port 72:0 (/dev/midi10) to port 73:0 (/dev/midi11) with:

$ aconnect 72:0 73:0

aconnect can show us, what was created, with its -lo and -li options:

$ aconnect -lo
client 72: 'Virtual Raw MIDI 1-0' [type=kernel]
0 'VirMIDI 1-0     '
Connecting To: 73:0
client 73: 'Virtual Raw MIDI 1-1' [type=kernel]
0 'VirMIDI 1-1     '
Connected From: 72:0
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

You see, that 'Virtual Raw MIDI 1-0' now is connected to 'Virtual Raw MIDI 1-1'. Now, depending on your applications, you can read midi data, that was sent to 'Virtual Raw MIDI 1-0' from 'Virtual Raw MIDI 1-1', or in OSS-device speak: What was sent to /dev/midi10 gets routed to /dev/midi11 and can be read from there.

You can also connect more than one port to a port. If you call aconnect twice like this:

$ aconnect 72:0 73:0
$ aconnect 72:0 74:0

you can receive the same data send to /dev/midi10 at /dev/midi11 and at /dev/midi12 as well. And of course you can really hammer your machine, if you create more VirMIDI cards and wildly connect these. There's no stopping us now...

To disconnect all ports use:

$ aconnect -x 

or disconnect only one connection with:

$ aconnect -d 72:0 74:0

Applications

In this last section I will show some examples, how to use the virtual midi connections in various applications. I will assume a VirMIDI card as a third card in the system, using ALSA midi ports 80:0 to 83:0 that correspond to the raw OSS midi devices /dev/midi20 to /dev/midi23 and to the ALSA raw midi devices /dev/snd/midiC2D0 to /dev/snd/midiC2D3. Of these, the first two have been 'aconnected' with

$ aconnect 80:0 81:0

As shown, this means, that all midi data sent to /dev/midi20 (or port 80:0 or /dev/snd/midiC2D0) can now be read at /dev/midi21 (or port 80:1 or /dev/snd/midiC2D1)

Sequencers

MuSE

MuSE is a full featured midi sequencer written by Werner Schweer and available at http://www.muse-sequencer.org/. We will need to configure the the virtual midi port as output port in the section "Config->Midi Ports". In MusE, the ports are named by their ALSA names 'VirMIDI X-X':

MusE - Midi Device Configuration

Now make sure, that the right port is selected as output port for any channel, for that you want the software synthesizer to listen to and play the midi events:

MusE - Trackview

Somehow I could not use 'VirMIDI 2-0' as output device in MuSE 0.4.9, although that is the expected device, when I wanted to receive on 'VirMIDI 2-1', but had to use it the other way around. I don't know why, I'm probably stupid, and you might have to experiment a bit. One could also use the midi02 or midi2 devices.

ttrk

ttrk is a simple, quick and tight midi sequencer bye Billy Biggs with a tracker interface. It can output it's midi data to a midi port, configured in the file $HOME/.ttrkrc

Put this line there, to have ttrk write to /dev/snd/midiC2D0:

mididev = /dev/snd/midiC2D0

Shaketracker

Shaketracker revives the tracker interface in MIDI like ttrk, but it has a more complete translation of the classic tracker effects to midi data. It is written by Juan Linietsky. Unfortunatly it uses the OSS sequencer device for its midi output, not the raw midi devices. This can confuse aconnect, at least I could not get it to work with aconnect as MuSE or ttrk. But there's a workaround, that involves aseqview. If we start aseqview before shaketracker, shaketracker recognizes the aseqview-port and can use it. One just has to select it in the 'User Devices' section of Shaketracker, where it shows up by its ALSA name 'Viewer Port 0':

Shaketracker - User Device Selection

It is convenient to give this User Device a good name instead of 'Null Output'.

If we just start aseqview without options, we would need to aconnect the aseqview port with the softsynth port, but as shown in [aseqview] we could also start aseqview directly with a destination port. Don't forget to use the new User Device in every track, that should go to the softsynth. I always run shaketracker with a little shell skript, that starts aseqview, waits for the creation of ports and then starts shaketracker:

#!/bin/sh
aseqview -d 81:0 &
# sleep 2 seconds to let aseqview do its work:
sleep 2
shaketracker

Software Synthesizer

Pure Data

Miller Puckette is the genius behind the open source software synth and multimedia development environment Pure Data (Pd), that evolved out of MAX and in turn was the base for the MAX-extension MSP. Newer versions of Pd support the ALSA sequencer right out of the box, so there is no need to use a virtual midi card if your other software supports the sequencer directly as well.

Pd also can use raw midi devices to read midi events, that are specified with the option '-midiindev <devnumber>' but it has an irritating way of specifying which device to use. The formula is as follows: To use /dev/midi0, start Pd with 'midiindev 1', to use /dev/midi1 start it with '-midiindev 2' and so on. Got it? Your have to specify the real device number plus 1 here. Another example: For /dev/midi21 start Pd with '-midiindev 22'

Pd has a help patch 'Test audio and Midi', that is invaluable in locating the right midi device.

Csound

Csound is the grandmother of most of todays software synthesizers, and it has learned Midi as well. 'csound --help' shows, where one has to configure the midi input device:

-M dnam or --midieventdev=dnam ........ Read MIDI realtime events from device

So in our example we need to start Csound as:

$ csound -M /dev/midi22 -o devaudio midi.csd

Conclusion

By now you should know how to play music, that was composed in a midi sequencer, with a software synthesizer. Of course, tools like aconnect and aseqview don't need to be used with a midi software sequencer. You could also redirect events, that come into your machine from an external sequencer or from an external midi keyboard, directly to the software synth without the midi sequencer step. Just 'aconnect' the external midi device to your softsynth or to the on-board synth of your soundcard. Or go the other way around: Pd, Csound or environments like Keyit allow you to create midi events in algorithmic ways, that are nearly impossible with classic Cubase-like midi sequencers: With aconnect you can route these events to any midi capable sound module you have.


comments
  • unknown visitor wrote:
    thanks, this info was useful
  • Prakash J K wrote:
    great work.between will you people prepare a howto Virtual MIDI in onboard soundcards with no MIDI Ports?.Thanking you all
  • fbar wrote:
    Hi Prakash, the cool thing is: as this tutorial is about "virtual" midi, it doesn't require a real midi capable soundcard at all. --fbar
  • Benedito Filho wrote:
    Very good! I like it... Thanks
  • simpleton wrote:
    Okay, interesting, but why we gotta use all the complicated stuff? Use Seq24, Jack, and Zyn once, much easier to figure out.
  • bri wrote:
    Keyit ? hope you mean Keykit - one of the best midi apps i've ever come across - glad to see it get a mention

name:
I'm no spammer: