VOGONS


Emulating MT-32 on an RPi2

Topic actions

First post, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

I've been working on and off on a project to add some additional capability to my Retro K6-2 machine, in particular the ability to play both GM/GS and LA midi using a compact equipment setup. My ultimate plan is to build an SBC into a 5 1/4 drive mount with an LCD message panel and basic controls on the front to use as a universal MIDI module.

The major unknown element of this project was which SBC would be best considering cost, capability, and form factor. I had previously tested Munt on an n270 Atom based netbook with some success, but I was unsure if ARM compilers would be efficient enough to allow Munt to run in realtime on any of the inexpensive SBCs available, the most obvious candidate being the Raspberry Pi 2.

After some tinkering and several long interruptions, I've achieved a measure of success and wanted to document my installation in case anyone wishes to use similar hardware to emulate Munt with their own systems.

I'm assuming your RPi2 has already been installed and configured using Raspbian. I began with a Debian Wheezy based version, then updated to Debian Jessie (latest stable) for more a up to date GCC and GlibC. I recommend you use this release as well.

Munt is fairly CPU intensive, so perform a couple of checks to ensure your CPU is operating at full power. Do the following as root.

# Pin the CPU by computing some digits of Pi
echo "scale=10^6; 4*a(1)" | bc -l &
# Measure the current CPU core clock
vcgencmd measure_clock arm
# This should be 900000000 for a Pi 2, higher for the more powerful models.
# Check for any thermal or voltage events.
vcgencmd get_throttled
# A healthy return is 0x0 indicating voltage and thermals are stable and in spec.
# 0x50000 indicates undervoltage has happened previously, but the CPU is clocked
# normally right now. 0x50005 indicates the CPU is currently throttled due to
# undervoltage. Other combinations indicate thermal issues as well.
killall bc

One important tool normally included in Raspbian but not in some cut down distros is cpufrequtils. If your CPU is underclocked, voltage and thermal issues don't appear to be a problem, and the CPU isn't manually underclocked in /boot/config.txt, this may be the culprit. Make sure it is installed.

apt-get install cpufrequtils

In terms of build requirements, I first installed the standard Debian build depends, cmake, Portaudio headers, some X headers, and QtMobility headers:

apt-get install build-essential cmake portaudio19-dev qtmobility-dev libglib2.0-dev libx11-dev libxt-dev libxpm-dev

Newer Debian versions (and workalikes such as Raspbian and Ubuntu) don't feature qtmobility, so please install qtmultimedia5-dev instead.

apt-get install git build-essential cmake portaudio19-dev qtmultimedia5-dev libglib2.0-dev libx11-dev libxt-dev libxpm-dev

Versions of qtmultimedia including 5.10 and newer already depend on libglib2.0-dev. If this applies to your case, you may exclude libglib2.0-dev and have it be managed automatically.

Feel free to add other libraries for JACK or Pulseaudio, depending what you're going to use.

Munt doesn't really enable any optimizations by default, so I used some settings recommended by ARM for the Cortex A7 (get them here) in concert with the general optimizer.

export CCFLAGS="-Ofast -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"
export CXXFLAGS="-Ofast -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"

If you're using an ARMv8 processor, such as the Cortex A53 in a Pi3 with a 64 bit build, please use the following flags.

export CCFLAGS="-Ofast -mcpu=cortex-a53"
export CXXFLAGS="-Ofast -mcpu=cortex-a53"

O2 can be used here instead of Ofast, but I'm more interested in speed than strict adherence to IEEE floating point.

Download the latest source version of Munt and unpack it to a directory of your choosing. As I used the master git branch of Munt, I labeled the source directory munt-master. Furthermore, I have created a build directory entitled munt-build at the same level as the source directory.

Next, configure the build directory using cmake. From the build directory:

cmake -DCMAKE_BUILD_TYPE=Release ../munt-master

Finally, run the make process.

make -j 4
sudo make install

Lastly, in the source directory, there is a subdirectory with two lightweight utilities designed to listen exclusively for incoming sequencer connections without any menus or dialogs for selecting MIDI files. One, xmt32, has a message display for the Pi's graphical output, the other, mt32d, outputs messages to the terminal. My eventual plan is to create a version of mt32d that outputs SYSX messages to a small LCD panel via GPIO, but "lightweight" seems like a good idea for the time being.

Go to the directory in question and build the software:

cd ../munt-master/mt32emu_alsadrv
make

At this stage, if you try to install the programs in question, you will receive an error message. You must unpack your MT32 roms (at least one of MT32_CONTROL.ROM and MT32_PCM.ROM or CM32L_CONTROL.ROM and CM32L_PCM.ROM) into a subdirectory of the mt32emu_alsadrv folder
called roms.

