mamut-sint-sw is the canonical EPM1 software repo inside the broader
Mamut EPM program.
Canonical line split:
EPM1= current software/runtime line in this repomamut-sint-swEPM2= hardware line in sibling repomamut-sint-hw
Current product posture:
EPM1is the current primary playable expression ofMamut EPMEPM2is the hardware continuation of the same identityMamut EPMis the umbrella concept across both lines
This repo owns the live software/runtime implementation for EPM1:
- standalone runtime
- engine and DSP implementation
- patch runtime code and validation
- factory patch bank and playback ergonomics
Shared identity language stays aligned across both lines:
HorizontPecBakljaGravitacija
Program map and repo split:
docs/mamut-epm-program-map.md- sibling
EPM2hardware repo:mamut-sint-hw
Current status:
- Sprint 1 core workspace is implemented
- patch/schema/identity/engine contracts are live in code
- Sprint 2 standalone audio milestone is implemented
- Sprint 3 standalone hardening is implemented
- Sprint 4 playable productization is implemented
- transport-boundary hardening reached its local freeze point; the freeze was rescinded on 2026-07-06 by ADR 0005 for the MIDI 2.0 UMP track
- the MIDI 2.0 migration (UMP-first internal protocol, per-note
expressiveness deep in the engine/DSP) is planned in
docs/EPM1_BACKLOG_SET4_MIDI2_UMP_EXPRESSIVENESS.md - plugin/editor work is intentionally deferred
cargo test --lockedThis is the main public proof path for the repo today.
Workspace crates:
mamut-params- stable parameter and macro registrymamut-patch- canonical TOML patch model and validationmamut-identity- macro-to-identity resolutionmamut-dsp- shared DSP blocks and real-time utilitiesmamut-field- Rust-first offline GFM lattice model and render evidencemamut-engine- voice allocation, identity resolution, and audio render pathmamut-runtime- runtime-facing transport/session logic (ALSA playback, MIDI ingress, CLI)mamut-tui- ratatui/crossterm terminal UI (lib + headless/TUIplaybinary)mamut-standalone- standalone runtime with audio, MIDI, and demo performermamut-seq- laptop MIDI sequencer: virtual-port scenario player (default development-time input)
Quick start:
cargo test
cargo run -p mamut-standalone
cargo run -p mamut-standalone -- list-factory
cargo run -p mamut-standalone -- list-audio
cargo run -p mamut-standalone -- list-midi
tools/run-pc4-ag03.sh molten-horizon
tools/run-pc4-ag03.sh --midi-channel 2 molten-horizon
tools/run-pc4-ag03.sh --trace-midi molten-horizon
PC4GEN_ROOT=/path/to/pc4gen PC4GEN_PROFILE=/path/to/profile.json tools/run-pc4gen-consumer-smoke.sh --audio-device hw:<card>,<device>
cargo run -p mamut-standalone -- validate patches/factory/molten-horizon.toml
cargo run -p mamut-standalone -- dry-run patches/factory/furnace-choir.toml
cargo run -p mamut-standalone -- dry-run molten-horizon
cargo run -p mamut-standalone -- play --demo patches/factory/molten-horizon.toml
cargo run -p mamut-standalone -- play --audio-device hw:<card>,<device> cathedral-bloom
cargo run -p mamut-standalone -- play --audio-device 0 --midi-device 1 gravity-wake
cargo run -p mamut-standalone -- play --headless --audio-device hw:<card>,<device> molten-horizon
cargo run -p mamut-seq -- ports
cargo run -p mamut-seq -- validate scenarios/gfm-gate-arm.toml
cargo run -p mamut-seq -- play scenarios/gfm-gate-arm.toml
cargo run -p mamut-seq -- livemamut-seq is the default development-time MIDI source: instead of the physical
PC4 -> mioXM rig, generate MIDI on the laptop. It is a pure MIDI source over a
virtual ALSA port, so it changes nothing in the runtime. The stage path
(PC4 -> mioXM -> EPM1, see docs/EPM1_FIRST_PERFORMANCE_PLAYBOOK.md) is
unchanged, and mamut-seq runs are synthetic development evidence — real-rig
evidence in docs/live-sessions/ stays a separate, hardware-only class.
Two-terminal flow — Mamut in one terminal, mamut-seq in the other:
# terminal 1 - Mamut, selecting the mamut-seq port as input
cargo run -p mamut-standalone -- play \
--audio-device hw:<card>,<device> \
--midi-device mamut-seq --midi-channel 2 \
--controller-profile profiles/pc4-full.toml --trace-midi cathedral-bloom
# terminal 2 - mamut-seq, sending a scripted scenario
cargo run -p mamut-seq -- play scenarios/gfm-gate-arm.tomltools/run-seq-smoke.sh prints this quickstart (and, with --run --audio-device <selector>, drives it end-to-end). Scenarios live in scenarios/ and address
controls by profile name (never raw CC), resolved through profiles/pc4-full.toml.
mamut-seq validate <scenario> prints the expanded schedule without sending;
mamut-seq live is an interactive computer-keyboard mode for ad-hoc sound checks
(the keymap is shown in-app). Full design:
docs/EPM1_BACKLOG_SET3_LAPTOP_MIDI_SEQUENCER.md.
If you want the shortest product-facing smoke instead of the full test suite:
cargo run --locked -p mamut-standalone -- list-factoryRuntime notes:
playaccepts either a patch path or a factory patch name likemolten-horizonplayrequires--audio-deviceand accepts only an ALSA list index or an explicithw:<card>,<device>selectorplaydefaults to96 kHz; pass--sample-rate 44100for the older 44.1 kHz behavior or--sample-rate 192000for the later high-rate experiment path. Supported rates are44100,48000,88200,96000,176400, and192000.play --alsa-period-frames,--alsa-buffer-frames, and--alsa-start-threshold-framesexpose direct ALSA tuning for latency and underrun work- first 96 kHz AG03 live tests should start with
--alsa-period-frames 512,--alsa-buffer-frames 2048, and--alsa-start-threshold-frames 2048; that is about a 5.33 ms period and 21.33 ms buffer at 96 kHz. The same frame counts represent half as much wall-clock slack again at 192 kHz. play --midi-channel <1..16>filters input to one MIDI channel when a port carries extra trafficplay --controller-profile <path>loads TOML controller bindings such asprofiles/pc4-full.tomlplay --trace-midilogs incoming MIDI messages tostderrfor routing/debug sessions- MIDI trace and latest-control UI work run on a session-owned worker, not in
the MIDI callback;
statusand the GUI expose accepted, dropped, trace dropped, and coalesced-controller counters - MIDI
panicandreset_controllersbypass the normal runtime-control queue and use the priority action path directly - when a graphical session is available,
playopens a nativeeguiperformance window by default withLive,PC4, andDebugtabs - use
--headlessto force the terminal runtime surface instead of the performance window tools/run-pc4-ag03.shis the shortest launch path for the firstPC4 -> mioXM DIN 1 -> AG06/AG03standalone test and auto-resolves the Yamaha ALSAhw:output before launch; it loadsprofiles/pc4-full.tomlby defaulttools/run-pc4gen-consumer-smoke.shis the local live ALSA smoke forpc4gen -> Mamut, using themamut-epm1-smokegenerator scenario and--trace-midias the contract oracle; it is a lab integration helper and requires explicitPC4GEN_ROOTplus eitherPC4GEN_PROFILEorPC4GEN_DERIVED- headless controls include
status,patches,favorites,favorite,patch,next,prev,demo-patch,macro,panic,reset-controllers,audio,midi,demo, andquit list-factoryshows the curated factory bank with display names and descriptionsfavorites,favorite <slot>,next,prev, and MIDIprogram change 0..7all operate on the locked 8-slot live setlist-audioenumerates ALSAhw:playback devices;list-midienumerates MIDI inputs by index- if no MIDI input is available, or
--demois passed, a built-in demo performer drives the synth - switching audio from the runtime surface restarts the live session and resets current held notes and live macro state
- switching patches during active play performs a clean voice/controller reset before the new patch becomes active
PC4full profile MIDI mapping lives inprofiles/pc4-full.toml; it coversK1..K9,S1..S9,SW1..SW9, notes, pitch bend,CC1mod wheel,CC64sustain, channel aftertouch, andprogram change 0..7- the windowed
PC4tab is read-only: it displays Mamut's internal synth state for incoming PC4 controls and does not send MIDI or synth parameter changes back from GUI clicks/drags - without
--controller-profile, the legacy fallback keepsCC16..20mapped toGravitacija,Bloom,Heat,Ruin, andSwarm - controller-profile binding
kinds:macro,direct_param,gfm_layer_amount,bcs_layer_amount/bcs_layer_gain,bcs_layer_enabled,mozaik_control,runtime_action,toggle_param,reserved mozaik_control(SET5-8) binds a CC to a Mozaik session control viatarget = "mix" | "slope" | "contrast" | "phason" | "drift"; the CC value maps linearly0..127 -> 0.0..1.0and routes through the sameEngineCommand::SetMozaikParampath as the headlessmozaik set(one truth for clamping, smoothing, and the slope detent-snap). Nomozaik_controlbinding enables, disables, or re-seeds the Mozaik layer — enable stays a deliberate--mozaik/mozaik onact, so a stray CC cannot restart a running texture (unlikebcs_layer_enabled, which does gate the BCS layer from a CC)profiles/android-touch.tomlis the example channel-1 surface for the PC4MS Android touch instrument (sibling repopc4-microkit-studio,docs/PC4MS-TOUCH-SURFACE-BACKLOG.mditemsTS-1..3): macrosCC16..20, expressionCC11, and Mozaik on the app'sProfile CC 21-31slide-lane band
Factory bank:
molten-horizon- open mass with late rupturefurnace-choir- densePec-centered poly bodyrazor-thaw-Baklja-ready leadcathedral-bloom- stable wideHorizontpadember-vault- dry playablePecbassgravity-wake- performance arc aroundGravitacijagranite-plain- dry poly anchor with restrained bodyglass-tide- wide animated pad aroundBloomandSwarm
Live set slots:
0-molten-horizon1-cathedral-bloom2-ember-vault3-razor-thaw4-gravity-wake5-furnace-choir6-granite-plain7-glass-tide
docs/mamut-epm-program-map.md- umbrella map forMamut EPM,EPM1, andEPM2docs/README.md- localEPM1doc ownership and cross-repo referencesdocs/EPM1_TRANSPORT_FREEZE.md- rescinded transport freeze (see ADR 0005); preserved for historydocs/EPM1_BACKLOG_SET4_MIDI2_UMP_EXPRESSIVENESS.md- MIDI 2.0 UMP migration backlog (SET4-0..12;SET4-9..12is the Android touch-surface track — native UMP over a UDP link)docs/EPM1_SPRINT_6_PC4_PERFORMANCE_RIG.md- Sprint 6 plan forPC4live rig, performance flow, and live UIdocs/EPM1_SPRINT_6A_HOST_UNDERRUN_STABILITY.md- next work item for real-host underrun diagnosis and stability tuningdocs/EPM1_PC4_LIVE_PROFILE.md- locked Sprint 6PC4mapping, patch-switch, and controller policydocs/EPM1_FIRST_PERFORMANCE_PLAYBOOK.md- practical first-performance startup, smoke-pass, and live fallback runbookdocs/factory-bank-listening-checklist.md- locked roles and listening pass for the shipped bank- shared
mamut-platformdocs - Linux audio platform thesis, boundary, open questions, and ADR track
Strict seL4 review disciplines are vendored in:
.claude/agents/
The claude directory name is historical. These are development-time review
prompts, not runtime dependencies, and Codex agents in this repo should apply
the same disciplines when the task matches them.
Repo-local workflow docs and helpers:
docs/review-gates.mdtools/review/run-rust-file-review.shtools/review/run-rust-subsystem-review.shtools/review/run-integrated-review.shtools/review/run-rust-hotpath-review.sh
Mandatory gates for core runtime work:
sel4-rust-systems-reviewerformamut-engine,mamut-dsp,mamut-standalone,mamut-patchsel4-rust-execution-optimizerfor hot-path audio/runtime changessel4-integrated-systems-reviewerfor architecture, docs, schema, and boundary shifts
- plugin/editor work is intentionally deferred
- the strongest current proof path is the standalone runtime, not a plugin host
- real hardware performance validation still depends on the
PC4-specific live profile and operator playbook
See DEVELOPMENT.md for the canonical smoke path and runtime-facing sanity checks.