cutoff 130
reverb 0.30

MIDI

Not connected

Samples

No folders

Preferences

Theme

Scope

Colour

Debug

Reference

1 — Welcome

Welcome to Sonic Tau — a live-coding audio playground. The language is heavily inspired by Sonic Pi. Write code, hit Run, and hear it instantly. Modify code while it plays and hear changes in real-time.

This tutorial is adapted from the Sonic Pi tutorial by Sam Aaron. It’s divided into sections — feel free to dip in and out.

1.1 Live Coding

One of the most exciting aspects is that you can write and modify code live to make music, just like performing with a guitar. Let’s start with a beat:

4.times do
  sample :bd_haus, rate: 1
  sleep 0.5
end

Press Run and you’ll hear a bass drum. Try changing sleep 0.5 to sleep 1 and hit Run again — the speed changes. That’s live coding!

Try layering sounds together:

4.times do
  sample :ambi_choir, rate: 0.3
  sample :bd_haus, rate: 1
  sleep 1
end

Play around — change rates, use negative values, try tiny sleep times. Comment out lines with # to remove them from the mix.

1.2 Learning through Play

There are no mistakes, only opportunities. No matter how experienced you are, unexpected outcomes happen. Take the sound, manipulate it and morph it into something awesome.

Start simple. Think of the simplest thing that would be fun, build it, play with it, and let new ideas emerge.

2 — Synths

Synth is short for synthesiser — something that creates sounds. Typically synths are complicated, but here you get that power in an approachable way.

2.1 Your First Beeps

This is where it all starts:

play 70

Lower numbers make lower pitched beeps, higher numbers make higher ones. The number 60 is middle C. Each +1 is one semitone up, so play 61 is C#, play 62 is D.

Play multiple notes at once for a chord:

play 72
play 75
play 79

Use sleep between notes for a melody:

play 72
sleep 1
play 75
sleep 1
play 79

Try shorter sleep values like 0.5 or 0.25 to speed things up. You can also use note names:

play :C
sleep 0.5
play :D
sleep 0.5
play :E

Add an octave number (:C3, :E4), sharps with s (:Fs3), and flats with b (:Eb3).

2.2 Synth Options: Amp and Pan

Options (opts) let you control the sound. Pass them after a comma:

play 60, amp: 0.5
sleep 0.5
play 60, amp: 2

amp: controls volume — 0 is silent, 1 is normal. Try to stay in 0–0.5 to avoid compression.

pan: controls stereo position — -1 is left, 0 is centre, 1 is right:

play 60, pan: -1
sleep 0.5
play 60, pan: 1
2.3 Switching Synths

The default beep is just one of many synths. Switch with use_synth:

use_synth :saw
play 38
sleep 0.25
play 50
sleep 0.25
play 62
use_synth :prophet
play 38
sleep 0.25
play 50
sleep 0.25
play 62

Combine them — play multiple synths at once by not sleeping between them:

use_synth :tb303
play 38
use_synth :dsaw
play 50
use_synth :prophet
play 57

Some favourites: :prophet, :dsaw, :fm, :tb303, :pulse

2.4 Duration with Envelopes

Sonic Pi uses ADSR amplitude envelopes to control sound duration and shape.

Release — how long the sound fades out (default 1 beat):

play 60, release: 2

Attack — how long to fade in (default 0):

play 60, attack: 2
sleep 3
play 65, attack: 0.5

Combine them:

play 60, attack: 0.7, release: 4

Sustain — hold at full volume between attack and release:

play 60, attack: 0.3, sustain: 1, release: 1

Decay — drop from attack level to sustain level:

play 60, attack: 0.1, attack_level: 1, decay: 0.2,
  sustain_level: 0.4, sustain: 1, release: 0.5

Total duration = attack + decay + sustain + release.

3 — Samples

Another great way to make music is with pre-recorded sounds — samples.

3.1 Triggering Samples
sample :ambi_lunar_land