Last, install the final two executables.

sudo make install

This will also install your MT32 roms to /usr/share/mt32-rom-data.

You should be up and running with all three existant options to use Munt. I'm seeing 60% usage on a single core using this type of install, so you should have plenty of horsepower to run DOS emulators or other utility programs on the other three cores in the CPU.

Edit:
Based on reports from jaffa225man, this install method seems to be applicable for the RPi3 when using 32 bit userland (current Raspbian build). If Raspbian is updated to support a 64 bit userland and build toolchain, this will have to be revisited.
Added flags for an RPi3 with a 64 bit userland and small changes required for Debian Stretch (and Buster).

========= USEFUL DOWNLOADS =========
Ready to go disk images. Use any raw writing method to copy to an SD card (minimum 8gb). Follow the steps to copy ROM files as above to get working Munt.

For an RPi2:
Roland MT-32, CM-32L + General MIDI for $50 Building a MIDI box

For an RPi3:
Roland MT-32, CM-32L + General MIDI for $50 Building a MIDI box

Last edited by gdjacobs on 2019-10-26, 07:38. Edited 6 times in total.

All hail the Great Capacitor Brand Finder

Reply 1 of 292, by brassicGamer

User metadata
Rank Oldbie
Rank
Oldbie

This is an awesome project. You mentioned the processing power of the RPi2 in another post - do you think a mark 1 RPi would be munt l insufficient for the task?

Edit: perhaps my ignorance rather than an omission on your part - you have mentioned how GPIO interfaces with output but how does it interface with the host system?

Check out my blog and YouTube channel for thoughts, articles, system profiles, and tips.

Reply 3 of 292, by brassicGamer

User metadata
Rank Oldbie
Rank
Oldbie
awgamer wrote:

$35 for a rpi2, here's something a tenth of the price($3.60) http://www.fudzilla.com/news/mobile/39981-ind … 3-60-smartphone

Maybe they're both ARM powered but no GPIO or video out so I'm not sure what the comparison is TBH.

And my question had been answered elsewhere:

alexanrs wrote:

Just checked. The RPi2 needs to be somewhat overclocked (1GHz proc, 600MHz core, 487MHz RAM) to be able to keep up with munt, and a reasonably large buffer (500ms) to play well enough. Maybe the next iteration will be good enough, but as of now, I consider the RPi2 to be a bit on the weak side for this.

Check out my blog and YouTube channel for thoughts, articles, system profiles, and tips.

Reply 4 of 292, by awgamer

User metadata
Rank Oldbie
Rank
Oldbie

Video out isn't needed for an mt32/lapc-i/sound canvas/xg midi module, though it has an lcd screen, and it has wifi & bluetooth for connectivity.

Reply 5 of 292, by brassicGamer

User metadata
Rank Oldbie
Rank
Oldbie
awgamer wrote:

Video out isn't needed for an mt32/lapc-i/sound canvas/xg midi module, though it has an lcd screen, and it has wifi & bluetooth for connectivity.

Oh ok, sorry what I meant was if I had an RPi I would be using it for a hell of a lot more then just emulation. 😀 I do like your idea though.

Edit: silly typo.

Last edited by brassicGamer on 2016-02-21, 10:48. Edited 1 time in total.

Check out my blog and YouTube channel for thoughts, articles, system profiles, and tips.

Reply 6 of 292, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++
brassicGamer wrote:
Maybe they're both ARM powered but no GPIO or video out so I'm not sure what the comparison is TBH. […]
Show full quote
awgamer wrote:

$35 for a rpi2, here's something a tenth of the price($3.60) http://www.fudzilla.com/news/mobile/39981-ind … 3-60-smartphone

Maybe they're both ARM powered but no GPIO or video out so I'm not sure what the comparison is TBH.

And my question had been answered elsewhere:

alexanrs wrote:

Just checked. The RPi2 needs to be somewhat overclocked (1GHz proc, 600MHz core, 487MHz RAM) to be able to keep up with munt, and a reasonably large buffer (500ms) to play well enough. Maybe the next iteration will be good enough, but as of now, I consider the RPi2 to be a bit on the weak side for this.

The RPi2 is good because it has GPIO, is cheap, is small, and runs vanilla GNU/Linux with standard ALSA infrastructure (unlike Android). I plan to use GPIO to drive an LCD for the module output messages and use a few additional pins to allow resetting and changing between LA and GM/GS mode via front panel controls.

As for performance, I believe the information you quoted is outdated. I can confirm the RPi2 has sufficient performance to run Munt using the optimizations I listed while running at stock clocks. Presumably the NEON unit provides enough muscle. Compiling for the Atom was similar, performance was anemic until I compiled for SSE2.

