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