Sound on BEAM: Music in the Land of Distributed Lisp
Overview
- Introduction
- undertone
- Demo
- Architecture
- Use Cases
- Languages
- FP, Global/Mutable State, and I/O
- Sound synthesis as functional programming
- Systems control for music
- What’s next for undertone
- Final Q & A
Who am I?
- Prinicpal software engineer
- Life-long hacker (started at age 9 in ‘81; never stopped)
- Habbitual explorer
- Core contributor to Robert Virding’s Lisp Flavoured Erlang (LFE)
Who am I?
- 4 yo - Messing about with Piano
- 9 or 10 yo - Formal piano lessons, casual guitar
- 14 yo - First synthesizer (analog Korg PolySix)
- 16 yo - Performed in a chamber music group
- 22 yo - Assembled a home recording studio
- 25 yo - Stopped playing music, replaced with physics / maths studies … then career
- 48 yo - Started playing again
Re-entering the Musical World
Re-entering the Musical World
Then … Nothing
But!
And …
And?
Wherefore undertone?
What is undertone?
Demo Time
Let’s have some space music!
Demo Time
- Creating a “space orchestra” with note transformations and multiple channels: see the teaser video
Demo Time
- Using
xt.midi:cc-ramp
to simulate turning the knobs on an analog synth: see the Dallas/Fort Worth BEAMers Meetup demo
Demo Time
- Towards generative music with Markov chains and chords: HD video + sound (posting on Twitter now …)
Architecture
Architecture
System context for Extempore:
- talks to the OS / routes MIDI
- signals routed to external devices
- also routed to MIDI in the DAW (e.g., software synthesizers)
Architecture
System context for undertone:
- uses Erlang (starts up supervision tree, clients, servers)
- talks to Extempore (bitstrings over TCP)
- controls OSC servers (e.g., DAWs)
Architecture
Architecture
Architecture
Architecture
Architecture
Architecture
Architecture
Architecture
The undertone “container”:
- OTP app with supervisor and state server
- State server for mananging session commands and system config
- OSC clients for any OSC-enabled software running a UDP server
- TCP client for long-running connections to Extempore
- LFE REPL
- Extempore REPL
What Can undertone Do?
What Can undertone Do?
What Can undertone Do?
- Long, slow looping music in given keys, but random notes or intervals
- Accompanyment for practice
- Jam sessions
- Endless, non-repeating background, ambient music
So Far
-
Introduction
-
undertone
-
Demo
-
Architecture
-
Use Cases
- Languages
- FP, Global/Mutable State, and I/O
- Sound Synthesis as Functional Programming
- What’s Next for undertone
- Q & A
Erlang & LFE
An example: a recursive function using pattern-matching in the function heads.
Erlang
ackermann(0, N) ->
N+1;
ackermann(M, 0) ->
ackermann(M-1, 1);
ackermann(M, N) when M > 0 andalso N > 0 ->
ackermann(M-1, ackermann(M, N-1)).
LFE
(defun ackermann
((0 n) (+ n 1))
((m 0) (ackermann (- m 1) 1))
((m n) (ackermann (- m 1) (ackermann m (- n 1)))))
Extempore
xtlang:
(bind-func AudioBuffer_data_b64
(lambda (ab:AudioBuffer*)
(let ((b64size:i64 0)
(datsize:i64 (* (AudioBuffer_frames ab)
(AudioBuffer_channels ab) 4)))
(String (base64_encode (cast (tref ab 4) i8*)
datsize
(ref b64size))))))
Extempore
Scheme:
(sys:load "libs/external/portmidi.xtm")
(pm_initialize)
(define *midi-out* (pm_create_output_stream 3))
(define midi-loop
(lambda (beat dur)
(mplay *midi-out*
(random (list 36 43 48 51 60 60 60 67 70 74 75))
(random 60 80)
dur 0)
(callback (*metro* (+ beat (* .5 dur)))
'midi-loop
(+ beat dur)
dur)))
(midi-loop (*metro* 'get-beat 4) 1/4)
(define midi-loop
(lambda (beat dur) #t))
FP in an I/O World
A mutable, global system bent upon I/O
(sys:load "libs/external/portmidi.xtm")
(pm_initialize)
(define *midi-out* (pm_create_output_stream 3))
(define midi-loop
(lambda (beat dur)
(mplay *midi-out*
(random (list 36 43 48 51 60 60 60 67 70 74 75))
(random 60 80)
dur 0)
(callback (*metro* (+ beat (* .5 dur)))
'midi-loop
(+ beat dur)
dur)))
(midi-loop (*metro* 'get-beat 4) 1/4)
(define midi-loop
(lambda (beat dur) #t))
FP in an I/O World
An LFE sequencer in undertone?
FP in an I/O World
Yes!
(set opts (xt.seq:midi-opts sequence-name
device-name
device-id
midi-channel
seq1
pulse1
beats-per-minute
beats-per-measure
note-timing))
(xt.seq:start opts)
(xt.midi:cc-ramp (mupd opts 'cc-code (cutoff-filter-1)) 15 40 5)
(xt.seq:set-midi-notes! (mupd opts 'notes '(c3 c3 c4 c4 a#3 g3)))
FP in an I/O World
Synthesis as Functional Programming
The Beginnings of Sound Synthesis
The Beginnings of Sound Synthesis
The Beginnings of Sound Synthesis
The Beginnings of Sound Synthesis
Synthesis as Functional Programming
Synthesis as Functional Programming
Synthesis as Functional Programming
Synthesis as Functional Programming
Synthesis as Functional Programming
Synthesis as Functional Programming
Synthesis as Functional Programming
What’s Next for undertone?
Land of Lisp
Special thanks to Conrad Barski, M.D.
for his kind permission in using images from his book in this talk.
Buy it! http://landoflisp.com/