VOGONS


First post, by gfrh

User metadata
Rank Newbie
Rank
Newbie

Hello fellow MT-32 enthusiasts,

A few years ago, I worked on a limited Rust port of Munt. It only targeted a very limited configuration (CM-32L, "good default" settings). The goal was to create a device I could compile to WASM for web use, and Emscripten was difficult to incorporate into my projects. To ensure correctness, the goal was sample-accurate behaviour compared to Munt. I only got ~15% through.

Fast-forward a few years, LLMs have made the porting of existing FOSS code as a reference oracle implementation trivial. I captured a few hours of raw MIDI from ScummVM games to serve as comparison tests.

So if anyone here is interested, here are some Rust crates:

https://crates.io/crates/moont: Core CM-32L synthesizer library
https://crates.io/crates/moont-render: Render .mid files to .wav
https://crates.io/crates/moont-live: Real-time ALSA MIDI sink
https://crates.io/crates/moont-web: WebAssembly wrapper with Web Audio API

Since these were based on Munt sources and as a test comparison, they are also licensed LGPL2.1+, with existing copyrights attached.

Some unique implementation details:
* There are no external dependencies for the main library. I'm considering making it no_std in the near future.
* There is optional General MIDI emulation.
* All of these crates support a bundle-rom feature flag that embed the control/PCM ROM, for builds where you don't care about Roland lawyers. It's more involved that just adding them as static buffers: all of the pre-processing (parsing, unscrambling) is done at build time, and Rust literals are generated for the build.
* The moont-live crate has a feature (repl) that allows simple control commands.

It's still pre-1.0 so please let me know if there are major API changes you want to see before I cut a 1.0, hopefully in a few weeks.

I don't have any plans to expand the scope beyond my original singular CM-32L configuration, but if you have good reasons why I should diverge, please contact me. Otherwise, feel free to fork!

Reply 1 of 6, by SScorpio

User metadata
Rank Oldbie
Rank
Oldbie
gfrh wrote on Yesterday, 01:42:

I don't have any plans to expand the scope beyond my original singular CM-32L configuration, but if you have good reasons why I should diverge, please contact me. Otherwise, feel free to fork!

CM-32 is pretty much for gaming as the additional voices are different sound effects. However, there are some game that don't work on correctly on REV 01 which the CM-32 uses. If you want to support everything correctly, you'll want MT-32 REV 00 support as well.

Reply 2 of 6, by BaronSFel001

User metadata
Rank Member
Rank
Member

Does this still require the Roland ROMs to work or has that functional ecosystem been reverse-engineered past that point? While Roland seems content to look the other way due to Linear Arithmetic being obsolete for production purposes, it would be nice to overcome that legal tripwire once and for all.

System 20: PIII 600, LAPC-I, GUS PnP, S220, Voodoo3, SQ2500, R200, 3.0-Me
System 21: G2030 3.0, X-fi Fatal1ty, GTX 560, XP-Vista
Retro gaming (among other subjects): https://baronsfel001.wixsite.com/my-site

Reply 3 of 6, by Falcosoft

User metadata
Rank l33t
Rank
l33t
gfrh wrote on Yesterday, 01:42:

...
* There is optional General MIDI emulation.

Hi,
I have found in your description how you implemented this:

General MIDI Translation
When the input is General MIDI, use GmSynth to translate program changes, drum notes, and bank selects into CM-32L equivalents:

I do not think it's enough even for basic GM emulation.
1. The default Pitch Bend range for MT-32/CM-32 is 12 semitones. In case of GM the default is 2 semitones. This can be set by sending RPN(0,0) messages.
2. The default channel pan is reversed in GM compared to MT-32. That is you have to translate CC#10 messages to 127 - value to get GM compatible values (or use MUNT's built-in mt32emu_set_reversed_stereo_enabled() functionality).
3.The default channel/part layout (channels 2-10 are used) is not ideal for GM since channel 1 is almost always usedby GM files/titles. In Munt there is an option to switch between Channels 2-10 and Channels 1-8,10 layouts.

