Device Details


Overview

Name | Version: Kasm Rust Ableton WASM - Source Code 1.12.3
Author: kevleyski
Device Type: MIDI Effect
Description: Use Rust code to manipulate Ableton Live note data, create intersting MIDI transformations and generators with interactive visuals!

Some ideas of what you might do with the Kasm Rust SDK in Ableton Live...

You might perhaps create some really cool looking VST wrappers for your 3rd party plugins

You might hook into WebXR and use AR to control virtual instruments that really are virtual

Or maybe create some new an interesting smarter X/Y controllers with visual feedback, rather than the blank one Ableton gives you

Triggaz is an example of listening to your live perfromance for known triggers, these can be knob twiddles in a certain sequence for example and it keeps looping them

You might hook Triggaz to include pitchdetection (or maybe Guitar2MIDI or autotune vst) trigger live performance events on the mixing desk, lighting effects etc

MIDI tape loops plays back the last half bar you played into it over and over applying super fast Rust compiled algorithms that introduce fade and counterpoint harmony

Bangaz is example of hitting a drum rack in intersting algorithmic ways in Rust code, which can incorporate all the above, e.g. when I play the drum like this do this

The Kasm Rust SDK is more a tutorial pack, example Max4Live devices including how to hook into Ableton MIDI Generator + MIDI Transformation with all source code and build scripts and even a WebMIDI test harness to hear your Rust code as it would work in Ableton in Chrome/Firefox

Kasm is WebAssembly so you can develop and test things in web browser too, try it out here:
https://pyrmontbrewery.com/kasm

Instant feedback loops - test harmonic analysis algorithms, chord detection systems, or algorithmic composition engines outside of the Max editor

Visual debugging capabilities - leverage web browser DevTools and IDEs for performance profiling, memory analysis, and execution tracing (tools unavailable in traditional Max4Live development)

Working examples of how to manipulate MIDI data using the most efficient Rust code in Ableton Live 12.2 w/ Max4Live using WebAssembly in the newly added V8 Javascript engine

Features includes:
Passing inlet parameters from JS into to Rust
Rust code calling Max4Live outlet function (Rust code plays chords offset by semitones passed in from Max4Live)
Max console debug post() messages from inside Rust code
Web browser test harness - run and test your Ableton Live WebAssembly in Chrome/Firefox
Monitoring for musical key changes and chord progressions
Detect musical patterns in live perfromances and use these to trigger Ableton Live and 3rd party plugins however you feel
Live looping MIDI with countepoint harmonising
Drum machine / step sequencing


Some examples of MIDI triggering from Rust code:

Emanator Algo #1 playing u-he Diva (HS Hippie Chimes patch)
https://soundcloud.com/kevleyski/kasm-emanator-with-diva

Emanator Algo #2 playing Kontak Stradivari “Vesuvius” Violin
https://soundcloud.com/kevleyski/kasm-emanator-algorithm-2-with

Emanator Algo #13 playing VSL Synchron Bösendorfer Imperial
https://soundcloud.com/kevleyski/kasm-emanator-rust-algorithm-13-piano

Bangaz #40 playing KORG M1 VST (this is via WebMIDI but its identical from Max4Live)
https://soundcloud.com/kevleyski/kasm-bangaz-40


How does it work, what does "Kasm" do for me? There are three primary layers working together to enable Rust execution within Max4Live/V8:

Rust Code Layer: Your MIDI/Audio DSP logic compiled as WebAssembly
JavaScript Bridge Layer: Handles WASM bytecode loading, setups parameter marshalling for Max4Live integration
Max4Live Layer: V8 JavaScript engine with an basic example .amxd device showing two way communication with Rust

Kasm then provides the base64-encoded WASM binary parts and compiles this as a blob for integration:

Base64 Decoding: Custom atob() implementation for Max4Live
WASM Compilation: Direct compilation from that decoded binary
Function Export: Cahing mapped Rust functions available to JavaScript
getStringFromWasm: Convert WASM memory strings into JavaScript strings

!! note for this to all work this project needs Ableton 12.2 or later as it utilises the new V8 engine, you'll need Live 12.2 Suite or Standard + Max4Live add-in !!


Building and updating it is easy:
npm install
npm run build

This updates kasm_WASM_rust.js which then compiles the WASM, you simply copy and paste that into any 'v8' Max4Live object



Rust code source structure and some sample code...

|____emanators
| |____spatial.rs
| |____melodic.rs
| |____loopcounterpoint.rs
| |____experimental.rs
| |____responsorial.rs
| |____mod.rs
| |____mathematical.rs
| |____harmonic.rs
| |____drumpattern.rs
| |____rhythmic.rs
| |____progressions.rs
|
|____kasm_arpeggiator.rs
|____lib.rs
|____kasm_looper.rs
|____kasm_drummer.rs
|____kasm.rs
|____kasm_triggaz.rs
|____max4live_ui_mapping.rs
|____kasm_emanator.rs
|____kasm_krumhansl.rs




