Order of expressions

Hi,

I apologize in advance because this is probably a true newbie question, but that is what I am: a real newbie. (Also apologies for the very generic and thus not very telling subject but I could not think of something better). I have some experience with Sonic Pi but I am very interested in Tidal and right now I am trying to grasp ... well, everything :wink: (... but not at once.)

I am working through the help docs (e. g. http://pages.tidalcycles.org, great stuff!) and did find Tidal Adventures by Carsten Heisterkamp quite helpful; that is because it has a section where Carsten sort systematically explains what I am working on right now: Composing functions the right way. So I sort of work within the hermeneutic circle, meaning, I read and try out general stuff, break my head over it, find details I dive into hoping to solve my initial question, reach some new limit understanding while doing this, go back to see the overall picture again and so on. So, nothing new under the sun, just the way I (we?) do learn new things.

So here is one of my questions which popped up while experimenting. I would be very grateful if someone could give a hint to understand the following:

d1 $ sound "pluck" # speed (choose [0.75,1,1.5])

... does make some sounds as expected and syntax and meaning is clear to me.

d1 $ speed (choose [0.75,1,1.5]) # sound "pluck"

... does seem to be okay, because I don't get an error but does not produce any sound.

Furthermore: I do understand what Tidal is telling me here:

sound "pluck" # speed (choose [0.75,1,1.5])
-- first example
-- (0>1)|s: "pluck", speed: 0.75f

But what is the meaning (and probably solution of my question) of:

speed (choose [0.75,1,1.5]) # sound "pluck"
-- second example
-- ~0>1~|s: "pluck", speed: 0.75f
1 Like

it is possible to move speed to the left of your sound pattern but some tweaks would need to be made first (see below).

d1 $ (# speed (choose [0.75,1,1.5])) $ sound "pluck"

remember that the output is dictated by the left-most pattern...in this case, you'd have one "pluck" occurring each cycle and speed is choosing from your list which value to apply each cycle.

2 Likes

Firstly, great sample choice, one of my faves :wink:

Secondly, I'm going to have a go at explaining this in a very rudimentary fashion (cause that's all I understand), in the hope that it can be expanded and I too can understand better:

I think of the items with $ preceding as functions, and # preceding as effects - and crucially, effects are not functions.

If you want an effect to apply where a function is expected (with a preceding $), you must use the syntax outlined by @kit-christopher by enclosing the effect (# and all) in round brackets.

1 Like

This comes down to the difference between:
(0>1)|s
and
~0>1~

The former is a discrete event, happening once per cycle. The latter is a continuous event, in this case an infinitely detailed random stream of numbers. The ~'s around the 0>1 indicate this - that it's sampling a value halfway between 0 and 1 (the first cycle, which is what gets printed out when you evaluate a pattern by itself like this), but that this is a continuous value, and if you queried a different part of that cycle you'd get a different value.

The reason you don't hear anything when you try to play a continuous pattern, is that it doesn't contain any discrete sounds to play - just continually varying values. To hear the values you need to apply some kind of transformation that does 'sample-and-hold'. One way to do that is by combining it with a discrete pattern (which is what the first example does). Another is to use something like segment or struct:

struct "t(5,8)" $ speed (choose [0.75,1,1.5]) # sound "pluck"`
segment 16 $ speed (choose [0.75,1,1.5]) # sound "pluck"`
2 Likes

I hadn't seen @CarstenH's tutorial by the way - it's really nice!

Although it looks nicer, https://pages.tidalcycles.org/ is actually the old version of the https://tidalcycles.org/ website and contains out-of-date information. The new website is a wiki, and had the advantage that it can be edited by anyone, and translated. The documentation is fragmented though, it does all need some love, including some design to make it look as good as the old site!

2 Likes

Thanks a lot to all of you for taking the time to give so much valuable input! I had a quick look at it but will need some more time to process ... :slight_smile: :smiley:

Ok, I guess that is an application case of what rule #4 of the mentioned Heistercamp article says:

If you want to use a function that returns a pattern [1] inside a function that takes a pattern of type ControlMap [2] , you need to evaluate it first with the bracket () notation, like juxcut (# speed 2)

[1] is function speed and [2] is d1. Hope that's a correct interpretation.

Still trying to understand the details because I a convinced this will help in the long run. So my understanding of the code right now is:

  • function sound expects param string, gets arg "pluck", returns ControlPattern
  • function choose expects list, gets "[0.75 etc.]" and returns pattern = one new value each cycle (?)
  • function speed expects double, gets return value of choose and returns ControlPattern
  • function (#) expects pattern on right side (?), gets ControlPattern from speed and combines this with return of sound to a ControlPattern (?)
  • function d1 expects ControlPattern ...

I guess, what sort of confuses me is that " # (and all its friends |+| , |*| , etc) are used to combine a pattern on the right with a pattern on the left" (quote from Understanding the $) but in

d1 $ (# speed (choose [0.75,1,1.5])) $ sound "pluck"

this seems to be a bit different (there is not really a pattern on the left, right?).

Wow. Still pondering about that... I'd be very grateful if you could elaborate on that. But it would also understand if you'd rather not ...

Ah, and thanks for the clarification about the docs. Actually I do prefer https://tidalcycles.org for the search function (but as you suspected, I was under the impression that this is the old version).

The above is exactly the same as:

d1 $ sound "pluck" # speed (choose [0.75,1,1.5])

There's just some weird 'plumbing' going on with partial application of # (the left hand side of the # is missing, resulting in a function that takes that as an argument..) to change the order of things but the result is the same.

I think a clearer way to switch around the order without changing the result would be:

d1 $ speed (choose [0.75,1,1.5]) >| sound "pluck"

# is shorthand for |>, and >| is the same but with the structure coming from the right..

1 Like

Basically any random source is an infinitiely detailed waveform, in the same way as sine etc, so doesn't contain events. I go into more detail in this video: Week 4 lesson 1 - continuous patterns - sine, square, tri, saw and random functions

You'll need to go through the pay-as-you-feel wall to see it though - (Paying 0 is all good if you don't have any money to hand!)
https://blog.tidalcycles.org/shop/

1 Like

Ok, I will watch. Glad if I can contribute this way at least a bit ...

Started watching the videos. I think once I've got through all of them (which will take a while) loads of questions will be answered. Thanks for making me aware of...!

1 Like