Layer samples with notes — they play simultaneously unless separated by sleep:

sample :ambi_lunar_land
sleep 1
play 48
sleep 0.5
play 36
sample :ambi_drone
sleep 1
play 36

Discover samples by typing a category prefix like :ambi_, :bass_, :elec_, :perc_, :guit_, :drum_, :misc_, or :bd_ and using autocomplete.

3.2 Sample Parameters

Samples accept the same opts as synths. Control amplitude and panning:

sample :ambi_lunar_land, amp: 0.5
sample :loop_amen, pan: -1
sleep 0.877
sample :loop_amen, pan: 1
Soundplay   synth   sample   use_synth
Timingsleep   use_bpm
Pitchuse_transpose   use_octave
FlowN.times   if   define   in_thread   live_loop   stop
Randomrand   rrand   rrand_i   rand_i   dice   use_random_seed
Theorychord   scale   note   range
Lists.choose   .shuffle
State@name =   @name   set   get   cue   sync
Outputprint

Sound

play note, amp: release: cutoff: ...

Play a note with the current synth. Accepts MIDI numbers or note symbols. Code continues executing while the sound plays through its envelope.

play 60
sleep 0.5
play :E4, amp: 0.5, release: 2
synth :synth_name, note: amp: release: ...

Trigger a specific synth by name. Unlike use_synth, this doesn’t change the default — it’s a one-shot. The note is passed as a note: kwarg (default: 52 / E3).

synth :prophet, note: 60, release: 2
sleep 0.5
synth :tb303, note: 36, cutoff: 80
sample :name, rate: amp: pan: ...

Trigger a sample. Play back a recorded sound file. Use a built-in sample name like :bd_haus or a full path string. There are many opts for manipulating playback — rate: affects speed and pitch, amp: controls volume. You can also filter samples from a directory by passing string keywords and an optional index.

sample :loop_amen
sleep 1
sample :ambi_drone, rate: 0.5, amp: 0.3

-- filter by directory and keyword
sample :drum "kick"
sample :drum "snare" 2, rate: 0.8
use_synth :synth_name

Set the default synth for all subsequent play calls.

use_synth :saw
play 50
sleep 0.5
use_synth :prophet
play 50

Timing

sleep beats

Wait for a number of beats before the next command. Beats are scaled to seconds by the current BPM.

play 60
sleep 1
play 67
sleep 0.5
play 72
use_bpm bpm

Set the tempo in beats per minute. Affects all subsequent sleep calls and temporal synth arguments.

use_bpm 120
play 60
sleep 1
play 67

Pitch

use_transpose semitones

Shift all notes by the given number of semitones. Use negative numbers to shift down.

play 60
sleep 0.5
use_transpose 7
play 60
use_octave octaves

Shift all notes by the given number of octaves (each octave = 12 semitones).

play 60
sleep 0.5
use_octave -1
play 60

Control Flow

N.times do … end

Repeat a block of code N times.

4.times do
  sample :bd_haus
  sleep 0.5
end
if condition … else … end

Conditional execution. Run code only when a condition is true.

if dice(6) > 3
  play 72
else
  play 60
end
define :name do … end

Give a block of code a name for re-use. Call it like any other function.

define :bass do
  use_synth :tb303
  play 36, release: 0.3, cutoff: 70
end

bass
sleep 0.5
bass
in_thread do … end

Run a block of code in a new thread. The parent continues immediately while the child runs concurrently. Each thread has its own timing, so sleep in one thread doesn’t block the other.

in_thread do
  4.times do
    sample :bd_haus, lpf: 90
    sleep 0.5
  end
end

in_thread do
  16.times do
    n = [52, 55, 57, 59, 62, 64].choose
    synth :chiplead, note: n, release: 0.1
    sleep 0.125
  end
end

8.times do
  sample :hat_bdu
  sleep 0.25
end
live_loop :name do … end