All hail the Great Capacitor Brand Finder

Reply 7 of 292, by Zup

User metadata
Rank Oldbie
Rank
Oldbie

Maybe I'm missing something, but... does it accept MIDI I/O? I mean, can this be used as a MIDI module?

I have traveled across the universe and through the years to find Her.
Sometimes going all the way is just a start...

I'm selling some stuff!

Reply 8 of 292, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++
Zup wrote:

Maybe I'm missing something, but... does it accept MIDI I/O? I mean, can this be used as a MIDI module?

At the moment, I'm feeding the MIDI streams directly. It definitely is possible to use GPIO pins for MIDI using the on board UART and a breakout board, but I'm just going to use a USB adapter for the interface to make my life a bit easier. I want to make a HardMPU board for the other end of the connection, so I'll get my jollies soldering that.

awgamer wrote:

$35 for a rpi2, here's something a tenth of the price($3.60) http://www.fudzilla.com/news/mobile/39981-ind … 3-60-smartphone

All DOSBox forks with Munt included that I've tried do not split the PC and LA emulation into two processes, so you need enough horsepower in one core to do both jobs. A 1.6 ghz Cortex A9 isn't able to handle it, so a 1.3 ghz A7 won't stand a chance. Until the multithreading problem is resolved, you need ALSA to provide the software MIDI patching required to make Munt talk with your emulator on a second core. Android builds generally don't have the ALSA kernel modules, so you're in bad shape until someone ports vanilla Linux to this platform.

All hail the Great Capacitor Brand Finder

Reply 9 of 292, by sergm

User metadata
Rank Oldbie
Rank
Oldbie
gdjacobs wrote:

All DOSBox forks with Munt included that I've tried do not split the PC and LA emulation into two processes, so you need enough horsepower in one core to do both jobs

FYI: the semi-official DOSBox patch for munt readily supports asynchronous rendering by enabling "mt32.thread" option. So, if SDL supports multithreading on the platform (seems modern NDK does support threads), there should be no need for a dedicated process requiring some IPC to transfer MIDI data.

BTW, you not need ALSA to do the job, a simple FIFO should suffice as a raw OSS MIDI port. But I really don't like the idea of making yet another munt "driver" now for Android...

Reply 10 of 292, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++
sergm wrote:
gdjacobs wrote:

All DOSBox forks with Munt included that I've tried do not split the PC and LA emulation into two processes, so you need enough horsepower in one core to do both jobs

FYI: the semi-official DOSBox patch for munt readily supports asynchronous rendering by enabling "mt32.thread" option. So, if SDL supports multithreading on the platform (seems modern NDK does support threads), there should be no need for a dedicated process requiring some IPC to transfer MIDI data.

BTW, you not need ALSA to do the job, a simple FIFO should suffice as a raw OSS MIDI port. But I really don't like the idea of making yet another munt "driver" now for Android...

Might be a project for an Android developer, but that's not me. 😜

All hail the Great Capacitor Brand Finder

Reply 11 of 292, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

I've got my LCD output going using a hacked version of the ALSA console application. It's not anything special, but if anyone wants a copy just ask.

I'm fishing around for ideas on useful MIDI information to show on the screen and was wondering if there's a method I can overload to output channel playback indicators like in the Qt client. I've got one 16 column line to play with so I figure that should just work. Of course, if anyone has another interesting suggestion, I'd be happy to hear from you.

All hail the Great Capacitor Brand Finder

Reply 13 of 292, by stamasd

User metadata
Rank l33t
Rank
l33t

I am attempting this with a RPi zero. Stay tuned.

(edit) For the zero using the latest Jessie image (2016-02-26) you must install some other missing dependencies: libglib2.0 qt5-default

And of course "make -j 4" won't work as it's single-core.

(edit2) well the compilation and install went fine with the above changes. To actually test if it works I need to add a DAC to the zero for sound out.

Last edited by stamasd on 2016-03-10, 23:56. Edited 1 time in total.

I/O, I/O,
It's off to disk I go,
With a bit and a byte
And a read and a write,
I/O, I/O

Reply 14 of 292, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

The zero will not work the same as I don't believe it has a Neon unit, and the VFP unit is an earlier generation as well. Last, with the Pi 2 I'm seeing approximately 60% CPU load. I doubt an ARM9 core will have enough grunt to execute Munt in anything like real time.

Still, I hope you have good luck.

I just tested with PQ2 in DOSBox and everything looks good with a console ALSA driver augmented with some GPIO glue. Audio and SYSEX work nicely. DOSBox was a bit slow, but as long as Munt works fine I'm happy. Now I've got to track down or build an ISA MPU401 for my K6-2 DOS machine.

