Hi there,
Recently, I’ve been toying around with SonicPi and loved the way the ring
idea works in that language.
If you haven’t seen rings in sonic pi, they are basically infinite lists that you can continuously grab the next value from:
live_loop :foo do
notes = [36,38,40,42].ring
use_synth :tb303
play 32 notes.tick
sleep 1
end
In sonic pi the code above first plays note 36, then, on the next loop, plays 38 and so on. When it reaches the end of the ring, it starts over and you get 36 again.
I wanted to make something similar in tidal. I thought it might take the form of a function mapping a list of values over a pattern of events. Each event would get the next value in the list and when all the values were taken, it would start again at the beginning of the list.
Here is my attempt below:
ring :: [a] -> Pattern b -> Pattern a
ring xs structure = withEvents getRingValues structure
where getRingValues events = map (\(Event whole part v , x)-> Event whole part x) (zip events (cycle xs))
The problem is, when use it, it returns a pattern with first value of the list over and over again. Also, if I write the following:
d1 $ note (ring [0,1,2,3] $ "0*13") #s "gtr"
Tidal freaks out and can’t figure out if the “0*13” is a Pattern or a String.
So I have to write: d1 $ note (ring [0,1,2,3] $ euclidFull 11 16 0 0) #s "gtr"
(the euclidFull
is just in there to give it some rhythmic structure as ("0*13"::Pattern String)
bypasses the parser and gives me a pattern with only one event.
Does anyone know what I might be doing wrong?