A loop for live coding. Runs the body repeatedly, automatically looping back to the start when it reaches end. If you edit the code and re-run, the new version hot-swaps into the running loop — no need to stop and restart. Each iteration automatically emits a cue at /live_loop/name so other threads can sync with it. Every live loop must contain at least one sleep to avoid spinning.

live_loop :beat do
  sample :bd_haus, lpf: 100
  sleep 0.5
end

live_loop :melody do
  use_synth :subpulse
  play [50, 54, 57, 62, 74].choose, release: 0.2
  sleep 0.125
end
stop

Stop the current thread or run. Does not stop any running synths triggered previously in the thread. Useful for conditionally silencing a live loop on some iterations.

play 70
sleep 0.5
play 72
stop
play 745

Randomisation

rand (max)

Random float between 0 and max (default 1).

8.times do
  play 72 + rand(24), release: 0.1
  sleep 0.125
end
rrand (min, max)

Random float between min and max.

8.times do
  play rrand(48, 72)
  sleep 0.25
end
rrand_i (min, max)

Random integer between min and max (inclusive).

8.times do
  play rrand_i(48, 72)
  sleep 0.25
end
rand_i (max)

Random integer between 0 and max−1.

4.times do
  sample :elec_blip, rate: rand_i(4)
  sleep 0.25
end
dice (n)

Roll a dice with N sides (default 6). Returns integer from 1 to N.

4.times do
  play 50 + dice(12)
  sleep 0.25
end
use_random_seed seed

Set the random seed for reproducible sequences. The same seed always produces the same random numbers.

use_random_seed 42
4.times do
  play rrand_i(50, 80)
  sleep 0.25
end

use_random_seed 100
4.times do
  play rrand_i(50, 80)
  sleep 0.25
end

use_random_seed 42
4.times do
  play rrand_i(50, 80)
  sleep 0.25
end

Music Theory

chord (:root, :type)

Create a list of MIDI notes forming a chord. The root can be a note symbol or MIDI number. Supports major, minor, 7th, 9th, 11th, 13th, sus, dim, aug, and many more.

play chord(:E3, :minor).choose
sleep 0.25
play chord(:C4, :major).choose
sleep 0.25
play chord(:A3, :dom7).choose
scale (:root, :type)

Create a list of MIDI notes forming a scale. Supports major, minor, pentatonic, blues, modes, and many exotic scales.

8.times do
  play scale(:C4, :minor_pentatonic).choose, release: 0.1
  sleep 0.125
end
note (:symbol)

Convert a note symbol to its MIDI number. Supports sharps (s), flats (b/f), and octave numbers.

print note(:C4)
print note(:Eb3)
play note(:Fs4)
range (start, end, step)

Create a list of numbers from start to end, incrementing by step.

8.times do
  play range(50, 74, 3).choose, release: 0.1
  sleep 0.125
end

Lists

[].choose

Pick a random element from a list.

4.times do
  play [60, 64, 67, 72].choose
  sleep 0.25
end
[].shuffle

Return a new list with elements in random order.

print [60, 64, 67, 72].shuffle

Time State

@name = value

Store information in Time State for the current time. The value is visible to all threads and will remain until overwritten. Shorthand for set :name, value.

@note = 60
play @note
sleep 0.5
@note = 72
play @note
@name

Retrieve information from Time State set prior to the current time from any thread. Returns 0 if no value has been stored. Shorthand for get :name.

@root = 50
8.times do
  play @root + rrand_i(0, 12), release: 0.1
  sleep 0.125
end
set :name, value

Store information in Time State. The value will remain until overwritten by another call to set. Also triggers any threads waiting on sync :name.

set :root, 60
4.times do
  play get(:root), release: 0.2
  sleep 0.25
end
set :root, 72
4.times do
  play get(:root), release: 0.2
  sleep 0.25
end
get :name

Retrieve information from Time State. Returns the most recent value stored with set prior to the current time. Returns 0 if not set.

