Munt
Munt is a multi-platform software synthesiser emulating pre-GM MIDI devices such as the Roland MT-32 (1987), CM-32L (1989), CM-64 (1989) and LAPC-I (1989). It's useful for listening to MIDI files in a glorious way or get a chance to experience the soundtrack of many DOS games the way they were often originally composed.
Installation
You need two things basically, the Munt software and the ROMS of the synth we want to emulate. Please note that even though MT-32 is often referred to as the ideal DOS gaming sound device, its successor the CM-32L, has some advantages. According to a Roland synth collector:
Internally, the CM-32L contains everything that the MT-32 does, but contained an additional 33 samples in it's wave banks. Most of the added samples were sound effects. There are several games that make use of these added sound effects, such as Beneath a Steel Sky and Ultima Underworld. If you play these games with an MT-32, you will get the music, but you will miss out on a few sound effects here and there. This was designed in such a way that an MT-32 user would not know that they were missing anything but the CM-32L, CM-64, CM-500 user would be treated to a nice surprise with extra sounds.
However (dramatic pause), using the latest CM-32L may not be the best thing to do for some games that exploited the faults and issues found in the original MT-32. As explained by The Cranky Hermit:
The MT-32 went through many iterations and variants. [The main ones are] the very original model (sometimes called the rev0), and the CM-32L. There are plenty of others, but these two will cover all of your bases with regards to playing old games on a new computer. The difference between the two [...] is that the CM-32L has some additional sound effects built into it and fixes a number of firmware bugs. There are also a very small number of games that simply don't work on a rev0. However, many games, especially those by Sierra and Dynamix, actually exploit the rev0's firmware bugs to produce sound beyond its intended ability, and they will not sound right on a CM-32L, or on anything but a rev0. Therefore, the MT-32 rev0 should be the default model to emulate, and the CM-32L to be used only for games which use its sound effects, and also for games known to be incompatible with the rev0 [my emphasis].
ROM files
It's basically copyrighted binaries and data, so they can be a bit tricky to find. You want these files:
CM32L_CONTROL.ROM
CM32L_PCM.ROM
MT32_CONTROL.ROM
(find the 1987 unpatched version, that's rev0)MT32_PCM.ROM
They may be available under a slightly different name, just rename them.
Place the files in /usr/share/mt32-rom-data
.
md5sum
FYI:
bfff32b6144c1d706109accb6e6b1113 CM32L_CONTROL.ROM 08cdcfa0ed93e9cb16afa76e6ac5f0a4 CM32L_PCM.ROM 5626206284b22c2734f3e9efefcd2675 MT32_CONTROL.ROM 89e42e386e82e0cacb4a2704a03706ca MT32_PCM.ROM
Munt Installation
Note: You may need to install some missing headers here YMMV
git clone https://github.com/munt/munt.git cd munt mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -Dmunt_WITH_MT32EMU_QT:BOOL=OFF .. # We don't build the QT tool thing make sudo make install cd ../mt32emu_alsadrv make sudo make install
Usage
As a MIDI player
The idea is to get a MIDI player to send MIDI data to the Munt ALSA module.
- First we start Munt:
mt32d
- Then we check where the Munt client is:
aconnect -l | grep MT-32
- On my machine it looks like this, it may be slightly different for yours:
client 128: 'MT-32' [type=user,pid=23689]
- So we know that Munt is listening on port 128, so to play MT-32 friendly MIDI files, just do something like:
aplaymidi *-mt32.mid --port 128
IMPORTANT: If you have installed both MT-32 and CM-32L ROM files, by default mt32d
will make use of the CM-32L ROM files. To force it to use the MT-32 romset, start mt32d like this:
mt32d -o 2
As a sound engine for DOSBox
TODO
As an External soundcard
TODO
MOAR
SYSEX init files
Very often, compos for the MT-32 are configuring the voices/synth in a specific way via SYSEX messages. These messages can be provided in 3 different ways:
- Embedded in the MIDI composition itself (which is why some MIDI files seem to take some time to start playing), in which case you have nothing to do.
- Embedded in a distinct MIDI file. If that's the case you're expected to load/play it before playing the other MIDI files.
aplaymidi INIT.MID --port 128 # play the MIDI file that will configure the synth aplaymidi FILE1.MID --port 128 # play your files aplaymidi FILE2.MID --port 128 # etc
- As a distinct SYSEX file. That needs a bit more work, because basic ALSA tools that work with raw MIDI only do so with specific type of ALSA Raw MIDI devices. So we need to create a Virtual Raw MIDI device, connect it to Munt, and then send it the SYSEX data.
sudo modprobe snd-virmidi # create Virtual Raw MIDI interfaces aconnect -l # note where VirMIDI 2-0 and MT-32 are, what card number is VirMIDI aconnect 24 128 # connect VirMIDI 2-0 out to MT-32 in (default :0) amidi -s INIT.SYX -p hw:2,0 # send SYSEX data to VirMIDI (hw:2,0 is card=2) aplaymidi FILE1.MID --port 128 # play your files aplaymidi FILE2.MID --port 128 # etc
Note: Every time some SYSEX data is sent and regardless how it is sent, whatever they change, will remain until the synth is reset, so don't forget that when you start playing MIDI files that do not need these configurations, or others, or do not reset the synth themselves. It will not sound right at all.
GUI for the ALSA plug-in
If you want to have a small MT-32-like graphical interface instead of a daemon, you can start the ALSA plug-in with xmt32
instead of mt32d
. Options are the same. Note that you don't need this to see the LCD messages, if you run the dameon as a foreground process it will be printed to stdout
.
General MIDI support
The MT-32 predates General MIDI. However Munt provides a GM emulation in case you'd like to feed the MT-32 with GM data. In that case you need to the secondary port of the Munt ALSA interface, namely:
aplaymidi mt32stuff.mid --port 128 # MT-32 interpretation of MIDI stream (default) aplaymidi mt32stuff.mid --port 128:0 # MT-32 interpretation of MIDI stream aplaymidi gmstuff.mid --port 128:1 # GM emulation of MIDI stream
Not sure how useful/good it is, the authors say that about it:
128:1 attempts to emulate general midi support using the MT-32 mode, try it for a laugh.
Redirecting Munt output to JACK via pulseaudio
OK this one is very specific to my setup but could give pointers for other scenarios. Today, PulseAudio is good enough to handle general audio applications, and has quite advanced mixing/wiring features that makes it very handy for desktop audio, handling BT headsets and things I don't want to waste time configuring. However for real-time audio processing and specific sound applications (Ardour, Pure Data, Supercollider, custom audio pipelines, etc), then JACK is by far still the most preferred audio system. So I have configured PulseAudio to ignore entirely (it's possible!) my external sound card that I can use with JACK whenever I want, and I let PulseAudio manages the internal USB soundcard of my display, and that's just perfect.
The problem with Munt is that it only uses the ALSA audio system for sound output, and with a PulseAudio enabled OS, it means that it's a bit tricky to use the usual .asoundrc
hacks to make a non-JACK audio app send its audio stream to JACK. However, thanks to pulseaudio-module-jack
it's very easy to redirect Munt audio to JACK.
Of course all this stuff comes at the cost of some added latency, but given the use case here, that's fine.
- install the PulseAudio JACK sink
sudo apt install pulseaudio-module-jack
- start JACK like you want
jackd -dalsa -dhw:DSP,0 -r44100 -p128 -n2
- start Munt like you want
mt32d
- enable the PulseAudio JACK sink
pactl load-module module-jack-sink channels=2; pactl load-module module-jack-source channels=2; pacmd set-default-sink jack_out
- launch
pavucontrol
to route the audio frommt32d
to the Jack sink.
Note: it would be possible to script the last step, but pactl
is a PITA to work with.