Golden Pulse
deep house · 120 BPM · A dorian
Score 90
v0.2.0 Open source, MIT licence. macOS and Linux, with Windows in preview.
claudius picks sounds, writes the parts with music theory, arranges them into a song, mixes and masters it, then listens to the result with a critic and revises it. Every sound is real audio, synthesized in code or recorded from sampled instruments. There is no neural audio generation and no General MIDI.
curl -fsSL https://github.com/devlato/claudius/releases/latest/download/install.sh | sh
irm https://github.com/devlato/claudius/releases/latest/download/install.ps1 | iex
Score 90
Golden Pulse deep house · 120 BPM · A dorian
01Listen
Each one is cut to about 40 seconds around its drop or groove. One came out of evolution and three from scripts. Next to each is what made it and what claudius printed, including the critic’s verdict.
deep house · 120 BPM · A dorian
Score 90
One command. It generated four deep house songs, then bred them for four generations of eight children each. Every child was auditioned on its build-up and first drop, and the four the critic liked best became the next parents. --no-library keeps Apple Loops and your own samples out; the sample packs still play.
Command
claudius evolve --genre deep_house --seed 5 --generations 4 --no-library
What it printed (… marks lines left out)
evolving deep_house (4 start, 4 generations x 8 children, 32-bar previews, with ears)
g0-0 86.1 Hollow Harbor
g0-1 80.0 Paper Haze
g0-2 85.0 Glass Garden
g0-3 85.9 Golden Pulse
+ g1-0 87.0 from g0-3: shaker: synth voice parameter 8 -> 0.079; mix: perc +2.4 dB (now +2.4)
+ g1-1 86.7 from g0-2: form: intro gets fills; drums: played on the tr808 kit
+ g1-2 86.3 from g0-3: harmony A: chord 2: IV7 -> IV (plain triad)
g1-3 84.9 from g0-2: harmony A: swapped chords 3 and 4; mix: pad sidechain depth 0.49
g1-4 85.3 from g0-0: drums: new clap pattern; mix: hat +1.9 dB (now +1.9)
g1-5 79.2 from g0-0: crossover: drums and form of one parent, harmony and parts of the other; mix: pad +1.6 dB (now +1.6)
+ g1-6 86.7 from g0-3: swing 0.55 -> 0.53; chords (keys): drive 0.4 dB
+ g1-7 86.1 from g0-0: crossover: drums of one parent, everything else of the other; pad (warm_pad): release 2.59 s; form: drop now 24 bars
generation 1: best 87.0
…
generation 4: best 90.1
searched 36 candidates in 76 s; rendering the best 3 in full
#1 g4-1 (Golden Pulse): preview 90.1, full song 89.7
swing 0.55 -> 0.53
chords (keys): drive 0.4 dB
pad: rewrote the part
drums: played on the muldjord kit
crossover: drums of one parent, everything else of the other
kick: synth voice parameter 3 -> 0.447
form: break now 24 bars
crossover: drums and form of one parent, harmony and parts of the other
mix: hat -3.0 dB (now -3.0)
Golden Pulse — deep_house at 120 BPM in A dorian, 112 bars (3:44)
progression A: i9 IV7
progression B: i IV7
form: intro 16 | groove 16 | break 24 | build 8 | drop 32 | outro 16
tracks: kick (synth kick), clap (sampled cp (tr808:cp)), hat (sampled hh (tr808:hh)), shaker (synth shaker), perc (sampled rim (tr808:rim)), bass (synth patch 'sub_bass'), chords (synth patch 'keys'), pad (sampled string_ensemble (vsco2:strings)), lead (sampled rhodes (jrhodes:rhodes)), crash (synth crash), riser (synth riser)
master: -11.0 LUFS, true peak -1.0 dBTP (pre-master -10.3 LUFS)
ears: 'house music' z +3.8 (closest confusion 'techno music' +3.1); production z +1.5 vs 'a low quality recording with hiss' +1.1; p_real 0.71
sounds like: house music, tech house music, drum and bass music, techno music
verdict: 90/100 (arc 0.92, genre 0.93, mix 0.95, production 0.59, theory 1.00). Fix first: dull 4-8 kHz: hats, claps and snare lack bite (presence -28.6 dB, healthy from -26); production reads close to 'a low quality recording with hiss' (z +1.1) vs professionally mixed (z +1.5)
wrote out/evolve-deep_house-5/1-g4-1-golden-pulse/song.mp3
The winner, printed as a script
// Golden Pulse — deep_house (seed 8)
// song("deep_house", 8); // uncomment to start over from the generator
title("Golden Pulse"); tempo(120); key("A dorian"); swing(0.53493524);
humanize(0.35);
prog("A", "i9 IV7");
prog("B", "i IV7");
// drums: X accent, x hit, o ghost, . rest, | bar line; 16 steps per bar unless a number follows
drum("kick", "main", "X...X...X...X...");
drum("kick", "sparse", "X...X...X...X...");
drum("clap", "main", "....X.......X...");
drum("hat", "main", "x.xxx.x..xxxx.x.|x.xxx.x..xxxx.x.|x.xxx.x..xxxx.x.|..xx.xx...xxxxxx");
drum("hat", "sparse", "..x...x...x...xx");
drum("shaker", "main", "o.o.o.ooo.ooo.o.");
drum("perc", "main", "x.x..x.x.x..x.x.");
drum("perc", "sparse", "..x.....x....x..");
// parts written by the theory engine: change the style, preset, register, density or seed
part("bass", #{ style: "syncopated", preset: "sub_bass", register: [33, 50], density: 0.4658955, seed: 7593466037959292827 });
part("chords", #{ style: "stabs", preset: "keys", register: [53, 74], density: 0.43242535, seed: -1845194844081732826 });
part("pad", #{ style: "sustain", preset: "vsco2:strings", register: [50, 76], density: 0.403872, seed: 5506831138054929778 });
part("lead", #{ style: "motif", preset: "jrhodes:rhodes", register: [62, 84], density: 0.34817874, seed: -2367553514172308588 });
form([
sec("intro", 16, "kick hat shaker perc top").filter_in(),
sec("groove", 16, "kick clap hat shaker perc bass chords top"),
sec("break", 24, "pad chords lead shaker"),
sec("build", 8, "clap hat shaker chords lead pad").energy(0.55).prog("B"),
sec("drop", 32, "kick clap hat shaker perc bass chords lead pad top").energy(0.9),
sec("outro", 16, "kick hat shaker perc bass"),
]);
mix("clap", #{ reverb: 0.3 });
mix("hat", #{ level: -2.9886246, pan: 0.18 });
mix("shaker", #{ pan: -0.3 });
mix("perc", #{ level: 2.3582892, pan: 0.4, reverb: 0.1, delay: 0.2 });
mix("bass", #{ duck: 0.45 });
mix("chords", #{ reverb: 0.3, delay: 0.1, duck: 0.35 });
mix("pad", #{ reverb: 0.4, duck: 0.4 });
mix("lead", #{ reverb: 0.35, delay: 0.25, duck: 0.15 });
mix("fx", #{ level: -3, reverb: 0.3 });
lofi · 82 BPM · D minor
Score 94
A script with real instruments: a Rhodes, an upright bass, a vibraphone and a string section over a recorded kit. This is its third version; the revision log shows what the critic asked for each time.
Command
claudius script paper-lanterns.rhai
The script
// lofi in D minor at 82 BPM: a Rhodes, an upright bass, a vibraphone and strings over a recorded kit
blank("lofi"); title("Paper Lanterns"); tempo(82); key("D minor"); swing(0.6); humanize(0.35);
prog("A", "i9 iv9 VImaj7 V7"); bars_per_chord(1);
track("kick", s("bd ~ ~ ~ ~ ~ bd ~ ~ ~ bd ~ ~ ~ ~ ~").bank("uzu"));
track("snare", s("~ sd ~ sd").bank("acoustic").gain(0.8));
track("hats", s("hh*8").bank("acoustic").gain("0.9 0.55").degradeBy(0.1));
track("tamb", s("~ tambourine ~ tambourine").gain(0.5).pan(0.3));
track("keys", chord("prog").struct("x ~ ~ ~ ~ ~ x ~").voicing(53, 74).s("rhodes").room(0.3));
track("pad", chord("prog").voicing(57, 72).s("string_ensemble").level(-8));
track("bass", note("<[d2 ~ ~ a1 ~ ~ d2 ~] [g1 ~ ~ d2 ~ ~ g1 ~] [bb1 ~ ~ f2 ~ ~ bb1 ~] [a1 ~ ~ e2 ~ ~ a1 ~]>")
.s("upright_bass"));
let tune = "<[3 ~ 4 3 1 ~ 0 ~] [~ ~ 4 5 2 ~ 1 ~] [5 ~ 6 5 3 ~ 2 ~] [3 ~ ~ ~ 2 ~ ~ ~] "
+ "[3 ~ 4 3 1 ~ 0 ~] [~ ~ 4 5 2 ~ 1 ~] [6 ~ 7 6 5 ~ 3 ~] [2 ~ 3 ~ ~ ~ ~ ~]>";
track("vibes", n(tune).scale("D:minor:pentatonic").octave(4).s("vibes").delay(0.25));
form([sec("intro", 4, "keys pad"), sec("groove", 8, "kick snare hats keys bass"), sec("groove", 16, "*"),
sec("break", 8, "keys vibes pad").prog("A"), sec("groove", 16, "*"), sec("outro", 4, "keys pad")]);
What it printed
track kick: bd
track snare: sd
track hats: hh
track tamb: tambourine
track keys: rhodes
track pad: string_ensemble
track bass: upright_bass
track vibes: vibes
ears loaded in 12.9 s
Paper Lanterns — lofi at 82 BPM in D minor, 56 bars (2:44)
progression A: i9 iv9 VImaj7 V7
progression B: i9 IIsus4 VImaj9 v9
form: intro 4 | groove 8 | groove2 16 | break 8 | groove3 16 | outro 4
tracks: kick (sampled bd (uzu:bd)), snare (sampled sd (muldjord:sd)), hats (sampled hh (muldjord:hh)), tamb (sampled tambourine (vcsl:tambourine)), keys (sampled rhodes (jrhodes:rhodes)), pad (sampled string_ensemble (vsco2:strings)), bass (sampled upright_bass (doublebass:upright_bass)), vibes (sampled vibes (vcsl:vibraphone))
master: -12.5 LUFS, true peak -1.6 dBTP (pre-master -9.8 LUFS); done in 32.1 s
ears: 'lo-fi hip hop beat' z +3.8 (closest confusion 'hip hop beat with heavy bass' +3.0); production z +1.9 vs 'a low quality recording with hiss' +0.9; p_real 0.74
sounds like: lo-fi hip hop beat, hip hop beat with heavy bass, inspirational corporate background music, warm and cozy music
verdict: 94/100 (arc 0.91, genre 0.95, mix 1.00, production 0.76, theory 1.00)
wrote out/lofi-paper-lanterns-1/song.mp3
techno · 130 BPM · F minor
Score 88
A script: a real TR-909, a bass rolling between the kicks, an acid line, a chord stab and recorded congas. The excerpt starts four bars before the second drop, so you hear the beat of silence that .gap() leaves in front of it. The critic still hears a mix close to mono; that note stayed in.
Command
claudius script night-shift.rhai
The script
// techno in F minor at 130 BPM: a TR-909, a rolling bass between the kicks, an acid line and a chord stab
blank("techno"); title("Night Shift"); tempo(130); key("F minor");
prog("A", "i7"); bars_per_chord(1);
track("kick", s("bd*4").bank("tr909"));
track("clap", s("~ cp ~ cp").bank("tr909").room(0.25));
track("ohat", s("[~ oh]*4").bank("tr909").gain(0.7).pan(0.3));
track("hats", s("hh*16").bank("tr909").gain("0.6 0.3 0.45 0.3").pan(-0.3));
track("rim", s("~ ~ rim ~ ~ ~ rim ~ ~ rim ~ ~ ~ ~ rim ~").bank("tr909").gain(0.5).pan(0.5).delay(0.3));
track("congas", s("~ ~ conga ~ ~ conga ~ ~ ~ ~ conga ~ conga ~ ~ ~").gain(0.6).pan(-0.5).room(0.3));
track("bass", note("f1").struct("~ x x x ~ x x x ~ x x x ~ x x x").s("saw_bass").lpf(500).legato(0.6));
track("acid", note("<[f2 f2 f3 f2 ab2 f2 c3 f2 f2 eb3 f2 f2 c3 f2 bb2 eb3] [f2 f2 f3 f2 ab2 f2 c3 f2 f2 eb3 f2 ab2 c3 eb3 f3 c3]>")
.s("acid").role("lead").delay(0.15));
track("stab", chord("prog").struct("~ ~ ~ x ~ ~ x ~").voicing(55, 70).s("stab").room(0.4).delay(0.3));
track("strings", chord("prog").voicing(53, 72).s("string_ensemble").level(-9).room(0.5));
form([sec("intro", 8, "kick hats"), sec("groove", 16, "kick hats ohat congas bass clap"),
sec("build", 8, "kick hats ohat bass stab").build(), sec("drop", 16, "kick clap hats ohat rim congas bass stab"),
sec("break", 8, "stab acid strings").prog("A").gap(), sec("drop", 16, "*").impact(), sec("outro", 8, "kick hats congas")]);
What it printed
track kick: bd
track clap: cp
track ohat: oh
track hats: hh
track rim: rim
track congas: conga
track bass: saw_bass
track acid: acid
track stab: stab
track strings: string_ensemble
ears loaded in 7.6 s
Night Shift — techno at 130 BPM in F minor, 80 bars (2:28)
progression A: i7
progression B: i
form: intro 8 | groove 16 | build 8 | drop 16 | break 8 | drop2 16 | outro 8
tracks: kick (sampled bd (tr909:bd)), clap (sampled cp (tr909:cp)), ohat (sampled oh (tr909:oh)), hats (sampled hh (tr909:hh)), rim (sampled rim (tr909:rim)), congas (sampled conga (vcsl:congas)), bass (synth patch 'saw_bass'), acid (synth patch 'acid'), stab (synth patch 'stab'), strings (sampled string_ensemble (vsco2:strings)), crash (synth crash), riser (synth riser), impact (synth impact), downlifter (synth downlifter)
master: -8.9 LUFS, true peak -1.0 dBTP (pre-master -9.8 LUFS); done in 22.0 s
ears: 'techno music' z +4.4 (closest confusion 'drum and bass music' +3.1); production z +1.1 vs 'a low quality recording with hiss' +1.4; p_real 0.68
sounds like: techno music, a punchy kick drum pattern, drum and bass music, an uplifter sweep
verdict: 88/100 (arc 0.92, genre 1.00, mix 0.92, production 0.45, theory 1.00). Fix first: production reads close to 'a low quality recording with hiss' (z +1.4) vs professionally mixed (z +1.1); nearly mono (correlation 0.97): widen pads, chords and effects; dull 4-8 kHz: hats, claps and snare lack bite (presence -26.1 dB, healthy from -26)
wrote out/techno-night-shift-1/song.mp3
drum and bass · 174 BPM · C minor
Score 93
A script for liquid drum and bass: the Yamaha grand and a string section on a slow progression, a flute on top, and a two-step beat with a recorded snare, hats and ride, and ghost snares between the backbeats. The excerpt runs from the last four bars of the build into the drop.
Command
claudius script low-light.rhai
The script
// liquid drum and bass in C minor at 174 BPM: a grand piano, strings and a flute over a recorded kit
blank("dnb"); title("Low Light"); tempo(174); key("C minor");
prog("A", "i9 VImaj7 IIImaj7 VII"); bars_per_chord(2);
track("kick", s("bd ~ ~ ~ ~ ~ ~ ~ ~ ~ bd ~ ~ ~ ~ ~").bank("uzu"));
track("snare", s("~ ~ ~ ~ sd ~ ~ ~ ~ ~ ~ ~ sd ~ ~ ~").bank("acoustic"));
track("ghosts", s("~ ~ ~ ~ ~ ~ ~ sd ~ sd ~ ~ ~ ~ ~ sd").bank("acoustic").gain(0.35));
track("hats", s("hh*8").bank("acoustic").gain("0.8 0.5"));
track("ride", s("~ rd ~ rd").bank("acoustic").gain(0.4).pan(0.25));
track("bass", note("<c2 c2 ab1 ab1 eb2 eb2 bb1 bb1>").struct("x ~ ~ ~ ~ ~ x ~ ~ ~ x ~ ~ ~ ~ ~").s("sub_bass").legato(0.9));
track("piano", chord("prog").struct("x ~ ~ ~ ~ ~ ~ ~ ~ ~ x ~ ~ ~ ~ ~").voicing(55, 76).s("piano").room(0.35));
track("strings", chord("prog").voicing(53, 72).s("string_ensemble").level(-7).room(0.5));
let tune = "<[4 ~ ~ 2 4 ~ 6 ~] [7 ~ ~ ~ ~ ~ ~ ~] [2 ~ ~ 0 2 ~ 4 ~] [4 ~ ~ ~ ~ ~ 3 2] "
+ "[4 ~ ~ 2 4 ~ 8 ~] [6 ~ ~ ~ ~ ~ ~ ~] [3 ~ ~ 1 3 ~ 5 ~] [6 ~ ~ ~ ~ ~ ~ ~]>";
track("flute", n(tune).scale("C:minor").octave(5).s("flute").level(-4).room(0.4).delay(0.2));
form([sec("intro", 16, "piano strings").filter_in(), sec("build", 8, "piano strings hats ride kick").build(),
sec("drop", 32, "*").impact(), sec("break", 16, "piano strings flute").prog("A").gap(),
sec("drop", 32, "*").impact(), sec("outro", 8, "piano strings")]);
What it printed
track kick: bd
track snare: sd
track ghosts: sd
track hats: hh
track ride: rd
track bass: sub_bass
track piano: piano
track strings: string_ensemble
track flute: flute
ears loaded in 4.2 s
Low Light — dnb at 174 BPM in C minor, 112 bars (2:34)
progression A: i9 VImaj7 IIImaj7 VII
progression B: i7 IIIsus4 VII7 VImaj7
form: intro 16 | build 8 | drop 32 | break 16 | drop2 32 | outro 8
tracks: kick (sampled bd (uzu:bd)), snare (sampled sd (muldjord:sd)), ghosts (sampled sd (muldjord:sd)), hats (sampled hh (muldjord:hh)), ride (sampled rd (muldjord:rd)), bass (synth patch 'sub_bass'), piano (sampled piano (salamander:piano)), strings (sampled string_ensemble (vsco2:strings)), flute (sampled flute (vsco2:flute)), crash (synth crash), riser (synth riser), impact (synth impact), downlifter (synth downlifter), reverse_crash (synth reverse_crash)
master: -8.5 LUFS, true peak -1.0 dBTP (pre-master -8.5 LUFS); done in 23.9 s
ears: 'drum and bass music' z +3.1 (closest confusion 'house music' +2.3); production z +1.7 vs 'a low quality recording with hiss' +0.9; p_real 0.76
sounds like: jazz music, funk music, drum and bass music, a snare roll
verdict: 93/100 (arc 0.98, genre 0.85, mix 1.00, production 0.72, theory 1.00)
wrote out/dnb-low-light-1/song.mp3
02How it works
A song goes round this loop until the critic runs out of complaints or you stop it. Under each stage is what claudius printed while it made Paper Lanterns.
Music theory writes a blueprint, the song’s genome: tempo, key, chord progressions as Roman numerals, the form, drum patterns, melodic parts with a writing style, every sound and the mix. Scripts, mutations and the studio all edit the same blueprint.
Paper Lanterns — lofi at 82 BPM in D minor, 56 bars (2:44)
progression A: i9 iv9 VImaj7 V7
form: intro 4 | groove 8 | groove2 16 | break 8 | groove3 16 | outro 4
The blueprint is arranged like a DAW session, with fills at phrase ends, builds with a riser and a highpass sweep, and a beat of silence before the drop. Each track is balanced to its role’s loudness, ducked under the kick and sent to reverb and delay; the master lands on the genre’s loudness target.
master: -12.5 LUFS, true peak -1.6 dBTP (pre-master -9.8 LUFS); done in 32.1 s
The critic meters the master (loudness, tonal balance per band, stereo width, mono low end), checks the energy arc and the score (melody in key, chord tones on strong beats, bass on the roots), and listens with earshot, a CLAP audio model ported to Rust.
ears: 'lo-fi hip hop beat' z +3.8 (closest confusion 'hip hop beat with heavy bass' +3.0)
verdict: 94/100 (arc 0.91, genre 0.95, mix 1.00, production 0.76, theory 1.00)
Every issue names what to change. You change it in the studio or the script, an assistant changes it over MCP, or claudius evolve mutates the song and keeps the children the critic prefers.
Fix first: no air above 8 kHz: hats and cymbals too quiet or too dark (air -35.4 dB, healthy from -30)
Judged with meters and theory only (--no-ears), which takes seconds. Each line is the verdict as printed.
Version 186
verdict: 86/100 (arc 0.88, mix 0.81, theory 0.92). Fix first: no air above 8 kHz: hats and cymbals too quiet or too dark (air -35.4 dB, healthy from -30); low end not mono (correlation 0.85 below 150 Hz); only 25% of the lead's strong-beat notes are chord tones
Rewrote the vibraphone line so beats 1 and 3 land on chord tones, made it eight bars long, raised the hats, and moved the keys and strings up out of the low end.
Version 289
verdict: 89/100 (arc 0.89, mix 0.83, theory 1.00). Fix first: no air above 8 kHz: hats and cymbals too quiet or too dark (air -34.6 dB, healthy from -30); low end not mono (correlation 0.85 below 150 Hz); muddy 250 Hz-1 kHz: too much pad / chord body (lowmid -3.9 dB, healthy up to -4)
Three quick renders, each with one track muted, showed that the stereo low end came from the recorded kit’s kick, so the kick moved to the uzu kit. A tambourine on beats 2 and 4 added the missing air, and the chords now follow the song’s progression with chord("prog").
Version 397
verdict: 97/100 (arc 0.91, mix 1.00, theory 1.00)
No issues left. With the ears on, the same song scores 94: genre 0.95 for “lo-fi hip hop beat”, production 0.76.
The critic measures; it does not have taste. A high score means no measurable problems and a confident genre read, not a hit, so listen to finished songs yourself.
03Script
A claudius script is Rhai with mini-notation patterns borrowed from Strudel. One cycle of a pattern is one bar. This is all of Paper Lanterns:
// lofi in D minor at 82 BPM: a Rhodes, an upright bass, a vibraphone and strings over a recorded kit
blank("lofi"); title("Paper Lanterns"); tempo(82); key("D minor"); swing(0.6); humanize(0.35);
prog("A", "i9 iv9 VImaj7 V7"); bars_per_chord(1);
track("kick", s("bd ~ ~ ~ ~ ~ bd ~ ~ ~ bd ~ ~ ~ ~ ~").bank("uzu"));
track("snare", s("~ sd ~ sd").bank("acoustic").gain(0.8));
track("hats", s("hh*8").bank("acoustic").gain("0.9 0.55").degradeBy(0.1));
track("tamb", s("~ tambourine ~ tambourine").gain(0.5).pan(0.3));
track("keys", chord("prog").struct("x ~ ~ ~ ~ ~ x ~").voicing(53, 74).s("rhodes").room(0.3));
track("pad", chord("prog").voicing(57, 72).s("string_ensemble").level(-8));
track("bass", note("<[d2 ~ ~ a1 ~ ~ d2 ~] [g1 ~ ~ d2 ~ ~ g1 ~] [bb1 ~ ~ f2 ~ ~ bb1 ~] [a1 ~ ~ e2 ~ ~ a1 ~]>")
.s("upright_bass"));
let tune = "<[3 ~ 4 3 1 ~ 0 ~] [~ ~ 4 5 2 ~ 1 ~] [5 ~ 6 5 3 ~ 2 ~] [3 ~ ~ ~ 2 ~ ~ ~] "
+ "[3 ~ 4 3 1 ~ 0 ~] [~ ~ 4 5 2 ~ 1 ~] [6 ~ 7 6 5 ~ 3 ~] [2 ~ 3 ~ ~ ~ ~ ~]>";
track("vibes", n(tune).scale("D:minor:pentatonic").octave(4).s("vibes").delay(0.25));
form([sec("intro", 4, "keys pad"), sec("groove", 8, "kick snare hats keys bass"), sec("groove", 16, "*"),
sec("break", 8, "keys vibes pad").prog("A"), sec("groove", 16, "*"), sec("outro", 4, "keys pad")]);
s("bd ~ ~ ~ ~ ~ bd ~ ~ ~ bd ~ ~ ~ ~ ~")~ is a rest, hh*8 is eight hats in a bar..bank("acoustic").bank("uzu") takes the kick from another one.prog("A", "i9 iv9 VImaj7 V7")key() can move it. chord("prog") plays whichever chord the song is on, voice-led between MIDI notes 53 and 74.n(tune).scale("D:minor:pentatonic")< > plays one group per bar, so the tune is eight bars long.form([sec("intro", 4, "keys pad"), …])"*" is every track.# render it, judge it and write the song folder
claudius script paper-lanterns.rhai
# run a script on a saved song: it changes only what the script names
claudius script tweak.rhai --on out/lofi-paper-lanterns-1
# the whole language
claudius reference
Every song prints as a script: the studio’s script tab shows it, GET /api/script returns it, claudius script writes it to song.rhai beside the render, and --print prints it for a saved song. Running that script on the song changes nothing, so a script is also how you read a song. Golden Pulse came out of evolution, and its script was printed this way.
04Studio
claudius studio opens the native window. claudius serve serves the same app, compiled to WebAssembly, at http://127.0.0.1:7878. Both are clients of one session, so the window, a browser tab and an assistant can work on the same song at once. Every change renders and is judged in the background, a few seconds for a full song.
The demo runs the studio in your browser with a built-in mock in place of the engine. Every panel works; the audio is a rough preview synthesized in the page. For real renders, run claudius studio or claudius serve.
05Assistants
claudius is an MCP server. An assistant connected to it sees the song you have open, edits it with scripts, mutations, evolution or raw edits, renders and judges it, and you hear every change in the studio as it happens.
claude mcp add --scope user claudius -- claudius mcp
codex mcp add claudius -- claudius mcp
In Claude's settings, Developer, Edit Config opens claude_desktop_config.json. Add this and restart Claude, with the full path that which claudius prints.
{
"mcpServers": {
"claudius": {
"command": "/Users/you/.local/bin/claudius",
"args": ["mcp"]
}
}
}
Cursor asks before it adds it. Or put the same command and arguments in ~/.cursor/mcp.json:
{
"mcpServers": {
"claudius": { "command": "claudius", "args": ["mcp"] }
}
}
claudius connect claude-code (or claude-desktop, cursor, codex) does the same with the full path, and adds the skills that teach the assistant claudius; so does Connect an assistant, in the studio.
claudius mcp drives the studio when one is running on the port, so you and the assistant share the song. When none is running, it starts a session of its own and serves the web studio on the port, so you can still open it.
Clients that speak Streamable HTTP can use http://127.0.0.1:7878/mcp while the studio or claudius serve runs.
Assistants in the cloud need a public HTTPS address. Run claudius with a token behind a tunnel:
TOKEN=$(openssl rand -hex 16)
echo "$TOKEN"
claudius serve --public --token "$TOKEN"
cloudflared tunnel --url http://127.0.0.1:7878
Then add a custom connector in ChatGPT’s developer mode with the URL https://<tunnel>/mcp?token=<token>. The studio is at https://<tunnel>/?token=<token>.
The tools an assistant gets
new_songget_songrun_scriptscript_referencelistenmutateevolvestatusundoredostopcatalogsaveopenanalyzeremakecommandMake a deep house track at 122 BPM, listen to it, and fix the critic’s top two issues.
06Sounds
Notes exist only as the score that plays the sounds, like a piano roll. The sounds themselves are synthesized in code or recorded.
13 drum voices; a polyphonic and monophonic synth engine with polyBLEP oscillators, unison with analog drift, SVF and ladder filters, FM and glide, and 20 presets; risers, downlifters, impacts and reverse cymbals. claudius sounds renders every one of them to WAV.
14 sample packs with 162 instruments, multi-sampled with velocity layers and round robins, all under licences that allow making and publishing music with them. claudius-packs install --defaults downloads them, about 1.1 GB. Songs that use CC BY packs get a credits.txt.
| Pack | What it is | Licence |
|---|---|---|
salamander | Yamaha C5 grand piano, five velocity layers | CC BY 3.0 |
epianos | Wurlitzer EP200, Yamaha CP80, Hohner Pianet T | CC BY 3.0 |
jrhodes | 1977 Rhodes Mark I Stage 73 | free for making music |
vsco2 | Chamber orchestra: strings, brass, woodwinds, harp, timpani | CC0 |
vcsl | Mallets, pipe organ, tenor sax, harmonica, world and orchestral percussion | CC0 |
tr808 | Roland TR-808, sampled by Michael Fischer in 1994 | CC0 |
tr909 | Roland TR-909, with every accent level | free use, no redistribution |
tr707 | Roland TR-707 | public domain |
uzu | A small processed electronic kit made for Strudel | Unlicense |
muldjord | Acoustic rock kit with velocity layers | CC BY 4.0 |
freepats | Upright piano, FM piano, organ, bass guitars, classical and electric guitars, synths and pads | CC0 |
doublebass | 1958 double bass, pizzicato | CC0 |
growlybass | Fingered electric bass recorded direct | CC0 |
voice | A sung “a” vowel, and a five-voice choir built from it | CC0 |
When GarageBand or Logic content is installed, claudius uses it too, about 14,000 loops on a full install. Apple licenses these loops for your own music; claudius reads them where GarageBand put them and copies nothing except one-shot cuts in its cache. The songs on this page use none.
claudius chop cuts any recording into bar loops and drum one-shots for your library, make --sample flips a chop into a song, and scripts play any file with .s("/path/to/sound.wav").
07Install
The install scripts download the latest release, check it against the release’s SHA256SUMS, and put claudius, claudius-packs and the web studio in your user folder. Then they offer to fetch the sample library and the listening models.
curl -fsSL https://github.com/devlato/claudius/releases/latest/download/install.sh | shApple silicon and Intel Macs (Intel builds have no ears: their verdicts come from the meters and the theory checks); x86_64 and ARM64 Linux with glibc 2.38 or newer (Ubuntu 24.04, Debian 13, Fedora 39 and later). Without ALSA you get the headless build, which serves the studio to your browser. The commands go to ~/.local/bin.
irm https://github.com/devlato/claudius/releases/latest/download/install.ps1 | iexIn PowerShell. An x64 build, which also runs on ARM64 Windows; it is newer and less tested than the others, so please report what breaks. The commands go to %LOCALAPPDATA%\Programs\claudius\bin, which the script adds to your PATH.
With a Rust toolchain, in a clone of the repository:
cargo install --path crates/claudius-cli # the claudius command
cargo install --path crates/claudius-packs # the claudius-packs command
(cd crates/claudius-ui && NO_COLOR=true trunk build --release) # the web studio (optional; needs trunk)
claudius setup # the sample packs (about 1.1 GB) and the listening models (about 0.8 GB)
claudius doctor # checks the installation: studio, packs, models, ffmpeg, the port
claudius make --genre house # a full song in out/house-<title>-<seed>/
claudius studio # the studio window, with the engine inside
Without the models, --no-ears judges with meters and theory only. Once they are downloaded, they load in about 4 seconds.