set :notes, [50, 54, 57, 62]
8.times do
  play get(:notes).choose, release: 0.1
  sleep 0.125
end
cue :name

Cue other threads. Send a heartbeat synchronisation message containing the virtual timestamp of the current thread. Any thread waiting on sync :name will wake up and inherit this thread’s beat. Unlike set, cues are for signalling — they don’t store a retrievable value.

in_thread do
  sleep 1
  cue :drop
end

sync :drop
sample :bd_haus
play 36, release: 2
sync :name

Sync with other threads. Pause the current thread until a matching cue, set, or live_loop event is received. When matched, the current thread’s virtual time is set to match the cueing thread — synchronising them musically.

live_loop :beat do
  sample :bd_haus, lpf: 100
  sleep 0.5
end

live_loop :melody do
  sync :beat
  use_synth :chiplead
  play [50, 54, 57, 62].choose, release: 0.1
end

Output

print value

Display a value in the output pane. Useful for debugging.

print 42
print rrand(0, 100)
print "hello"

Quick jump:

Classic

:beep

A simple pure sine wave. The default synth.

play 60
:saw

A saw wave with a low pass filter.

use_synth :saw
play 50, release: 1
:square

A simple square wave with a low pass filter.

use_synth :square
play 50, release: 1
:tri

A simple triangle wave with a low pass filter.

use_synth :tri
play 60, release: 1
:pulse

A simple pulse wave with a low pass filter. Adjustable pulse width.

use_synth :pulse
play 52, pulse_width: 0.3, release: 1
:subpulse

A pulse wave with a sub sine wave passed through a low pass filter.

use_synth :subpulse
play 40, release: 1
:prophet

Dark and swirly, this synth uses Pulse Width Modulation (PWM) to create a timbre which continually moves around. This effect is created using the pulse ugen which produces a variable width square wave.

use_synth :prophet
play 60, release: 2
:hollow

A hollow breathy sound constructed from random noise

use_synth :hollow
play 60, release: 3
:dark_ambience

A slow rolling bass with a sparkle of light trying to escape the darkness. Great for an ambient sound.

use_synth :dark_ambience
play 48, release: 4
:growl

A deep rumbling growl with a bright sine shining through at higher notes.

use_synth :growl
play 40, release: 1
:zawa

Saw wave with oscillating timbre. Produces moving saw waves with a unique character controllable with the control oscillator (usage similar to mod synths).

use_synth :zawa
play 55, release: 2

Detuned

:dsaw

A pair of detuned saw waves passed through a low pass filter.

use_synth :dsaw
play 50, detune: 0.3, release: 1.5
:dpulse

A pair of detuned pulse waves passed through a low pass filter.

use_synth :dpulse
play 48, detune: 0.2, release: 1
:dtri

A pair of detuned triangle waves passed through a low pass filter.

use_synth :dtri
play 55, detune: 0.3, release: 1.5
:supersaw

Thick swirly saw waves sparkling and moving about to create a rich trancy sound.

use_synth :supersaw
play 50, release: 2

Bass

:tb303

Emulation of the classic Roland TB-303 Bass Line synthesiser.

use_synth :tb303
play 40, cutoff: 80, release: 0.5
:bass_foundation

A soft bass synth inspired by the sounds of the 80s.

use_synth :bass_foundation
play 36, release: 1
:bass_highend

An addition to the :bass_foundation synth inspired by the sounds of the 80s.

use_synth :bass_highend
play 40, release: 1
:gabberkick

An aggressive Gabber synth sound.

use_synth :gabberkick
play 36, release: 0.5

Keys & Bells

:rhodey

The sound of an electric piano from the 60's and 70's, producing a characteristic metallic sound.

use_synth :rhodey
play 60, release: 1.5
:dull_bell

A simple dull discordant bell sound.

use_synth :dull_bell
play 60
:pretty_bell

A pretty bell sound.

