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

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: Patterning resets · Issue #658 · tidalcycles/Tidal · GitHub

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

@yaxu

I encountered 2 issues lately and i can't figure out the problem:

Here the repeatCycles 1 doesn't work anymore :

   d1 $ repeatCycles 1 $ n (struct "t(13,16)" (irand 4)) # s "cpu"

I don't know if i missed something but repeatCycles doesn't seems to work at all.
.
.

That line of code is sending an error:

   d1 $ n (struct "t(13,16)" (range 0 3 perlin)) # s "cpu" 

but that one doesn't:

   d1 $ n (struct "t(13,16)" (range 0 3 rand)) # s "cpu" 

The only difference is the use of perlin instead of irand.

1 Like

@martinmestres

repeatCycles 1 will repeat each cycle once, so won't have any effect. Are you looking for loopFirst or timeLoop 1 ?

This should fix the problem with perlin, I'll add the fix to the next tidal version.

perlinWith :: Fractional a => Pattern Double -> Pattern a
perlinWith p = fmap realToFrac $ (interp) <$> (p-pa) <*> (timeToRand <$> pa) <*> (timeToRand <$> pb) where
  pa = (fromIntegral :: Int -> Double) . floor <$> p
  pb = (fromIntegral :: Int -> Double) . (+1) . floor <$> p
  interp x a b = a + smootherStep x * (b-a)
  smootherStep x = 6.0 * x**5 - 15.0 * x**4 + 10.0 * x**3

perlin :: Fractional a => Pattern a
perlin = perlinWith (sig fromRational)
1 Like

Ok my bad... In fact I was just trying to understand the function because i never use it and I already have a little something for looping duties:

lock n offset = timeLoop n . ((offset |- (slow n $ run n)) <~)

:ok_hand:

1 Like

I love the discussion about engagement with randomness above.

One text that takes on randomness km creative processes in a really interesting way is Michael Cook and Simon Colton: Generating Code For Expressing Simple Preferences: Moving On From Hardcoding And Randomness" (2015, Proceedings of the Sixth International Conference on Computational Creativity).

The abstract:

Software expressing intent and justifying creative decisions are important considerations when building systems in the context of Computational Creativity. However, getting software to express subjective opinions like simple preferences is difficult without mimicking existing people’s opinions or using random choice. In this paper, we propose an alternative way of enabling software to make meaningful decisions in smallscale subjective scenarios, such as choosing a favourite colour. Our system uses a combination of metrics as a fitness function for evolving short pieces of code that choose between artefacts. These ‘preference functions’ can make choices between simple items that are neither random nor based on an already existing opinion, and additionally have a sense of consistency. We describe the system, offer some example results from the work and suggest how this might lead to further developments in generative subjectivity in the future.

Basically they displace the randomness from random number generator to comparator functions like >, < which they evolve using generic algorithms.

The example programs are silly but useful, e.g.

public int compare(int i, int j) {
    if ((i < i)) {
        return 0;
        return 0;
    }
    if (((j + i) < j)) {
        i = i;
        return -1;
    }
    else {
        j = -491;
        return 1;
    }
    return 0;
}

Another kind of randomness is something which is maybe better described by other terms, but random chains which are not independent from one another; stateful randomness, or path-depenedent randomness. Things like random walks etc.

1 Like

Hi! First time posting here as i'm a very new user/learner (started 3 days ago). I just have a quick question regarding the below:

Is there a way to apply ? to a group so that it affects the entire group and not the individual parts?

Also i just wanted to say thanks to Alex @yaxu for...

  1. making Tidal Cycles (it's awesome)
  2. for your tutorial videos. They are really great.

Thanks!
Chris

hi @chris_collis, you can use degrade or degradeBy to remove events of an entire pattern.

d1 $ degradeBy 0.5 $ sound "kick [clap:4 off clap:5] kick snare" # speed 1.5 should do the trick.

degrade = degradeBy 0.5 = ?

1 Like

No? They wanted to "affect the entire group", presumably "group" = " syntactic unit" (in brackets, or before *2 in my example). Can be achieved with struct (using different queries to show effect of randomisation)

ghci> flip queryArc (Arc 0 1) $ struct (degrade "1*4") ("bd sn*2 bd*4 sn*4" :: Pattern String)
[(¼>⅜)-½|"sn",¼-(⅜>½)|"sn"]
ghci> flip queryArc (Arc 1 2) $ struct (degrade "1*4") ("bd sn*2 bd*4 sn*4" :: Pattern String)

[(1>1¼)|"bd",(1¼>1⅜)-1½|"sn",1¼-(1⅜>1½)|"sn",(1½>19/16)-1¾|"bd",1½-(19/16>1⅝)-1¾|"bd",1½-(1⅝>111/16)-1¾|"bd",1½-(111/16>1¾)|"bd"]

previous discussion:
mininotation degradeBy operator "as a whole" · Issue #869 · tidalcycles/Tidal · GitHub ? notation location · Issue #742 · tidalcycles/Tidal · GitHub

1 Like

For this specific question, I am interpreting "group" as this particular grouping of samples:

"kick [clap:4 off clap:5]? kick snare"

and "[affecting] the entire group" to mean randomly remove events from this particular pattern.

I suppose you could just put the whole thing in brackets and apply the ? operator to it, like so:

sound "[kick [clap:4 off clap:5]? kick snare]?"

or you could use degrade which is maybe the more blunt-force way of achieving this

thanks for the reply and yes sorry I should have been clearer. I didn't mean the whole pattern but just the "group" of notes between the square brackets as in the below.

"kick [clap:4 off clap:5]? kick snare"

so I would like [clap:4 off clap:5] to either play or not play. i'm probably not explaining well as I don't know the terminology but thanks for the assistance :slight_smile:

if you want a random choice between

either kick [clap:4 off clap:5] kick snare (all of the events in the inner group)

or kick ~ kick snare (none of the events in the inner group)?

then d1 $ sound $ mask "1 1? 1 1" "kick [clap:4 off clap:5] kick snare"

(mask - not struct as I wrote above)

2 Likes