Skip to content
automata edited this page Sep 22, 2012 · 6 revisions

Principles:

  • The language should be simple
  • Use mnemonics and syntax sugar (with care): few chars, big results

Rules:

  • Music is made by voices (instruments)
  • Voices have name, timbre and parameters ranging along the time
  • Names are something like a, b, c
  • Timbre are signals made by chains of audio generators and filters
  • Parameters are musical notes, amplitudes, oscillators frequency, delay time, ...
  • Parameters changes their values at some times and have some durations

Audio sources:

  • osc(freq), saw(freq), square(freq), audio(filename)

Audio filters:

  • gain(), reverb(), delay(), echo(), low(freq), high(freq), band(f1, f2)

Code example:

a.sig = audio('foo.wav')         # foo.sig defines a signal
a.amp = [1 1 _ 1 | 1 _ _ _ ]     # foo.param = [] defines where and how parameter values changes
a.amp = {.25 .25 .25 .25 }       # foo.param = {} defines how long parameter changes will apply

# every voice has amp and notes as default parameters
c.signal = osc => gain => reverb
c.notes = [c4 c4# d4 e2 | c4 c4# _ d2  ]
c.notes = {1/4 1/2}

# chords
c.notes = [C2m7 C2 D2 E2]

# complex dsp graphs (+ to add signals, => to chain)
b.sig = (osc1() + osc2(20)) => delay1(100) => gain1, gain1 => delay1

# complex parameter automation
b.osc1.freq = [100 200 100 440]
b.osc1.freq = {1/2 1/4}

# or inline
b.osc1.freq = [100 200 100 440] {1/2 1/4}

# list operations
c.notes reverse
c.notes shake
c.notes circular
c.notes * 2

# event schedulling with @
c.notes = [c4# c4 d4 e4] reverse @ now
c.notes = [c4# c4 d4 e4] reverse @ now + 2
c.notes = [c4# c4 d4 e4] @ now ~ forever    # default

Three voices:

a.sig = audio('cello.wav')
b.sig = audio('piano.wav')
c.sig = audio('string.wav')

a.notes = [c0 d0 e0 d0] {1/4}
b.notes = [C2m7 C2m E2m D2m] {1/4}
c.notes = [c0 d0] {1/16}

Sampling:

a.sig = audio('dub.wav') => delay
a.amp = [1 .5 .8 .7] {1/4}
a.dir = [> < > >] {1/4}
a.delay = [100 200 300 200] {1/4}

Granular synthesis:

a.sig = audio('noise.wav')
a.amp = [1 .5 .8] {.02}
a.dir = [<] {.02}

Additive synthesis:

a.sig = osc1(440) + osc2(220) + osc3(110)

Substrative synthesis:

a.sig = noise => adsr(.8, .6, .6, .0)

FM synthesis:

a.sig = osc1 => osc2.freq

Misc Syntax Ideas

# dsp chain with mnemonics
a = wav("foo") => lp => rvb => phz => out

# values x durations
a.lp = [100, 200, 300] 
a.lp.dur = [1/2, 1/4]

# at operator
a.lp = [100, 200, 300] @ [1/2, 1/4]

List operators as mnenonics

# reverse
a.lp = [100, 200, 300] r   # => [300, 200, 100]

# two-first circular
a.lp = [100, 200, 300] c2  # => [200, 100, 300]

# shift left
a.lp = [100, 200, 300] <   # => [200, 300, 100]

Clone this wiki locally