After posting at length about the history of my musical pattern representation, I thought I’d better show some demos and explain a bit about how it works in practice.
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:
[vimeo 60914002 w=657&h=120]
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:
[vimeo 60914003 w=657&h=120]
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:
[vimeo 60914004 w=657&h=120]
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:
[vimeo 60914010 w=657&h=120]
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:
[vimeo 60914011 w=657&h=120]
Finally (for now) here’s a video demonstrating Haskell’s “do syntax” for monads:
[vimeo 60914028 w=657&h=120]
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.
This is by far the coolest thing I’ve seen done with Haskell.
Awesome! What are the dependencies, if I want to play with it?
Oops sorry for the massively late reply!
Installation instructions are here:
http://yaxu.org/tidal/
alex
Wow. Finally a computer livecoding paradigm that innately makes sense. It really works cleanly and simply. I love the way it is centered around a constant loop. It wasn’t even hard to get dirt + tidal going. Kudos, this is great work.
Very fun. I’ll see what I can create now.