Implementing somthing like SonicPi's rings


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

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?



What would be the difference between ring [1,2,3,4] and “<1 2 3 4>”?



Great question! cat and the angle braces get really close. The main difference too me seems to be that when using those functions the time until the next value in the ring is always the same size (1 cycle unless fast or slow is applied) and access is deterministic. In sonic pi, you could choose to fetch the next value randomly and that would affect the speed at which new values are gathered.