handmade-livecode.txt
An introduction to live coding for Handmade Boston using strudel and hydra.
Table of Contents
My Background
programming
C++
at work and try not to hate
it. Spent a lot of time writing Rust
and recently switched over to Zig
.livecoding
Viscera
and with livecode.nyc.handmade
Goals
My hope is that this can be a wonderful cross-pollination between the live code and handmade communities.
The handmade
community has a lot to offer:
- Low level insights leading to high level improvements
- Appreciation of the technical aspects of UX:
Performance, Simplicity, Reliability - Technology that serves the user
The live coding
community has a lot to offer:
- Making technology accessible to non-technical people
- Alternative perspectives on technology & its meaning
- Artistic and creative practice and perspectives
Live Coding
verb
.- Writing and running code in a live environment, where one is able to run and manipulate the program at the same time.
noun
.- A form of performance art using code as the interface to create art with an emphasis on live manipulation of code that is usually visible to the audience. Fully improvised, or party planned.
We usually treat Software development
as a practice with a relatively
objective goal, with quantifiable results:
- Means of Production
- Automation
- Commerce
- Permenance
Live Coding
requires a shift in mindset:
- Community
- Creative Performance
- Connection
- Ephemerality
Ethos
The live coding
community also carries values of:
- Software made by people for people
- On the fly problem solving: No backups!
- Gender Equality & Diversity
- Opposition to Heirarchy
And perhaps most importantly…
ALWAYS SHOW YOUR CODE
On Gender Equality, I'd like to shout out some of my fave women and enbies:
Char Stiles
- Uses GLSL (hardcore) to create awesome visuals, also proficient in strudel.
Also:
Char's Tiles
Switch Angel
- Very talented strudel developer and live code performer, one of the best out there.
DJ_Dave
- A very talented musician who uses sonic-pi.
elle
- Talented local visual performer also using Hydra, and de-facto co-organizer for our meetup group.
Heavy Lifting
- Musician, contributor to Tidal Cycles, and one of the OGs.
this.xor.that
- Visualist with a custom live coding tool called
Murrelet
Technical Constraints
Live coding presents intersting technical constraints in needing to write and edit code live. This leads to the use of:
- Scripting languages:
ruby
,python
,lua
javascript
and the browserREPL
s likehaskell
'sghci
This has downsides though:
Performance Problems ==
Performance Problems
I think this is where Handmade can help!
But now, let's make some art.
Javascript
The only special thing you need to know:
We can also get functional freaky
12
Strudel
strudel
: javascript sound engine and live coding framework.
Represents music as repeating cycles
of events.
Making a Sound
Go to strudel.cc and type:
"bd"
Press CTRL+Enter
to run your program.
Sound | Description |
---|---|
bd | Bass drum |
sd | Snare drum |
hh | High-hat |
sawtooth | A very bright synth sound |
xylophone_hard_ff | A xylophone sample |
- or ~ | rest |
Mininotation
Everything inside "
s is a pattern
written in mininotation
.
$: "bd bd bd bd"
We call each slice of the cycle an arc
. The length of the cycle stays the
same no matter how many arc
s divide up the cycle.
$: "bd bd - bd bd -"
Operators
Strudel has mininotation operators:
Operator | Effect |
---|---|
@ | Elongates |
! | Repeats |
* | Speeds up |
/ | Slows down |
? | Play event 50% of the time |
[ ] | Create a sub-cycle |
< > | Alternate |
Melody
strudel
can play notes as well:
$: "c ab f bb""piano"
Notation | Meaning |
---|---|
[a-g] | note (western scale) |
a[0-9]+ | a with octave |
a(f|b) | a with flat |
a(s|#) | a with sharp |
Transforming Patterns
Apply functions to patterns to alter them:
.fast(n)
n
.ply(n)
n
times.degradeBy(n)
n
% of events where 1
is 100%.transpose(n)
n
semitones.late(n)
n
cycles.struct(pat)
x
in pat
, sample data from the leftHigher Order Functions
Apply functions to patterns to alter them:
.superimpose(fn)
fn
applied.off(n, fn)
n
.when(pat, fn)
pat
is true, apply fn
.Self learning
strudel
is an instrument, and requires practice.
- Try weird combinations of things
- Look at random stuff from the
reference
- Watch and
steallearn - Ask for help on club.tidalcycles.org
Hydra
hydra
is a javascript tool for generating shaders
inspired by analogue
video synthesis.
Represents a shader as a tree (or hydra) of transforms
.
We can either open hydra
's editor at hydra.ojack.xyz,
or directly in strudel
's editor with:
await
Source
The simplest possible patch:
1,0,1
- gradient()
- draws a gradient from
uv
coordinates - shape(n)
- draws a shape with
n
sides - osc()
- draws
sin(uv.x)
with time offset - noise()
- Draws smooth noise
- voronoi()
- Draws voronoi diagram
Color
We can chain functions which modulate the color:
.hue()
- Shift hue by optional amount
.luma()
- Set alpha of dark pixels to
0
.saturate()
- Multiply color saturation
.constrast()
- Increase or decrease contrast
Coord
We can also manipulate the uv
coordinates as observed by the shader:
.rotate()
- Apply 2d rotation in radians
.scale()
- Apply uniform scale
.repeat()
- Repeat the image
n
times .scollX()
- Shift
x
coordinates .kaleid()
- Apply kaleidescope effect
Modulation
But what about non-uniform
transforms?
.modulateRotate(osc(), n)
- Rotate each pixel by
osc
or whatever pattern goes in .modulateScale(voronoi(), n)
- Scale each pixel by
voronoi
Generally, each coord
function has a "modulate
" version.
Combine
We can layer multiple transforms atop one-another:
.add(osc())
osc
, scaled by optional param.blend(gradient())
.layer(voronoi().luma())
.diff(shape())
Feedback
hydra
supports up to 4 outputs! o0
, o1
, o2
, o3
We can read and write to the same one to create feedback.
o00 1o0
o0
is the default and we can omit it.
Sequencing
[]
in hydra create sequences,
similar to strudel
but much simpler:
40, 0 1,
Uniforms
You can use an javascript
lambda to create a uniform:
() => Math.sin(time) * 2
Incompatible with sequence []
s.
Audio Reactivity
Reacting to sound can bring so much life into your patch!
4
// a.hide()
40, 0 1,a.fft* 2
Questions & Demo
- Some closing thoughts
- Let's jam out!
- Shout out your questions
FIN.