BTW, bank select is not defined in GM. Only GM2/GS/XG etc.systems use bank select MSB/LSB messages.

Website, Youtube
Falcosoft Soundfont Midi Player + Munt VSTi + BassMidi VSTi
VST Midi Driver Midi Mapper
x86 microarchitecture benchmark (MandelX)

Reply 4 of 6, by gfrh

User metadata
Rank Newbie
Rank
Newbie
BaronSFel001 wrote on Yesterday, 17:43:

Does this still require the Roland ROMs to work or has that functional ecosystem been reverse-engineered past that point? While Roland seems content to look the other way due to Linear Arithmetic being obsolete for production purposes, it would be nice to overcome that legal tripwire once and for all.

ROMs and derived data are not included in the code repo, or into builds by default.

I chose this conservative stance based on the previous recorded experiences of Roland emulator developers. In particular, I do not want to test whether or not the audio samples in the PCM ROM are protected by copyright, and possibly taint the repository with any proprietary copyrighted material.

I tried to make things as simple as possible for select opt-in users to embed ROMs and not worry about runtime loading.

For this, you must build the crates with the non-default bundle-rom option. There is a even a script to download the ROMs from an external source and put them in the correct location. I've just added docs to better explain this feature, and added an environment variable to override ROM location. Will be included in a 0.9.2 release.

Reply 5 of 6, by gfrh

User metadata
Rank Newbie
Rank
Newbie
Falcosoft wrote on Yesterday, 18:47:

Hi,
I have found in your description how you implemented this:

Thank you for sharing your insights!

Falcosoft wrote on Yesterday, 18:47:

I do not think it's enough even for basic GM emulation.
1. The default Pitch Bend range for MT-32/CM-32 is 12 semitones. In case of GM the default is 2 semitones. This can be set by sending RPN(0,0) messages.

This was already implemented in v0.9.1 by changing the range of all parts during initialization. It occurred to me though that this (as well as some other effects) would be cleared on device reset, so I have implemented a fix for that.

Falcosoft wrote on Yesterday, 18:47:

2. The default channel pan is reversed in GM compared to MT-32. That is you have to translate CC#10 messages to 127 - value to get GM compatible values (or use MUNT's built-in mt32emu_set_reversed_stereo_enabled() functionality).

Good point. I have implemented an emulation.

Falcosoft wrote on Yesterday, 18:47:

3.The default channel/part layout (channels 2-10 are used) is not ideal for GM since channel 1 is almost always usedby GM files/titles. In Munt there is an option to switch between Channels 2-10 and Channels 1-8,10 layouts.

Another good suggestion. I have now mapped the default parts to MIDI channels 1-8 and 10 for rhythm for GmSynth.

Falcosoft wrote on Yesterday, 18:47:

BTW, bank select is not defined in GM. Only GM2/GS/XG etc.systems use bank select MSB/LSB messages.

The GmSynth wrapper already filters out bank select messages in v0.9.1, but the README was incorrectly worded here. I've updated the relevant README to reflect the actual behavior. There may be better emulation to do here?

Thanks again for your observations. The above updates will be included in a v0.9.2 release.

Reply 6 of 6, by Falcosoft

User metadata
Rank l33t
Rank
l33t
gfrh wrote on Today, 05:49:

...
The GmSynth wrapper already filters out bank select messages in v0.9.1, but the README was incorrectly worded here. I've updated the relevant README to reflect the actual behavior. There may be better emulation to do here?

Thanks again for your observations. The above updates will be included in a v0.9.2 release.

Thanks for the updates!
I have just mentioned the bank select part to notify you that no emulation is necessary at all. Bank select messages are ignored by both GM and MT-32.
You do not even have to filter them out. Of course filtering does not hurt either.

Website, Youtube
Falcosoft Soundfont Midi Player + Munt VSTi + BassMidi VSTi
VST Midi Driver Midi Mapper
x86 microarchitecture benchmark (MandelX)