Rhythm generation in modern DAWs is often relegated to simple piano rolls or standard 16-step grid sequencers. While these tools are reliable, they rarely inspire the kind of complex, evolving polyrhythms found in generative hardware or modular synthesizers.
At OMNi, we wanted to build a rhythmic composition environment that forces you to think differently about beats. We didn't want just another arpeggiator; we wanted an engine that calculates rhythm mathematically and evolves over time without manual plotting.
Meet Euclidean Pro—our 8-channel polyrhythmic collider.
Here is a deep dive into how we designed it, its core functionalities, and why executing this vision in real-time required the raw power and safety of the Rust programming language.
The Anatomy of Euclidean Pro
Euclidean Pro is built around an interactive, 8-ring circular display. Each ring represents an independent channel (e.g., Kick, Snare, Hi-hat), and instead of placing notes on a grid, you define mathematical rules:
- Steps, Pulses, and Offset: Distribute X pulses evenly across Y steps. By assigning a 7-step pattern to the hi-hats and a 16-step pattern to the kick drum, they continuously phase against each other, generating unpredictable grooves.
- Elektron-Style Step Conditions: We implemented 12 distinct pulse modifiers per step. By right-clicking any ring, you can assign probabilities (Coin), Ratchets, micro-nudges, or logical conditions (Pre, NotPre, First, 1:2, 2:2). This ensures your loops never sound exactly the same twice.
- Boolean Logic Between Channels: Rhythms can interact. Applying an AND-NOT condition between the kick and the snare guarantees they never hit at the same time, instantly creating organic space in your mix without manual micro-editing.
- Morph Banks: Each channel holds four pattern slots (A/B/C/D). You can seamlessly morph between entirely different Euclidean formulas in real-time.
The Engineering Behind the Math
Rendering an 8-layer, interactive circular UI that calculates Boolean logic and probabilistic step modifiers in real-time—while driving a high-performance audio engine—is a massive technical hurdle. Here is how Rust's architecture made it possible.
1. Immediate Mode GUI (egui) Meets Zero-Latency Audio
In traditional DAWs built with C++, rendering complex vector graphics (like 8 concentric rings with independent modulation indicators) often requires heavy UI frameworks that can stall the main thread. In OMNi, we use egui, an immediate-mode GUI framework written in Rust.
Because there is no retained DOM or complex widget hierarchy, Euclidean Pro recalculates and draws the entire circular UI from scratch every single frame at 60+ FPS. Modulating the "Global Rotate" parameter with your mouse instantly shifts offsets across all 8 channels with zero UI lag.
2. Lock-Free Communication
When you press keys 1-8 to audition a channel's sound, the UI must instruct the audio engine to play a note immediately. A standard mutex lock could cause a priority inversion, resulting in an audio dropout.
Rust's ecosystem provides crossbeam_channel. We use lock-free, concurrent queues (sender.try_send(EngineCommand::NotePreview)) to stream commands from the UI thread directly to the DSP pipeline. The audio thread never waits, ensuring absolute stability.
3. Pattern Matching Exhaustiveness
Euclidean Pro features a massive array of per-step modifiers (Pitch, Velocity, Probability, Tie, Slide, StepCond, etc.). In C++, adding a new modifier often leads to bugs where the UI or the playback engine "forgets" to handle the new state.
Rust's strong enums (EuclideanPulseModifier) and exhaustive pattern matching force the compiler to check every single case. If we add a new "Glitch" modifier to the core logic, the code literally will not compile until the UI dropdowns, the randomizer shortcuts (Ctrl+R), and the MIDI generation algorithms are explicitly updated to support it. This results in "Zero-Bug" design.
4. Lightweight Randomization
Generative sequencers live and die by their Random Number Generators (RNG). Features like "Randomize active modifier lane" need to update 64 steps across 8 channels instantly. By utilizing the fastrand crate, Euclidean Pro executes thousands of PRNG calculations in microseconds. Because Rust provides zero-cost abstractions, modifying the underlying vectors (step_pitch_mod, step_gate_mod) directly is incredibly cheap on the CPU.
From Math to MIDI
Euclidean Pro isn't a closed ecosystem. Once your generative pattern mutates into something perfectly balanced, a single click on Bake to MIDI compiles the mathematical conditions and writes hard, editable MIDI notes directly to OMNi's Piano Roll. You get the best of both worlds: infinite generative exploration, and precise manual editing.
Euclidean Pro is fully integrated into OMNi. It’s time to stop drawing notes and start programming rhythm.
