I collaborated with xname on a performance as xynaaxmue on Saturday, audio+video up soon I hope.. xname performs with circuits that turn light into sound, improvising noise using stroboscopic lights. I was live coding with tidalcycles, as ever.
In the past I’ve created flashing patterns on an external monitor for xname’s circuits to feed off, check here for a recording of that one. This time I wanted to control a pair of RGB flash panels over DMX.. I used a tinkerit DMX hat for the arduino, officially retired but you can still find them online and the library is downloadable on github.
I hacked together a Tidal interface the night + morning before the conference, and it worked pretty well.. The Haskell and Arduino code is here.
With everything loaded up, Tidal code like this triggers flashes of light as well as sound:
x2 $ every 2 (slow 2) $ (jux (rev) $ foldEvery [5,7] (slow 2) $ (slowspread (chop) [64,128,32] $ sound "bd*2 [arpy:2 arpy] [mt claus*3] [voodoo ind]")) # dur "0.02" # nudge (slow 4 sine1) The basic features:
- sound – (sample name) is translated into colour in a semi-arbitrary way (a mapping which falls back on some crypto hashing)
- pan – (kind of) pans between the two lights
- dur – controls the duration of the flash
- the flashes have a linear fade, which works across chop and striate
Will update with documentation of the performance itself when it’s up.
Here’s Broken, a new two-sided single out on Chordpunch.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
I’ve continued with the Tidal cycles project, pushing forward with at least one cycle per weekday, apart from one day when I made a longer recording (to appear on chordpunch soon). All the audio is downloadable and creative commons licensed (CC-BY), check the descriptions for the tweet-sized tidal code for each cycle, and follow on twitter or soundcloud for updates.
brak $ let x = "bd [sn [[sn bd] sn]]*1/3" in interlace (sound $ slow 3 $ x) (sound $ every 3 (append "[bd]*6") x)
weave 4 (speed $ (1+) sinewave1) [density 4 $ every 5 ((0.25 <~) . rev) $ striate 16 $ sound"[bd sn/2]/2", sound "bd [~ hc]*3"]
Texture v.2 is getting interesting now, reminds me of fabric travelling around a loom..
Everything apart from the DSP is implemented in Haskell. The functional approach has worked out particularly well for this visualisation — because musical patterns are represented as functions from time to events (using my Tidal EDSL), it’s trivial to get at future events across the graph of combinators. Still much more to do though.
A quick improv from Sheffield:
Here’s the state of my editor at the end:
d1 $ slow 2 $ sound "bd [sn sn bd]/2" let x = density 2 $ striate' 8 0.75 $ sound (slow 4 $ "[bd bd/4] [ht mt lt]") in d2 $ stack [every 3 rev $ every 4 (0.75 <~) x |+| pan "0.2", every 4 rev $ every 3 (0.5 <~) x |+| pan "0.8" ] |+| speed "1" |+| shape "0.6" d4 $ every 4 (density 2) $ echo 0.5 $ brak $ every 3 (0.25 <~) $ sound "[future,odx,bd]*3" |+| shape "0.7" let perc = 0.2 in d3 $ slow 2 $ whenmod 10 12 (echo 0.25) $ density 2 $ sound (pick <$> "~ [operaesque]" <*> (slow 5 $ run 24)) |+| slow 16 ((begin $ (*(1-perc)) <$> sinewave1) |+| (end $ (+perc) <$> sinewave1)) |+| speed (slow 2 "0.75 0.7") |+| pan "0.6" |+| shape "0.6" let perc = 0.2 in d4 $ slow 3 $ every 2 (rev) $ whenmod 10 12 (echo 0.25) $ density 2 $ sound (pick <$> "~ [operaesque]*3" <*> (slow 10 $ run 16)) |+| slow 16 ((begin $ (*(1-perc)) <$> sinewave1) |+| (end $ (+perc) <$> sinewave1)) |+| speed "0.75" |+| pan "0.4" |+| vowel "i" hush d6 $ whenmod 10 12 (density 2) $ whenmod 12 4 (rev) $ slow 2 $ sound "[futuremono]*3 [odx/3]" d7 $ whenmod 6 4 (0.25 <~) $ every 4 (density (3/2)) $ slow 2 $ sound "[jungle/2]*2 [jungle/3]*2" |+| shape "0.7" d7 $ (whenmod 2 4 ((|+| speed "0.9") . rev) $ every 2 (0.25 <~) $ sound "odx [sn/2 ~ sn/2]") d2 silence d8 $ ((slow 8 $ double (0.25 <~) $ striate 12 $ sound "[diphone2/1 ~ diphone2/3]*4") |+| (slow 4 $ speed ((*) <$> "[2 1] 1.5" <*> ((+0) <$> ((+0.4) <$> (slow 4 $ sinewave1)))))) |+| vowel "i" d9 $ slow 2 $ sound "[[odx]*4]/3 [[odx]*4 [odx]*8]/3" |+| speed "1" |+| cutoff "0.04" |+| resonance "0.7" |+| shape "0.8" bps 1
Texture 2.0 (my Haskell based visual live programming language) is working a bit more. It has reached gabber zero – the point at which a programming language is able to support the production of live techno. Also I’ve made some small steps towards getting some of my live visualisation ideas working. Here’s a video which exposes some nice bugs towards the end:
This is an unsupported, very pre-alpha experiment, but if you want to try to get it working, first install Tidal (and if you want sound, the associated “dirt” sampler). Then download the code from here:
.. and run it with something like
For me the best part of my workshops during my residency here at Hangar was getting the participants to try out Tidal. In the final workshop there were around 12 of us jamming together, each with a speaker in a kind of drumming circle, at several points it was sounding really great.
In between workshops I’ve been cleaning up my various bits of code, and have now tied it all together into the first semi-documented release of Tidal. You can get the docs and the source over here.
Let me know if have feedback, or would like me to run workshops in your town…
Demonstrating music tech is difficult, because it seems to be impossible to listen to demos without making aesthetic judgements. The below is not meant to be good music, but if you find yourself enjoying any of it, please think sad thoughts. If you find yourself reacting badly to the broken rhythms, try humming a favourite tune over the top. Or alternatively, don’t bother reading this paragraph at all, and go and tell your friends about how the idea is kind of interesting, but the music doesn’t make you weep hot tears like S Club did back in the day.
Anyway, this demo video shows how polyrhythmic patterns can be quickly sequenced:
Strings in this context are automatically parsed into Patterns, where comma-separated patterns are stacked on top of each other. Subpatterns can be specified inside square brackets to arbitrary depth, and then the speed of those can be modified with an asterisk.
In the above example the patterns are of sample library names, where bd=bass drum, sn=snare, etc.
By the way, the red flashes indicate when I trigger an evaluation. Lately people have associated live coding with evaluate-per-keypress. This doesn’t work outside well-managed rigged demos and educational sandboxes; computer language generally doesn’t work on a character level, it works on a word and sentence level. I had an evaluate-per-keypress mode in my old Perl system ten years ago, but always kept it switched off, because I didn’t want to evaluate 1 and 12 on the way to 120. *Some* provisionality is not necessarily a bad thing; mid-edits may be both syntactically valid and disastrous.
That rant aside, this video demonstrates brak, a fairly straightforward example of a pattern manipulation:
Here’s the code for brak:
brak :: Pattern a -> Pattern a brak = every 2 (((1%4) <~) . (\x -> cat [x, silence]))
In other words, every 2nd repetition, squash some silence on to the end of the pattern, and then shift the whole thing 1/4 of a cycle to the left. This turns any pattern into a simple breakbeat.
Let’s have a closer look at every in action:
This demonstrates how a function can be applied to a pattern conditionally, in the above shifting (with <~) or reversing (with rev) every specified number of repetitions.
These demos all trigger sounds using a software sampler, but it’s possible to get to subsample level:
The striate function cuts a sample into bits for further manipulation, in the above case through reversal. This is a technique called granular synthesis.
Here’s the code for striate:
striate :: Int -> OscPattern -> OscPattern striate n p = cat $ map (\x -> off (fromIntegral x) p) [0 .. n-1] where off i p = p |+| begin (atom (fromIntegral i / fromIntegral n)) |+| end (atom (fromIntegral (i+1) / fromIntegral n))
It takes n copies of the pattern, and concatenates them together, but selecting different portions of the patterns to play with the begin and end synthesiser parameters. The |+| operator knits together different synth parameters into a whole synth trigger message, which is then sent to the synth over the network (the actual sound is not rendered with Haskell here).
This video demonstrates the |+| combinator a little more, blending parameters to pan the sounds using a sine function, do a spot of waveshaping, and to apply a vowel formant filter:
Finally (for now) here’s a video demonstrating Haskell’s “do syntax” for monads:
A pattern of integers is used to modulate the speed of a pattern of samplenames, as one way of creating a stuttering rhythm.
That’s it, hopefully this discharges some flavour of what is possible — any kind of feedback always very welcome.