use_synth :pretty_bell
play 72
:kalimba

A synthesised kalimba (a type of African thumb piano).

use_synth :kalimba
play 72
:pluck

A basic plucked string synthesiser that uses Karplus-Strong synthesis.

use_synth :pluck
play 60, release: 1

Modulated

:fm

A sine wave with a fundamental frequency which is modulated at audio rate by another sine wave with a specific modulation, division and depth. Useful for generating a wide range of sounds by playing with the divisor and depth params.

use_synth :fm
play 60, divisor: 2, depth: 3, release: 1.5
:mod_saw

A saw wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.

use_synth :mod_saw
play 50, mod_rate: 4, release: 2
:mod_sine

A sine wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.

use_synth :mod_sine
play 60, mod_rate: 2, release: 2
:mod_pulse

A pulse wave with a low pass filter modulating between two notes via a variety of control waves (see mod_wave: arg). The pulse wave defaults to a square wave, but the timbre can be changed dramatically by adjusting the pulse_width arg between 0 and 1.

use_synth :mod_pulse
play 52, mod_rate: 3, release: 1.5
:mod_tri

A triangle wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.

use_synth :mod_tri
play 60, mod_rate: 5, release: 2
:mod_dsaw

A pair of detuned saw waves (see the dsaw synth) which are modulated between two fixed notes at a given rate.

use_synth :mod_dsaw
play 48, mod_rate: 2, release: 2
:mod_fm

The FM synth modulating between two notes - the duration of the modulation can be modified using the mod_phase arg, the range (number of notes jumped between) by the mod_range arg and the width of the jumps by the mod_width param. The FM synth is a sine wave with a fundamental frequency which is modulated at audio rate by another sine wave with a specific modulation, division and depth.

use_synth :mod_fm
play 55, mod_rate: 3, release: 1.5
:mod_beep

A sine wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.

use_synth :mod_beep
play 60, mod_rate: 2, release: 2

Chip & Retro

:chipbass

A 16 step triangle wave modelled after the 2A03 chip found in voice 3 of the NES games console. This can be used for retro sounding basslines.

use_synth :chipbass
play 36, release: 0.5
:chiplead

A slightly clipped square (pulse) wave with phases of 12.5%, 25% or 50% modelled after the 2A03 chip found in voices 1 and 2 of the NES games console. This can be used for retro sounding leads and harmonised lines.

use_synth :chiplead
play 72, release: 0.3
sleep 0.25
play 74, release: 0.3
sleep 0.25
play 76, release: 0.5
:chipnoise

Generates noise whose values are either -1 or 1 (like a pulse or square wave) with one of 16 particular frequencies. This is similar to the noise channel on the 2A03 chip used in the NES games console, although it lacks the same Pseudo-Random Number Generator (PRNG) and doesn't implement the 2A03's lesser used noise mode.

use_synth :chipnoise
play 60, release: 0.15

Other

:blade

Straight from the 70s, evoking the mists of Blade Runner, this simple electro-style string synth is based on filtered saw waves and a variable vibrato.

use_synth :blade
play 55, release: 1.5
:tech_saws

Slightly modified supersaw implementation based on http://sccode.org/1-4YS

use_synth :tech_saws
play 52, release: 2
:hoover

Classic early 90's rave synth - 'a sort of slurry chorussy synth line like the classic Dominator by Human Resource'. Based on Dan Stowell's implementation in SuperCollider and Daniel Turczanski's port to Overtone.

use_synth :hoover
play 40, release: 1.5
:rodeo

Classic 70's electric piano sound, with built-in compressor and chorus.

use_synth :rodeo
play 60, release: 1
:organ_tonewheel

An emulation of a tonewheel organ with an optional rotary speaker. These instruments were the first electro-mechanical synthesisers, developed in the mid 1930s by Laurens Hammond.

use_synth :organ_tonewheel
play 60, release: 2

Noise

:noise

