AWE64 midi synth driver v0.4.2

Description

Here is my experimental AWE64 midi synth driver for ALSA. It is derived from the sound driver included in the standard kernel written by Takashi Iwai, ported to the ALSA framework. With it you can play a type 0 midi file using the playmidi1 test program. A temporary method also exists for connecting Midi-in to the driver which allows direct playing from a midi keyboard.

I hope that parts of this driver will be useful for writing similar drivers. To this end I have separated out the midi emulation code so that it could be made into a module and used by any other driver. The same is true of the soundfont handling code. I would like feedback on these ideas.

Latest news

In ALSA CVS, 3 May 1999

There is no need to use the driver version here as it has been merged into the main CVS tree.

Version 0.4.2, 22 Feb 1999

I strongly advise that you upgrade to this version, especially if you thought that there was anything strange about the sound before. I would also try using the -A1 or -A2 flag to sfxload, to see if that sounds better.

Version 0.4.1, 16 Feb 1999

Added modulation wheel, reverb and equalization are set at startup. Drumkit support improved. Bug in panning fixed.

Version 0.4.0, 15 Feb 1999

Big reorganization of the interface.

  • The driver now appears as four ports on one kernel client. This gives you 64 midi channels, and although the hardware only gives you 32 simultaneous voices at most, all the channels can be set to different instruments or whatever.
  • Routines to connect drivers that use sequencer events, rather than raw midi, are provided.
  • The MIDI emulation is separated out so that other drivers could use it.
  • Sustain is added and so now the most common controls are implemented. The framework is there to quickly add the rest.

If you have previously downloaded my modified playmidi1.c file you will need to replace it with the latest.

For more see the changelog.

What is needed

Downloads

You need to download the

  • The alsa-emu-0.4.2.patch.gz driver source. This is in the form of a patch that can be applied to the current CVS tree of ALSA. I don't think that it will patch the latest release of ALSA so be sure to use an up to date CVS tree.
  • Source to a slightly modified version of sfxload alsa-sfx.tar.gz or as a patch against sfxload-0.4.2.
  • Use this playmidi1.c instead of the one in the alsa-lib/test directory.
  • Earlier restrictions on the soundfont you can use no longer apply. But if you don't have a suitable one use GU11-ROM.SF2.gz (as supplied with RedHat).

Building

Apply patch

The patch (its mainly new files) should be unpacked in the alsa-driver directory.

cd ..where-ever/alsa-driver
patch -p1 < alsa-emu-0.4.2.patch

Driver

After applying the patch it should just build if you have a 2.2.x system. I have not even tried it on 2.0.x.

    aclocal
    autoconf
    ./configure --with-sequencer=yes --with-isapnp=yes --with-debug=full
    make install

The --with-cards=sbawe option can be used to cut down on compilation time. There is no need for the configuration step if you've already done them.

sfxload

Unpack the source somewhere and type make.

Making it work

You have to follow this slightly lengthy procedure to load everything up. You will probably want to make these steps into a script. .AL "1" 1 None Load modules as normal

modprobe snd-sbawe

None Load a soundfont. You need to use the very slightly modified sfxload that you downloaded above to do this.

sfxload GU11-ROM.SF2

There will be a couple of warnings that can be ignored. None Un-mute channels as normal using alsamixer, xamixer, amixer etc. Make sure that the synth output is un-muted and turned up.

Now you should be able to run the test playmidi1 program.

Controls

There are a few things that can be controlled temporarily via the patch interface.

dd if=/dev/asound/0/patch0 count=1 bs=1

Using a different block size will trigger a particular command.

bs=1
Trigger a test note.
bs=2
Connect MIDI-in to the synth. After this command it will be possible to play from a connected keyboard etc.
bs=3
Disconnects from MIDI-in.
bs=4
All notes off.

This is now done automatically when the sequencer disconnects, so this is not really needed anymore.

Unloading the modules

Should you want to unload the modules you may find that you need to run the following command first. (But try without first as this may not be a problem anymore).

dd if=/proc/asound/0/patch0 bs=3 count=1

Then you can unload everything with a simple

modprobe -r snd-sbawe

Possible problems and limitations.

  • It will most likely break if you try to load a font while playing. There is no locking at all between these actions. I haven't actually had a problem, but you were warned. Temporary solution: don't do it.
  • You can now load a soundfont that uses samples that are stored in RAM. Although it works it is much slower to load than it should be. This is because I can not get the samples to write to RAM reliably. Many samples will write perfectly, but some will have a large number of missing sample points. It is as if sometimes the write address pointer does not increment properly (I saw the same problem on read as well, leading to duplicate words). The only way that I can get it to work is to set the address each time. The OSS driver doesn't do this and seems to work fine so there must be something that I am missing. Any help would be appreciated.
  • There is not a good method of loading up the sequencer client. Really the user is the only one who can know what should be connected to what. You may or may not want MIDI in to be connected directly to the soundcard. Therefore we need a user utility to determine which client/port combinations are connected together. At present I just have a hack to connect the synth driver to the MIDI-in. Thats all the ddstuff.
  • I get
    snd: seq: snd_seq_pool_done() - pool isn't free!!

messages when a client disconnects from the synth. I believe that this is harmless, or at least mostly harmless.

Feedback

Bug reports

Please let me know if this works for you. I am happy to receive bug reports, or any mail about this driver.

Design notes

There are some design notes (under construction).

Changelog

If you want to see what has changed here is the changelog.

Applications

Applications that can use the driver

The test program playmidi1.c can only play type 0 midi files. The following is a list of applications that can make use of the midi driver. If you know of any more please let me know.

Widi

This is a midi player (and other formats) written by Isaku Yamahata. You can find it at http://www.ne.jp/asahi/i/yamahata/widi. It will play type 1 midi files as well as type 0. You need egcs 1.1.1 or some other very up-to-date compiler to build it unfortunately.

I made this patch to the widi-19990204-SNAP version. This has been applied in the later versions.

You need to set the environment variables to set up the correct clients and ports to talk to. For me this was:

export WIDI_SEQUENCER_ALSA_DEST_QUEUE_A=1
export WIDI_SEQUENCER_ALSA_DEST_CLIENT_A=65
export WIDI_SEQUENCER_ALSA_DEST_PORT_A=0
export WIDI_SEQUENCER_ALSA_DEST_QUEUE_B=1
export WIDI_SEQUENCER_ALSA_DEST_CLIENT_B=65
export WIDI_SEQUENCER_ALSA_DEST_PORT_B=1

I believe that the latest version uses just WIDI_SEQUENCER_ALSA_DEST_QUEUE.