Methods for Pattern Interactions

I'd love to discuss different methods for having patterns interact with each other.

Let's say I have a stack with 5 or 6 drum patterns... I have a clap that happens infrequently and randomly, and I'd like all of the other drums to drop out whenever it hits. Or maybe I have some decay automation on the kick drum and it would be nice if the inverse of this automation made the cymbal decay shorter, for instance. What would be some methods for making these happen?

I've been chatting with @kindohm about it, and he suggested a few options, like putting a conditional pattern above the stack and using const to mute all of the other patterns and only play the new one.

d1 $ every 4 (someCyclesBy 0.4 (within (0.33, 0.5) (const $ s "~ cp ~"))) $
  stack [
  ...,
  ...,
  ]

This works nicely for the clap example above but are there other ways to achieve this that you can think of? He also suggested looking at while but I have yet to explore boolean options much.

For the automation option I could probably assign it to a variable and multiply it as I see fit. But I'd love to open this to a wider discussion about pattern interactions in general. Seems like an important topic and I'm curious if others have thought about it and found solutions.

5 Likes

I've been thinking about this as well. I want to try things like using a pattern applied to a sound (probably to struct) and then use the same pattern and applied i.e. an inversed version to gain. I imagine smth like this

let ptrn = "t(3,8)"
d1 $ stack [
struct ptrn # s "bd",
fast 2 $ struct "~ t" # s "cp" # gain (0.9 |*| (inv $ ptrn)) -- I should check the correct operator
]

But I should read the docs on how to combine patterns (structure and values).

3 Likes

I need to do more tinkering with this, but there could be some nice things to do with fix and contrast.

4 Likes

yeah, I've done things with fix but it gets confusing (and I think its heavy on the cpu) fast. I didn't know about contrast, 'll check it out!

1 Like

Contrast and fix look pretty powerful!

Here's a way with state:

setB "clap" $ slow 4 $ scramble 16 "t!3 f!13"

d1 $ mask (inv "^clap") $ sound "bd*16"
d2 $ struct "^clap" $ sound "clap:4"

Then you can update the binary pattern on the fly:

setB "clap" $ shuffle 4 "t(7,16)"
setB "clap" $ chunk 8 (fast 16) $ shuffle 4 "t(7,16)"
6 Likes

niiice. I should start using state and all the new "tidal can count" new stuff

In my experience, it's difficult to achieve wholesale pattern swapping if you want exact timing of when that swap happens. This is the const and within approach that @ben has shared and that I've used in the past. It results in a really dramatic change, but it requires a lot of Tidal code and a lot of trial and error with numbers and pattern placement. For example, what would be the correct within arc range of the cp event of ~ ~ [~ [~ cp] ~]? It's a contrived example, but it's not fun to figure this stuff out. Sometimes it's worth it though.

I think Tidal shines when you let it work in its own ways with as little code as possible.

I've had success doing pattern swaps with boolean patterns, sew, stitch, and conditional changes with while. The results are a weird exchange of different patterns, but you lose a little control over the exact frequency and placement of the changes. But I think this is a fun thing.

2 Likes

wait what is this setB?

3 Likes

I have exactly the same question about setB xD

It puts a boolean/binary pattern in the state dictionary - the same dictionary that you update by sending OSC (or via the mapping in supercollider, MIDI) control data to tidal or by using one of the work-in-progress counting functions. There's setF for floating point patterns, setR for rational/time patterns and so on.

4 Likes

In which version of tidal does setB is implemented? I'm running 1.7.4 and it seems it is not defined (neither setF nor setR)...

aah, I see these are typed on the BootTidal file!

3 Likes