White noise — equal energy at every frequency, comparable to radio static.

use_synth :noise
play 60, release: 0.5
:pnoise

Pink noise — spectrum falls off in power by 3 dB per octave.

use_synth :pnoise
play 60, release: 0.5
:bnoise

Brown noise — spectrum falls off in power by 6 dB per octave.

use_synth :bnoise
play 60, release: 0.5
:gnoise

Grey noise — results from flipping random bits in a word.

use_synth :gnoise
play 60, release: 0.5
:cnoise

Clip noise — values are either -1 or 1.

use_synth :cnoise
play 60, release: 0.5

SC808 Drum Machine

:sc808_bassdrum

SC808 bass drum.

synth :sc808_bassdrum
:sc808_snare

SC808 snare drum.

synth :sc808_snare
:sc808_clap

SC808 clap.

synth :sc808_clap
:sc808_closed_hihat

SC808 closed hi-hat.

synth :sc808_closed_hihat
:sc808_open_hihat

SC808 open hi-hat.

synth :sc808_open_hihat
:sc808_cymbal

SC808 cymbal.

synth :sc808_cymbal
:sc808_cowbell

SC808 cowbell.

synth :sc808_cowbell
:sc808_rimshot

SC808 rimshot.

synth :sc808_rimshot
:sc808_claves

SC808 claves.

synth :sc808_claves
:sc808_maracas

SC808 maracas.

synth :sc808_maracas
:sc808_tomlo

SC808 low tom.

synth :sc808_tomlo
:sc808_tommid

SC808 mid tom.

synth :sc808_tommid
:sc808_tomhi

SC808 high tom.

synth :sc808_tomhi
:sc808_congalo

SC808 low conga.

synth :sc808_congalo
:sc808_congamid

SC808 mid conga.

synth :sc808_congamid
:sc808_congahi

SC808 high conga.

synth :sc808_congahi

Quick jump by category:

Ambient (ambi_)

:ambi_choir
:ambi_dark_woosh
:ambi_drone
:ambi_glass_hum
:ambi_glass_rub
:ambi_haunted_hum
:ambi_lunar_land
:ambi_piano
:ambi_sauna
:ambi_soft_buzz
:ambi_swoosh

Bass (bass_)

:bass_dnb_f
:bass_drop_c
:bass_hard_c
:bass_hit_c
:bass_thick_c
:bass_trance_c
:bass_voxy_c
:bass_voxy_hit_c
:bass_woodsy_c

Kick Drums (bd_)

:bd_808
:bd_ada
:bd_boom
:bd_chip
:bd_fat
:bd_gas
:bd_haus
:bd_jazz
:bd_klub
:bd_mehackit
:bd_pure
:bd_sone
:bd_tek
:bd_zome
:bd_zum

Drums (drum_)

:drum_bass_hard
:drum_bass_soft
:drum_cowbell
:drum_cymbal_closed
:drum_cymbal_hard
:drum_cymbal_open
:drum_cymbal_pedal
:drum_cymbal_soft
:drum_heavy_kick
:drum_roll
:drum_snare_hard
:drum_snare_soft
:drum_splash_hard
:drum_splash_soft
:drum_tom_hi_hard
:drum_tom_hi_soft
:drum_tom_lo_hard
:drum_tom_lo_soft
:drum_tom_mid_hard
:drum_tom_mid_soft

Electronic (elec_)

:elec_beep
:elec_bell
:elec_blip
:elec_blip2
:elec_blup
:elec_bong
:elec_chime
:elec_cymbal
:elec_filt_snare
:elec_flip
:elec_fuzz_tom
:elec_hi_snare
:elec_hollow_kick
:elec_lo_snare
:elec_mid_snare
:elec_ping
:elec_plip
:elec_pop
:elec_snare
:elec_soft_kick
:elec_tick
:elec_triangle
:elec_twang
:elec_twip
:elec_wood

Glitch (glitch_)