All hail the Great Capacitor Brand Finder

Reply 15 of 292, by stamasd

User metadata
Rank l33t
Rank
l33t

Well the plan is to try this zero as a dedicated MT32 emulator, with proper MIDI input and audio out, to be attached to a vintage gaming machine. As such, it won't be running pretty much anything else, so I hope it'll keep the pace.

I/O, I/O,
It's off to disk I go,
With a bit and a byte
And a read and a write,
I/O, I/O

Reply 16 of 292, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

A dedicated universal MIDI module is my plan, so our requirements are pretty well aligned.

Make sure you use the appropriate flags for the code generator.

export CCFLAGS="-march=armv6zk -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp"
export CXXFLAGS="-march=armv6zk -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp"

The older Broadcom CPU is at a significant architectural disadvantage which is why I doubt it can operate at 60% of one Pi 2 core. To get this approach to work, you're going to need every drop of performance squeezed out. I'd also test with audio through the HDMI out as you're still at a proof of concept stage.

All hail the Great Capacitor Brand Finder

Reply 18 of 292, by stamasd

User metadata
Rank l33t
Rank
l33t
keropi wrote:

there is a Pi3 now, faster and better - maybe it will work fine with this project

My approach is "how low can you go" 😀

Raspberry Pi zero is $5.

As far as audio out, I'll try a USB sound card first. I know I have one somewhere, but a quick search didn't turn it up. Maybe tomorrow. In the meantime I tried a Creative SB X-Fi Surround 5.1 Pro, also USB - but it just connects then immediately disconnects from the USB bus, over and over again. It's powered from the hub, and it should have plenty of juice so I doubt that's the problem (I can connect it fine to a computer using the same hub). Not a good sign.

[  132.223629] usb 1-1.1: new full-speed USB device number 57 using dwc2
[ 132.331910] usb 1-1.1: New USB device found, idVendor=041e, idProduct=30df
[ 132.331942] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 132.331956] usb 1-1.1: Product: SB X-Fi Surround 5.1 Pro
[ 132.331968] usb 1-1.1: Manufacturer: Creative Technology Ltd
[ 132.331979] usb 1-1.1: SerialNumber: 000007W8
[ 132.598703] usb usb1: clear tt 1 (9393) error -22
[ 132.606719] usb usb1: clear tt 1 (9393) error -22
[ 132.614754] usb usb1: clear tt 1 (9393) error -22
[ 132.622767] usb usb1: clear tt 1 (9393) error -22
[ 132.624843] usb 1-1.1: USB disconnect, device number 57
[ 132.903662] usb 1-1.1: new full-speed USB device number 58 using dwc2
[ 133.011920] usb 1-1.1: New USB device found, idVendor=041e, idProduct=30df
[ 133.011950] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 133.011964] usb 1-1.1: Product: SB X-Fi Surround 5.1 Pro
[ 133.011975] usb 1-1.1: Manufacturer: Creative Technology Ltd
[ 133.011987] usb 1-1.1: SerialNumber: 000007W8
[ 133.277727] usb usb1: clear tt 1 (93a3) error -22
[ 133.285703] usb usb1: clear tt 1 (93a3) error -22
[ 133.294592] usb usb1: clear tt 1 (93a3) error -22
[ 133.301775] usb usb1: clear tt 1 (93a3) error -22
[ 133.309758] usb usb1: clear tt 1 (93a3) error -22
[ 133.317803] usb usb1: clear tt 1 (93a3) error -22
[ 133.325774] usb usb1: clear tt 1 (93a3) error -22
[ 133.334642] usb usb1: clear tt 1 (93a3) error -22
[ 133.341799] usb usb1: clear tt 1 (93a3) error -22
[ 133.349724] usb usb1: clear tt 1 (93a3) error -22
[ 133.357715] usb usb1: clear tt 1 (93a3) error -22
[ 133.365835] usb usb1: clear tt 1 (93a3) error -22
[ 133.374473] usb usb1: clear tt 1 (93a3) error -22
[ 133.381776] usb usb1: clear tt 1 (93a3) error -22
[ 133.389736] usb usb1: clear tt 1 (93a3) error -22
[ 133.392811] usb 1-1.1: USB disconnect, device number 58

I/O, I/O,
It's off to disk I go,
With a bit and a byte
And a read and a write,
I/O, I/O

Reply 19 of 292, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

Even a USB headset should work. Also, if you output to the default or a dummy sound device, Munt will still let you know if it's being overrun by the MIDI stream.

All hail the Great Capacitor Brand Finder