pub fn rhythmic_morse_code(
note: i32,
offset: i32,
velocity: i32,
enc1_velocity_offset: i32,
enc2_intensity: i32,
_time_step: i32,
_time_bar: i32,
) -> i32 {
let root_note = (note + offset).max(0).min(127);
let base_velocity = (velocity + (enc1_velocity_offset / 10)).max(30).min(127);
let intensity_factor = enc2_intensity.max(1).min(127) as f32 / 32.0;

// Morse code patterns for different notes
let morse_alphabet = [
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---",
"-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-", "-.--", "--..",
];

let morse_index = ((root_note + enc1_velocity_offset) as usize) % morse_alphabet.len();
let morse_pattern = morse_alphabet[morse_index];

let dot_duration = (120.0 * intensity_factor) as i32;
let dash_duration = (360.0 * intensity_factor) as i32;
let element_gap = (120.0 * intensity_factor) as i32;

let mut current_delay = 0;
let total_elements = morse_pattern.len();

for (i, morse_char) in morse_pattern.chars().enumerate() {
let pan_angle = (i as f32 / total_elements as f32) * 2.0 * std::f32::consts::PI;
let pan_position = ((pan_angle.cos() + 1.0) * 63.5) as i32;

let (duration, pitch_offset) = match morse_char {
'.' => (dot_duration, 0),
'-' => (dash_duration, 12),
_ => continue,
};

let morse_note = (root_note + pitch_offset).max(0).min(127);
let morse_velocity = (base_velocity as f32 * (0.8 + 0.4 * intensity_factor)) as i32;

send_note(
morse_note,
morse_velocity.max(30).min(127),
current_delay,
duration,
pan_position,
);

current_delay += duration + element_gap;
}

root_note
}


pub fn spatial_3d_positioning(
note: i32,
offset: i32,
velocity: i32,
x_movement: i32,
y_movement: i32,
_time_step: i32,
_time_bar: i32,
) -> i32 {
let root_note = (note + offset).max(0).min(127);
let x_factor = x_movement.max(0).min(127) as f64 / 127.0;
let y_factor = y_movement.max(0).min(127) as f64 / 127.0;

let num_positions = 12;
let position_duration = 300;

for pos in 0..num_positions {
let t = pos as f64 / num_positions as f64;

// Simulate 3D movement
let x = (t * 2.0 * std::f64::consts::PI * x_factor).sin();
let y = (t * 2.0 * std::f64::consts::PI * y_factor).cos();
let z = (t * std::f64::consts::PI).sin(); // Height simulation

// Convert 3D position to stereo pan
let pan_position = ((x + 1.0) / 2.0 * 127.0) as i32;

// Simulate distance with velocity and filter
let distance = (x * x + y * y + z * z).sqrt();
let distance_factor = (2.0 - distance).max(0.1).min(2.0);
let pos_velocity = (velocity as f64 * distance_factor * 0.7) as i32;

// Height affects pitch
let pitch_offset = (z * 12.0) as i32;
let spatial_note = (root_note + pitch_offset).max(0).min(127);

let delay = pos * position_duration;
let duration = (position_duration as f64 * distance_factor) as i32;

send_note(
spatial_note,
pos_velocity.max(20).min(127),
delay,
duration,
pan_position,
);

// Add filter automation based on distance
let filter_value = (40.0 + distance_factor * 60.0) as i32;
send_cc(74, filter_value.max(20).min(127), delay);
}

root_note
}


pub fn experimental_multidimensional_markov(
note: i32,
offset: i32,
velocity: i32,
enc1_intensity: i32,
enc2_complexity: i32,
_time_step: i32,
_time_bar: i32,
) -> i32 {
let root_note = (note + offset).max(0).min(127);
let intensity_factor = (enc1_intensity.max(50).min(127) as f64 + 50.0) / 127.0;
let complexity_factor = (enc2_complexity.max(40).min(127) as f64 + 40.0) / 127.0;

let pitch_classes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 19, 21, 24];
let rhythm_classes = [300, 350, 400, 450, 500, 600, 750];
let harmonic_contexts = ["major", "minor", "diminished", "augmented", "sus4", "sus2"];

let sequence_length = (20.0 + complexity_factor * 16.0) as usize;

let mut pitch_state = 0;
let mut rhythm_state = 2;
let harmonic_state = 0;
let mut phrase_position = 0;

for step in 0..sequence_length {
let pitch_transition_weights = match harmonic_contexts[harmonic_state] {
"major" => [0.2, 0.05, 0.15, 0.05, 0.15, 0.1, 0.05, 0.15, 0.05, 0.03, 0.02, 0.02, 0.08, 0.05, 0.03, 0.01, 0.01, 0.01, 0.02],
"minor" => [0.15, 0.05, 0.1, 0.15, 0.1, 0.15, 0.05, 0.1, 0.05, 0.05, 0.03, 0.02, 0.08, 0.05, 0.03, 0.01, 0.01, 0.01, 0.02],
_ => [0.05; 19],
};





All this source code you need to build Rust/WebAssembly Max4Live device plugins is in here: (only $29 and students get 30% discount)

https://buymeacoffee.com/kasm/e/426168

https://kevleyski.gumroad.com/l/kasm_ableton_wasm_rust

Details

Live Version Used: 12.2
Max Version Used: 9.0
Date Added: Jun 26 2025 03:33:25
Date Last Updated: Aug 07 2025 04:01:48
Downloads: 0
Website: https://kevleyski.gumroad.com/l/kasm_ableton_wasm_rust
License: Commercial
Average Rating

Log in to rate this device

-n/a-



Login to comment on this device.

Browse the full library