:glitch_bass_g
:glitch_perc1
:glitch_perc2
:glitch_perc3
:glitch_perc4
:glitch_perc5
:glitch_robot1
:glitch_robot2

Guitar (guit_)

:guit_e_fifths
:guit_e_slide
:guit_em9
:guit_harmonics

Hi-hats (hat_)

:hat_bdu
:hat_cab
:hat_cats
:hat_gem
:hat_gnu
:hat_gump
:hat_hier
:hat_len
:hat_mess
:hat_metal
:hat_noiz
:hat_psych
:hat_raw
:hat_sci
:hat_snap
:hat_star
:hat_tap
:hat_yosh
:hat_zan
:hat_zap
:hat_zild

Loops (loop_)

:loop_3d_printer
:loop_amen
:loop_amen_full
:loop_breakbeat
:loop_compus
:loop_drone_g_97
:loop_electric
:loop_garzul
:loop_industrial
:loop_mehackit1
:loop_mehackit2
:loop_mika
:loop_perc1
:loop_perc2
:loop_safari
:loop_tabla
:loop_weirdo

Percussion (perc_)

:perc_bell
:perc_bell2
:perc_door
:perc_impact1
:perc_impact2
:perc_snap
:perc_snap2
:perc_swash
:perc_swoosh
:perc_till

Snares (sn_)

:sn_dolf
:sn_dub
:sn_generic
:sn_zome

Tabla (tabla_)

:tabla_dhec
:tabla_ghe1
:tabla_ghe2
:tabla_ghe3
:tabla_ghe4
:tabla_ghe5
:tabla_ghe6
:tabla_ghe7
:tabla_ghe8
:tabla_ke1
:tabla_ke2
:tabla_ke3
:tabla_na
:tabla_na_o
:tabla_na_s
:tabla_re
:tabla_tas1
:tabla_tas2
:tabla_tas3
:tabla_te1
:tabla_te2
:tabla_te_m
:tabla_te_ne
:tabla_tun1
:tabla_tun2
:tabla_tun3

Vinyl (vinyl_)

:vinyl_backspin
:vinyl_hiss
:vinyl_rewind
:vinyl_scratch

Misc

:misc_burp
:misc_cineboom
:misc_crow
:ride_tri
:ride_via
:mehackit_phone1
:mehackit_phone2
:mehackit_phone3
:mehackit_phone4
:mehackit_robot1
:mehackit_robot2
:mehackit_robot3
:mehackit_robot4
:mehackit_robot5
:mehackit_robot6
:mehackit_robot7

Sonic Tau (demo)

This is a working technical demo of the upcoming Sonic Tau system — a small taster of what’s to come.

There’s just enough here for play, experimentation and introductory workshops. It’s a design prototype — the journey is just getting started.

Sonic Tau is heavily influenced by Sonic Pi — whilst the language is designed to feel familiar, the architecture is radically different.

Follow along on patreon.com/samaaron

Give me the tech details…

The compiler is built on tree-sitter and is designed to be tolerant of syntax errors. The language runtime is completely deterministic and consists of a tree of concurrent register-based bytecode VMs coordinating via an immutable time-series in-memory database.

All implemented in Rust with zero mallocs, zero IO and zero blocking — running lock-free directly on the browser’s high-priority AudioWorklet thread alongside SuperSonic.

Built with SuperSonic, tau-state, tree-sitter & CodeMirror 6.

Join the Journey

Sonic Tau, SuperSonic and related tech are being built in the open by Sam Aaron — the creator of Sonic Pi.

Sam shares regular development updates on Patreon — thoughts, progress and goals — with the Sonic Pi and Sonic Tau communities.

Follow Sam on Patreon for free to keep in the loop.

Follow on Patreon GitHub Sponsors
Audio suspended

Install Sonic Tau

1 Tap in Safari's toolbar
2 Scroll down and tap Add to Home Screen
3 Tap Add to confirm

Share this code