Shortcuts or higher-level Tidal functions for faster pattern composition

Have any of you developed your own custom functions or systems to more quickly make sound in Tidal? I mean, it doesn’t get much faster than d1 $ s "bd", but:

  1. Do you have specific rhythms that you always like to use?
  2. Are there specific combinations of Tidal functions that you always use together?
  3. Is there a way that you consolidate these things into a small function instead of working with a big block of code typed from scratch?

For example, I livecode against my drum machine all the time. To play a snare drum I do this:

d1 $ note "32" # s "midi" # midichan 1

I realize that this is MIDI code but I think this topic also applies to samples, so stay with me here. The above MIDI code is a bit tedious to type every time I just want to play a snare drum on my machine.

An improvement is this:

let snare = note 32 # s "midi" # midichan 1

d1 $ snare

And then I can easily play patterns against that:

d1 $ struct "t(<3 5>,8,<0 2 5>)" $ snare

or

d1 $ gain "1.25(<3 5>,8,<0 2 5>)" # snare

Since MIDI CC’s aren’t easily combined into the same pattern, I do the same thing for CC’s:

let snarePan = ccn 67 # s "midi" # midichan 1

d2 $ struct "t*16" $ ccv (range 0 127 $ slow 4 sine) # snarePan

But that CC pattern is still too much to type. Even better:

let snarePan = ccn 67 # s "midi" # midichan 1

let slowPan p = struct "t*16" $ ccv (range 0 127 $ slow 4 sine) # p

d2 $ slowPan # snarePan

(above code has not been tested)

So if those custom functions are defined automatically when Tidal boots up, now all I have to do is this:

d1 $ struct "t(3,8)" $ snare

d2 $ slowPan # snarePan

You could of course extrapolate this to samples:

d1 $ every 2 (sickRaveEffects) $ dopeRaveRhythm $ favRaveSample

The goal is simple chains of user-defined shortcuts.

Do any of you do things like this? If so, what is your goal? How do you achieve it?

2 Likes

I’d like to branch out a bit more because I feel a little stuck in one sound, but I often start a rhythm with just n (run 8) and use a “drumkit” sample directory (like feel). My first few steps are usually to write something like n (run 8 + "<0 1 0 2>" + "{0 1 3}%4") and then start messing with every.

I use inside m (every n f) a lot, and made a shortcut inev for it (that I keep forgetting to use).

1 Like

Well I’ve recently starting using tidal. So far I have:

wallOfSound p = (off (1/64) (#pan 0) . (#pan 1)) p
retrolizer r = notchf (range 20 20000 $ slow r $ sine) # notchq 0.5

where notchf and notchq are to custom params to a notch filter I added.
wallOfSound can probably be rewritten using jux I think, but when I wrote it I wanted to be as explicit as I could.

Also I have a couple of fn to handle MIDI/OSC data.

filterMidiKeys cond p = p + n(filterValues cond $ cP "[]" "notes")

keys p = (#octave 0) $ filterMidiKeys (>15) p

I have a Akai MPKMini controller and the first 16 notes are on the pads, so I want to filter them out.
Now I have to figure out how to remove “n” and replace it with a param so I can use in other contexts (#speed i.e.), but tidal is giving me an error (I thinks it has to do with infering types, and fn signatures…)

1 Like

let I’ve been meaning to put together a lot of pattern shortcuts, but these have lived in BootTidal for the past year or so.

let slowsine = (slow 4 (sine))
    slowersine = (slow 8 (sine))
    slowsaw = (slow 4 (saw))
    slowersaw = (slow 8 (saw))
    slowtri = (slow 4 (tri))
    slowertri = (slow 8 (tri))
    htime p = slow 2 $ p
    qttime p = slow 4 $ p
    dtime p = fast 2 $ p
    qdtime p = fast 4 $ p
    slow1 p = slow 1 $ p
    slow2 p = slow 2 $ p
    slow3 p = slow 3 $ p
    slow4 p = slow 4 $ p
    loop2 p = loopAt 2 $ p
    loop4 p = loopAt 4 $ p
    loop8 p = loopAt 8 $ p
    slice8 a p = slice 8 a $ p
    slice16 a p = slice 16 a $ p
    slice32 a p = slice 32 a $ p
    slice64 a p = slice 64 a $ p
    j p = jump $ p
    j4 n p = jumpIn n 4 $ p
    j8 n p = jumpIn n 8 $ p
    cl4 n p = clutchIn n 4 $ p
    cl8 n p = clutchIn n 8 $ p
2 Likes

So far, I see that usually functions for function composition cover most use cases. Then, all is mainly a matter of naming them well, the rest is just moving code. Have you had cases where you need functions that take other functions as arguments?

This was helpful, I was able to make CC oscillation easier/faster:

(should be properly indented)
sin a b c d = struct “t*64” $ ccv (range a b $ slow c sine) # “midi” # d
cc = s [
sin 30 60 4 $ s[c 1,c 2,c 3,c 4,c 5] # ch 0,
sin 50 60 8 $ s[c 1,c 2,c 3,c 4,c 5] # ch 1,
sin 50 60 2 $ s[c 1,c 2,c 3,c 4,c 5] # ch 2,
sin 55 60 6 $ s[c 1,c 2,c 3,c 4,c 5] # ch 3
]
d1 $ cc

And just making shortcuts for myself with function compositions.

I was trying something with euclid, but I’m seeing there are some limitations to that function.

Anyway, ‘up’ is a revelation too me right now in altering pitch. Simple way to create polymeter rhythms with midi:

d1 $ midichan “{0 ~ ~ 0 ~ ~ 0 ~, 1 ~ 1 ~ ~ ~ 1}%10” # “midi” # up “[10 20]*2 -4 15/2”

1 Like