Category: haskell

Patterns are the time of numbers

Ok this post is going to look quite dry, but is actually very exciting, at least for users of TidalCycles. So first here’s a video demonstrating the simplified syntax the below blurb will allow in a future version (version 1.0, which will probably be released soon after the upcoming 0.9).

If you want to see more videos like this check the playlists on the TidalCycles youtube channel.

Anyway.. Something I’ve noticed at Tidal workshops is that beginners have problems with this sort of code:
density 2 "1 2 3 4"
There’s the pattern 1 2 3 4, denoted by quotes, and the number 2 without quotes. This says ‘make the pattern twice as dense’, so you end up with this every cycle: 1 2 3 4 1 2 3 4.

Fairly straightforward, but why is the 2 a number, not a pattern? With more complicated, higher-order patterns this becomes increasingly unclear. There are ways to treat that number like a pattern:

spread' (density) "2 5" $ "1 2 3 4"
or ..
do n <- "2 5"
   density n "1 2 3 4"

… but now you’re converting between numbers and patterns of numbers instead of engaging with the music you’re making.

So I asked about this on haskell-art, in particular how to make it so a function like density could take either a number, or a pattern of numbers. One suggestion from Henning Thielemann was surprising – that Tidal’s Pattern type could be defined as a Haskell Number.

To cut this short it turned out that simply by evaluating a small amount of very simple code[1], Tidal’s syntax suddenly becomes far more expressive.

Instead of:
d1 $ sound "bass3" # speed "1.2"

you can just do
d1 $ sound "bass3" # speed 1.2

instead of
d1 $ sound "bass3*4" # speed (scale 1.2 3.2 $ ((+) <$> (slow 4 tri1) <*> sine1))
you can just do:
d1 $ sound "bass3*4" # speed ((slow 4 tri1) + sine1 * 2 + 1.2)

instead of
d1 $ up (every 3 ((+12) <$>) "1 8 [7 ~ 4]") # sound "bd"
it’s simply:
d1 $ up (every 3 (+12) "1 8 [7 ~ 4]") # sound "bd"
and with a quick re-jig of the definition of functions like density:

instead of
d1 $ n ((+) <$> ((+) <$> "1 2 3" <*> slow 3 "0 1") <*> slow 2 "3 1") # sound "voodoo"
it’s:
d1 $ n ("1 2 3" + slow 3 "0 1" + slow 2 "3 1") # sound "voodoo"

and much more…

By redefining density and friends, e.g.:

let density tp p = unwrap $ (\tv -> withResultTime (/ tv) $ withQueryTime (* tv) p) <$> tp

It’s then possible to fulfil my original aim:

d1 $ density "1 [2 3] [1 3]/2" $ sound "bd [sn:2 mt]/2"
while still supporting the original syntax:
d1 $ density 1.5 $ sound "bd [sn:2 mt]/2"

Basically, it turns out that if you let Haskell treat patterns of numbers as numbers, it provides extremely expressive means for working with them. This makes sense — patterns of numbers are numbers, just numbers which are polyphonic, and vary over (rational) time.

Lovely. This is a huge and unexpected win, which greatly simplifies pattern combination and manipulation, in the process greatly extending the possibilities that are within reach of a few keystrokes. This renews my suspicion that Haskell is full of much wondrous stuff just waiting to be discovered..

[1] Here’s that ‘small amount of very simple code’, if you want to try this at home:

instance Num a => Num (Pattern a) where
negate = fmap negate
(+) = liftA2 (+)
(*) = liftA2 (*)
fromInteger = pure . fromInteger
abs = fmap abs
signum = fmap signum

instance (Fractional a) => Fractional (Pattern a) where
fromRational = pure . fromRational
(/) = liftA2 (/)

 

Cyclic visualiser

Something I did ages ago on a residency, made a video a while back but forgot to put it here, here it is:

Sound to light for light to sound

xynaaxmue
xynaaxmue

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
  • it is kind of polyphonic but the colour mixing can be improved.. mixing coloured light seems to get into the realm of philosophy though !

Will update with documentation of the performance itself when it’s up.

Test transmission 20140210

CP0x0d

Here’s Broken, a new two-sided single out on Chordpunch.

Creative Commons Licence
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

cover

Tidal cycles continued

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.

I should note that this is of course inspired by the long-lived sctweets tradition in the supercollider community.

Tidal cycles

I’ve started a twitter feed called @tidalcycles, with minimal tidal programs and their output. I’ll try to add one a day, but lets see how things go. Here’s the first couple:

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"]

Colourful texture

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.

Vocal

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 bug exposure

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:

https://github.com/yaxu/hstexture

.. and run it with something like runhaskell Main.hs