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.