Can patterns be separated from synth/sample declarations?

Hello!

I have a question about something that has been bugging me. First, I love TidalCycles! It is very concise and easy to use.

But I end up with things like this:

d11 $ slow 12 $ n (off 0.0 (+ 7) $ off 0.0 (+ 12) "d2 f2 a2 ~ c2 e2 g2 ~") # s "superpwm" 
# semitone 7
# pitch1 100
# resonance 5
# rate 120
# lfo 100
# accelerate 0.1
    # distort 0.5
    # delay 1 # delayt 2 # delayfb 0.5
    # room 0.4 # sz 0.4
  # gain 0.75

That is one layer, but it feels cluttered when many other layers get added. And I would prefer to focus on instrument and sound tuning separate from the pattern logic.

Is there a way to separate this: d11 $ slow 12 $ n (off 0.0 (+ 7) $ off 0.0 (+ 12) "d2 f2 a2 ~ c2 e2 g2 ~")

From this:

# s "superpwm" 
# semitone 7
# pitch1 100
# resonance 5
# rate 120
# lfo 100
# accelerate 0.1
    # distort 0.5
    # delay 1 # delayt 2 # delayfb 0.5
    # room 0.4 # sz 0.4
  # gain 0.75

Perhaps even put the longer part in another file?
Then Import it and send it live updated patterns?

I imagine something like this:

import skunk_rize
d11 $ slow 12 $ n (off 0.0 (+ 7) $ off 0.0 (+ 12) "d2 f2 a2 ~ c2 e2 g2 ~") # "skunk_rize"

As you might guess I am more comfortable with Python than Haskell.

Thank you for any advice!

Sure, you can do:

let skunk_rize = s "superpwm" 
  # semitone 7
  # pitch1 100
  # resonance 5
  # rate 120
  # lfo 100
  # accelerate 0.1
  # distort 0.5
  # delay 1 # delayt 2 # delayfb 0.5
  # room 0.4 # sz 0.4
  # gain 0.75

Evaluate it (also in another file, it doesn't matter) then:

d11 $ slow 12 $ n (off 0.0 (+ 7) $ off 0.0 (+ 12) "d2 f2 a2 ~ c2 e2 g2 ~") # skunk_rize
5 Likes

also, if you are not planning on using off to actually pattern offset, you might be interested in superimpose (or, in this case, layer), when building up your main sound pattern.

2 Likes

Oh thanks! I tried this with my bandmate and neither of us could get the 'let' statement to work unless it was all on one line. We tried in Troop and in Atom.

But that is fine really. Once the sounds are dialed in we can put everything in single line abstractions. Sorta minify the whole mess.

Cheers! :beers:

Thanks! Ima mess with those. I like layer so far because I can offset, or not. But I see how layer can be really succinct.

you might need to make sure every new line in the let statement is indented

.. is indented deeper than the variable that gets bound:

does not work:

let foo = s "bd"                                                                    
  # delay 1                                                            
         
<interactive>:14:3: error: parse error on input ‘#’

does:

let foo = s "bd"                                                                    
      # delay 1

(foo starts in 5th column, # is in 7th)

Source: https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-210002.7

1 Like

Ah hah! That worked great!

That is an odd indentation rule, but I can live with it!

Thank you! :pray:

For reference: Odd maybe, but well established. Haskell (1990) copied the "offside rule" from ISWIM (Peter Landin, 1966), and it goes back to CPL (Christopher Strachey, 1963) http://research.microsoft.com/~simonpj/papers/history-of-haskell/history.pdf (Section 4.1)