Expand description
Roland CM-32L synthesizer emulator.
Renders 32kHz stereo PCM audio from MIDI input. Based on Munt, with no external dependencies.
The CM-32L is in the MT-32 family of synthesizers. This hardware predates General MIDI, but many early 1990s PC games directly support these synths.
§Quick start
use moont::{CM32L, Frame, Rom, Synth};
let control = std::fs::read("CM32L_CONTROL.ROM").unwrap();
let pcm = std::fs::read("CM32L_PCM.ROM").unwrap();
let rom = Rom::new(&control, &pcm).expect("invalid ROM");
let mut synth = CM32L::new(rom);
// Note On: channel 1, middle C, max velocity.
synth.play_msg(0x7f3c91);
// Render 1 second of audio at 32 kHz.
let mut buf = vec![Frame(0, 0); 32000];
synth.render(&mut buf);
// Note Off.
synth.play_msg(0x3c81);§Loading ROMs
The CM-32L ROMs are not distributed with this crate. Load them at
runtime with Rom::new:
let control = std::fs::read("CM32L_CONTROL.ROM").unwrap();
let pcm = std::fs::read("CM32L_PCM.ROM").unwrap();
let rom = Rom::new(&control, &pcm).expect("invalid ROM");With the bundle-rom feature, ROMs are parsed at compile time and
embedded in the binary, enabling [Rom::bundled()]. Place
CM32L_CONTROL.ROM and CM32L_PCM.ROM in rom/ inside the crate
directory, or set the MOONT_ROM_DIR environment variable:
let rom = Rom::bundled();§General MIDI translation
The CM-32L uses its own instrument map. When the input is General MIDI,
use GmSynth to translate program changes, drum notes, and pan
direction into CM-32L equivalents. GM defaults are automatically
reapplied after any device reset:
use moont::{GmSynth, Rom, Synth};
let control = std::fs::read("CM32L_CONTROL.ROM").unwrap();
let pcm = std::fs::read("CM32L_PCM.ROM").unwrap();
let mut synth = GmSynth::new(Rom::new(&control, &pcm).unwrap());
synth.play_msg(0x7f3c91);§Type-safe MIDI messages
The midi::Message type provides validated message construction as
an alternative to raw u32 values:
use moont::midi::Message;
let msg = Message::note_on(60, 100, 0).unwrap();
let packed: u32 = msg.try_into().unwrap();§Features
| Feature | Description |
|---|---|
bundle-rom | Embed pre-parsed ROMs in the binary (enables Rom::bundled()) |
tracing | Emit tracing spans and events |
§Related crates
| Crate | Description |
|---|---|
moont-render | Render .mid files to .wav |
moont-live | Real-time ALSA MIDI sink |
moont-web | WebAssembly wrapper with Web Audio API |
Re-exports§
Modules§
- gm
- General MIDI to CM-32L translation.
- midi
- MIDI message types, instrument enums, and conversions.
- param
- Shared parameter types for instrument timbres, patches, and rhythm keys.
- rom
- ROM parsing, structures, and PCM sample processing.
- smf
- Minimal Standard MIDI File (SMF) parser.
Structs§
- CM32L
- CM-32L synthesizer state.
- Frame
- Stereo PCM audio frame of two (left, right) 16-bit little-endian samples.
Enums§
- Control
Command - High-level runtime control commands for a synth instance.
- Control
Error - Error applying
ControlCommand.
Constants§
- SAMPLE_
RATE - Audio frames (stereo samples) per second.
Traits§
- Synth
- Interface for MIDI synthesizers.