Week 4 lesson 2 - random marathon: rand, irand, mininotation randomness, scramble, shuffle, choose + more

Hey @vin would you mind explaining a bit what the "do" line does? Is this necessary for declaring variables?

1 Like

Hey @julianmrn5, in the above it is pseudocode. But in reality it encapsulates everything below it that is indented by one tab (or more) into a single execution. I’m not sure how variable scopes work in Haskell/Tidal but to my mind if in the above pseudocode the subsequent Dirt connections were indebted correctly then those variables would be local in scope. When I get in front of a computer I can paste in some actual code if that would be helpful? I can’t answer about the necessity for variables but I reckon @yaxu or @eris (I think) can give better answers around variable creation and scope!

1 Like

Ah I missed this question sorry !

You can give names to values with

a = "bd sn"

and then use them

d1 $ s a

With older versions of haskell you have to use let

let a = "bd sn"

that's still useful for naming more than one value at once:

let a = "bd sn"
    faster = fast 2
    squizit = (# squiz 4)

d1 $ squizit $ faster $ s a 
3 Likes

That is a super interesting question!

I tried the snippet myself and I'll give you my interpretation: since you are asking scramble to create 8 pieces from a 4-piece long pattern, it will fill the pattern up with some fictive steps of silence.
That is, the pattern to scramble might look something like
n "0 1 2 3 ~!4"
And that is probably why I hear silence now and then when I play it.

(although I would love @yaxu to confirm or refute)

Ah missed this question! Yes, sort of.

scramble 8 "a b c d" chop the pattern into eight parts, being the first half of a, then second half of a, then first half of b, second half of b and so on. Then you scramble them, and you will probably end up with two or more second halfs in a row, which will sound like a gap, because only the event starts actually trigger anything. You'll also end up with two or more first halfs in a row, which will sound faster.

1 Like

OMG how much I love the | operator!

One question: what is the highest value (i.e. probability) that wchoose can take on?

A side thing: I was quite sure that random generators were lazy i.e. they gave a number only when asked, but you say that they are continuous in their generation. What is the rate of generation then?

Aaah!
So the fact that I hear silence is just a byproduct of the length of the sample - if I had a longer one then I would be listening to the second halfs?

There's no real limit apart from the underlying haskell type which will be big enough. If you have two elements, one with '1' and another with 999999, then the first one would have a million-to-one chance of being picked.

There's one number for every possible point in time, counting from when the cycle counter started (usually when you start tidal, unless you use something like resetCycles).

Time in Tidal is infinite, both in terms of how long things can last and in terms of detail. So there are an infinite number of random numbers even in the first cycle.. So when I say continuous, I mean continuous.. We call these laptops digital computers but they can represent analogue things perfectly. Of course computer memory isn't infinite so there are some constraints :wink:

1 Like

Hm this is tricky to explain. When I say first / second halves I'm talking about tidal events. This is a confusing thing with Tidal.. You chop up these events but it's only the start (onset) of the event that actually triggers a message to SuperDirt. So currently the second half of an event does nothing in a lot of cases.. Does that make sense?

Yes sort of.
I can then deduce there is a difference between e.g. chop and scramble - the former creates new Tidal events from a single event whereas the latter just chops the event.

If I take this example:

d1
    $ scramble "<4 8>"
    $ slow 2
    $ chop 8
    $ s "bev:1"
    # legato 1

when the no. of parts to scramble equals the no. of parts in which bev is cut, 4 events per cycles are triggered - thus bev is now a series of Tidal events. Do I understand correctly?

1 Like

About repeatCycles, is there a way to lock a cycle and mutate it on evaluation ? I tried with
reapeatCycles 1 but evaluating the code doesn't change anything.
Also is there a way to include resetCycle in code (in order to do stuff like every 4 (resetCycle)

Last question, in the following code i can't get the octave offset working. Am i doing it wrong? :

d1 $ shuffle 12 $ up " 0 1 2 3 4 5 6 7 8 9 10 11" + "[0|12|48]" # s "arpy "

Tnx :slightly_smiling_face:

timeLoop lets you loop the given number of cycles. There's not a straightforward way to play a different loop on each evaluation, but here's a complicated way:

do
  x <- (toRational . floor) <$> randomRIO (0, 9999)
  d1 $ timeLoop 1 $ rotR x $ n (struct "t(5,8)" $ irand 8) # sound "newnotes"

No, but that's a nice idea. I've made an issue for it: https://github.com/tidalcycles/Tidal/issues/658

It just needed parenthesis:

d1 $ shuffle 12 $ up ("0 1 2 3 4 5 6 7 8 9 10 11" + "[0|12|24]") # s "arpy"
2 Likes

@yaxu Ok thank you.

I thought about something else that would better suit my needs (but i didn't managed to make it work) :

setI "x" $ 1
d2 $ repeatCycles "^x" $ s "bd([3|5],8) [sd8|sn4]" # gain (rand + 0.2) # legato (rand)

from there i could try something like that:

setI "x" $ 1 + 9999*1

then switching the last 1 to 0 would activate pattern randomization, and switching back to 1 would activate repeatCycle.

Why does randomisation only happen every cycle :thinking: (and not every note) ?

I can't get this code to evaluate without errors complaining that randomRIO is out of scope. I tried to import System.Random but it seems it is not allowed in Tidal... What is the trick to access randomRIO ???

Hm, this should indeed make it available:

import System.Random

You'll have to run it as a single line on it's own

I get this error

t>: error:
    Could not load module ‘System.Random’
    It is a member of the hidden package ‘random-1.2.0’.
    You can run ‘:set -package random’ to expose it.
    (Note: this unloads all the modules in the current scope.)
    It is a member of the hidden package ‘random-1.1’.
    You can run ‘:set -package random’ to expose it.
    (Note: this unloads all the modules in the current scope.)

OK by trial and error, I found that if I add
:set -package random
at the top of BootTidal.hs and then reboot tidal then I can import System.Random with no error and then evaluate the do section.

Ah sorry for not replying before, that sounds like a good workaround!

d1  $ shuffle 8 
    $ slow 1
    $ up 
    ("<[0|-12|2][0|3|5]>*4[0|3|5]*4[3|5|9]*4[7|5|9]*4" 
    + "[-24|-12|-9][-24|-15|-12][-15|-12|0][-24|-12|12]" + "24" + "<-9 -5 4 7>") 
    # s "pluck" 
    # legato 3
    # room (range 0.1 1 $ slow 1.5 perlin)
    # sz (range 0.4 1 $ slow 2 perlin)
    # dry (range 0.4 0.8 $ slow 2.2 perlin)

Medieval

1 Like

@yaxu Could you pls hint why something like this does not seem to work. I'd like to select a bunch of samples for each option or select a bunch of sample folders for each option but I cannot get it to work.

d1 $ s (segment 8 $ choose ["[bd:1|bd:2|bd:3|bd:4]", "808", "hh"])