How Do I Skip an Element?

I'm looking to play a long (circle) chord progression and I want steps in the progression to randomly drop out, but instead of silence I want the pattern to skip to the next element.

The ? lets elements drop out, but doesn't skip to the next one without silence.

There's a bunch of unshown variables, but here's the context:

prog = "<^one ^four ^seven ^three ^six ^two ^five>"

progRand = "<^one? ^four? ^seven? ^three? ^six? ^two? ^five?>"

p "chords" $ slow 2
  $ note (scale colorMain progRand)
  # s synth
  |+ note (fromInteger(key)) 
  # octave 3
  # legato 1
  # gain 0.75

I'm guessing what I want doesn't jibe well with how Tidal works and isn't (easily) possible. But figured I'd still ask.

Thanks!

Randomly advancing the clock

maybe something like this

-- pseudo-random monotonically increasing sequence [0,0,0,1,1,2,3,4,4,4 ... ]
offsets :: [Int]
offsets = scanl (+) 0 $ map (`mod` 2) $ iterate xorwise 424242

-- make pattern from (infinite) list. 
fromList ::  [a] -> Pattern a
fromList xs = segment 1 $ sig $ \ t -> xs !! truncate t

-- use the offsets to advance the clock
d1 $ fast 4
  $  ( fmap fromIntegral (fromList offsets) <~ )
  $ s "superpiano"
  + note (scale "major" $ slow 8 $ run 8)

such fromList should be in a library somewhere? It's risky though - it will traverse the list on each query, with linear cost in the index. Challenge: reduce to logarithmic

Long-winded explanation

for why there isn't a more direct solution

(I get similar questions often when I teach Tidalcycles. I have the following explanation, maybe it helps. If not, perhaps I can improve it.
I actually do need it next week.)

A pattern is a function from time to some domain of values. Time is unbounded, so these functions do not have a beginning, or an end. This implies

  • we cannot append patterns (play one first, then the other) - we can only merge them (slowcat : play one measure from each, in order)
  • we cannot skip a pattern (since it never ends)

This seems counter-intuitive

  • other systems of (algebraic) music notation (e.g., Haskore/Euterpea) do have patterns with lengths
  • Tidal's mini-syntax clearly does have elements. But that's purely syntactical - each of them still denotes a pattern in the above sense.

Now there's two options:

  • we can explain the above definition of pattern
  • or we can change it, because people 1. don't know, 2. don't understand, or 3. don't accept the explanation

Because of this, every N years there's an attempt to rewrite tidal's basic pattern type, and I really don't know the current status. Plans for tidal-2 were shelved? The pattern type in 1.10.1 is

-- | A datatype representing events taking place over time
data Pattern a = Pattern 
  { query :: State -> [Event a]
  , steps :: Maybe (Rational)
  , pureValue :: Maybe a
  }

here, State contains time, mentioned above. steps is new to me, and I am not seeing an explanation, except implicitly in the tests cases https://codeberg.org/uzu/tidal/src/branch/main/tidal-core/test/Sound/Tidal/StepwiseTest.hs

1 Like

see also earlier discussion (lazy fromList) https://codeberg.org/uzu/tidal/issues/695