maybe this can be useful for someone someday. Atm, it is only to have organized what I have been learning in Tidal.
d1 $ palindrome $ --- is the same as
d1 $ every 2 (rev) $ n
d1 $ iter 4 $ sound
d1 $ sound $ scramble 3 "xxx*3"
d1 $ every 4 (0.25 <~) $ sound
d1 $ "<0 0.5 0.125>" <~ sound
d1 $ "[0 0.25]/4" <~ (sound " ")
d1 $ linger 0.25 $ sound
d1 $ linger "<0.25 0.5 1>" $ sound
d1 $ every 2 (linger 0.25) $
d1 $ trunc "<0.75 0.25 1>" $ sound
d1 $ zoom (0.25, 0.75) $ sound
d1 $ every 4 (zoom (0.25, 0.75)) $ sound
d1 $ sometimesBy 0.25 (somefunc) $ sound
d1 $ degradeBy 0.9 $ sound
d1 $ brak $ sound
d1 $ swingBy (1/3) 4 $ sound
# somefunc (sine*2)
d1 $ sound "bd(3,8) sn(5,8)"
d1 $ sound "bd(5,8,2)"
d1 $ e 3 8 $ sound "bd*2 [sn cp]"
d1 $ sound "bd([5 3]/2,8)"
d1 $ someCyclesBy 0.25 (fast 2) $ sound
d1 $ foldEvery [3, 4, 5] (fast 2) $ sound
d1 $ every' 4 0 (somefunc) $ sound
d1 $ every' 4 2 (somefunc) $ sound
d1 $ fit' 1 4 (run 4) "[0 3*2 2 1 0 3*2 2 [1*8 ~]]/2" $ s ""
d1 $ spread slow [2,4/3] $ sound --- is the same as
d1 $ slow "<2 4/3>" $ sound
d1 $ spread ($) [fast 2, rev, slow 2, striate 3, (# speed "0.8")] $ sound
d1 $ fastspread slow [2,4/3] $ sound --- inside one cycle(?)
d1 $ within (0, 0.5) (fast 2) $ sound
d1 $ within (0.75, 1) (# speed "0.5") $ sound
d1 $ chunk 4 (somefunc) $ s
d1 $ seqPLoop [
(0, 16, s "" ),
(16, 32, s "" )
] # n (irand 16)
d1 $ randcat[
s " ",
s " "
] # n ( irand 16 )
d2 $ stack [
s " ",
s " "
] # n (run 16)
d2 $ seqPLoop [
(0, 32, stack [
slow 2 $ s " " # gain 1.5,
s " " # gain 0.8
] ),
(32, 64, stack[
s " ",
s " "
] )
]
d1 $ sound "xxx*4" # speed (rand + 0.5)
d1 $ n (run "<4 8 4 6>") # sound
(scale 0.25 0.75 $ rand)
# somefunc (slow 4 $ sine * 0.5 + 1)
# somefunc (scale (-2) 3 $ tri)
# somefunc (slow 8 $ saw)
d1 $ s " xxxx*4 " # n (choose [0,2,5])
d1 $ s (discretise 1 $ choose["kif", "kip"])
d1 $ s (struct "x ~ x ~ ~ x ~ ~" $ choose["kif", "kip"])
solo $ d1 $
t1 (clutchIn 8) $ sound
t2 (jumpIn' 1) $
The Slack Tidal channel is great to learn, but the information is ephemeral. So I put here conversations about something that I might want to use, or experiment with, or learn about.
I know this information can be put together from the tutorial, but I can't figure it out: How can I play a chord progression that lasts more than a single cycle (say, 6 quarter notes) every N cycles? assume 4/4 time. every 4 measures I want to play some notes, say
"c1 e1 g1 b1 d1"
, all quarter notes let me know if that's clear or not I know I can pitch notes with up or use midinotes to create the notes I can get something to happen every 4 measures using every 4, but this seems like a hack:
d1 $ every 4 (const $ sound "bd") $ sound "~"
guess I use slowcat to create a pattern longer than a single cycle
You can use slow and fast to change the speed of a Pattern, not just ParamPatterns.
is this what you want?
"<[c1 e1 g1 b1] [d1 ~ ~ ~] ~ ~>"
d1 $ s "pluck*2" # up (slow 8 "0 3 5 7")
Or even
d1 $ s "pluck*2" |*| up "[0,3,7]" |*| up (slow 8 "0 3 5 7")
If you want to get more advanced, you can apply a slow progression to multiple elements:
do
cps 1
let progression p = p |*| up (slow 8 $ "0 5 10 7")
let melody = progression $ stut 4 0.3 1.033 $ fast 2 $ up "0 3 7 10" |*| up "12" # s "pluck"
let bass = progression $ s "pluck" |*| speed "0.5" |*| gain "1.0" # shape 0.6 # cut "-1"
d1 $ stack [melody, bass]
@yaxu yes, that is what I want, can I slow that down so that it happens in 2 cycles I guess?
@efairbanks I dont get why the plucks are playing twice in your example, even if I remove *2
oh, I guess 8/4=2
d1 $ s "pluck" # up (slow 6 "0 3 5 7 9 11")
works
Yeah, and there slow is essentially changing the length of a cycle. So you could alternate between two melodies per cycle like so:
d1 $ s "pluck" # up (slow 6 "<[0 3 5 7 9 11] [2 4 8 11 13 15]>")
hmm I don't want to change the length of the cycle
It's only changing it local to the Pattern, not globally.
how do I get something that's "in time" with my other patterns?
Another way to think of slow is that it slows down the time that the pattern is receiving, so to speak. The pattern:
"<[0 3 5 7 9 11] [2 4 8 11 13 15]>"
is operating on a different time scale than the "pluck" pattern because you've slowed it. But you could then do.
d1 $ (s "pluck" # up (slow 6 "<[0 3 5 7 9 11] [2 4 8 11 13 15]>")) |*| up "0 7 12"
And the cycle
"0 7 12"
is being evaluated after all that, so it is operating at the normal time scale and will occupy one normal cycle.
I mean, not strictly. There are a lot of ways to achieve what you want to do. The
<>
mean "every cycle play the next element within <>" Where each element occupies one cycle. And then the whole thing is being slowed by a factor of 6.
okay, so there are six notes in those two cycles
6 notes in one cycle, 6 notes in the next. And because the whole thing is slowed by a factor of 6 after that, each cycle is 6 times as long as it normally would be. So each note ends up being the length of "one cycle" from a global reference point.
so I guess the alternative to
<>
isslowcat
?
an important point is that tidal has no fixed idea of what a beat is the reference point is (almost) always the cycle
hmm I got the impression a cycle was a measure
Yeah, cycles are more like units of time, and time is malleable in Tidal. Tempo is defined in cycles per second rather than BPM.
cps 1 == bpm 60
only if you put four events per cycle
^ depending on if you want to think of a cycle as a beat.
cps 1 feels like 120 bpm to me
why doesn't this work?
d1 $ slowcat [s "pluck*4" # up "[0 3 5 7]", s "pluck*2 ~ ~" # up "9 11 0 0 "]
but if you put three events in a cycle it'll feel like a different bpm
/@averageaht works for me
But!
This
"pluck*2 ~ ~"
Does not mean
"pluck pluck ~ ~"
It means
"[pluck pluck] ~ ~"
That's why it's playing the 9 twice.
The up pattern hasn't switched to 0 yet.
hmm for me it's playing the 9 twice
yes the second pluck will start 1/6th of the way into each cycle
d1 $ slowcat [s "pluck*4" # up "[0 3 5 7]", s "pluck pluck ~ ~" # up "9 11 0 0 "]
works the way you'd expect.
you can do
"pluck!2 ~ ~"
for that
btw @averageaht if you want to apply the same progression to multiple patterns, you can do stuff like this:
d1 $ slow 2 $
stack [s "bass:3(3,8)", s "pluck(5,8,2)" # up "24"] |*| up (slow 4 "0 5 7 0")
I can see how angle brackets are useful if cycle=beat. unfortunately they seem to just "not work" for me. I get: no synth or sample named 'nil' could be found. instrument not found: nil
well if you just want to repeat once you can do
"pluck ! ~ ~"
pluck !
has the same effect - number is optional:pluck !!!
That's cool as heck. Is there way to tell Tidal to continue the last note instead of cutting it off in the case of using cut or synthdefs as well? I heard something about _ but last time I tried it, it didn't work for me.
oh actually there is @
2017-07-02 ----------------------------------------------------------------------------------------------------
(n.a. this is cool! Promising!)
added this Smalltalk snippet
Tidal {
classvar ghci, ghciOutput;
*new {
^this.start();
}
*start {
if ( currentEnvironment.at(\tidal).isNil ){
~tidal = this;
ghci = Pipe.new("ghci -XOverloadedStrings", "w");
ghciOutput = Routine {
var line = ghci.getLine;
while(
{ line.notNil },
{
line.postln;
line = ghci.getLine;
}
);
ghci.close;
};
};
}
*send {
|message|
ghci.write("%\n".format(message));
ghci.flush;
}
*stop {
ghci.close;
~tidal = nil;
}
}
with a little help of @munshkr, it's possible to talk to tidal from supercollider
Tidal.start;
Tidal.send(":module Sound.Tidal.Context");
Tidal.send("(cps, getNow) <- bpsUtils");
Tidal.send("(d1,t1) <- superDirtSetters getNow");
Tidal.send(":set prompt ".format("tidal> ".quote));
Tidal.send("d1 $ sound % # release 0.25".format("kick".quote));
Tidal.send("d1 silence");
Tidal.stop;
A dope little trick that it deserves the spotlight: https://medium.com/potac/reusable-code-in-tidalcycles-59b7a4dba30a
2017-07-07 ------------------------------------------------------------------------------------------------------------
Ooh, hadn't realized that there's no reason custom effects can't also use parameters like n (or freq). Note-following filter:
~dirt.addModule( \lpf2, {|dirtEvent| dirtEvent.sendSynth("dirt_lpf2" ++ ~dirt.numChannels,
[cutoff2: ~cutoff2, freq:~freq, resonance:~resonance, out: ~out])}, {~cutoff2.notNil});
SynthDef("dirt_lpf2"++~dirt.numChannels, {|out, cutoff2=0, resonance, freq|
var sig;
sig = In.ar(out, ~dirt.numChannels);
sig = RLPF.ar(sig, freq*(1+cutoff2), resonance.linexp(0, 1, 1, 0.001));
ReplaceOut.ar(out, sig);
}).add;
2017-07-17------------------------------------------------------------------------------------------------------------
Hey gang. I'd like to choose a new value for a sine envelope each time that particular envelope has completed its full duration. This example chooses a new value for the sine envelope each cycle which is not what I want:
d1 $ s "bass1:4*8" # cut 1 # gain (slow (choose [1..16]) $ scale 0 1 $ sine)
That said, you can fake it for a finite amount of time with seqP
let randomList sn len = map (ceiling . (* sn) . timeToRand) [1..len]
let cycleSines sn len = seqP $ map (\(a,b,c) -> (fromIntegral a, fromIntegral b, slow (fromIntegral c) sine)) $ zip3 x0 x1 r
where x0 = take (length r - 1) $ scanl (+) 0 r
x1 = scanl1 (+) r
r = randomList sn len
so
cycleSines 16 100
will give you a series of sines with aslow
in the range 1..16, and repeat for 100 sine cycles, which in this case is about to cycle count 850 (because of the random lengths).
Note that due to the way "random" numbers work, this will give the same exact sequence each time you use the same
sn
andlen
. If you want to mix things up you can change up the[1..len]
in randomList
let randomList' sn len k = map (ceiling . (* sn) . timeToRand . (+ k)) [1..len]` would give a different result for different `k
- [further footnote,
sine
starts its cycle at its midpoint, 0.5, if you want the waves to "reset" their cycle at 0.0 I think you can just rotate it, replacingsine
with0.25 ~> sine
]
I realized mine doesn't work right - the phases aren't necessarily going to line up to be continuous.
ok try this eval these
import Sound.Tidal.Time
import Sound.Tidal.Utils
import Data.Maybe
then this
let randArcs :: Int -> Pattern [Arc]
randArcs n = do rs <- mapM (\x -> (pure $ (toRational x)/(toRational n)) <~ rand) [0 .. (n-1)]
let rats = map toRational rs
total = sum rats
pairs = pairUp $ accum 0 $ map ((/total)) rats
return $ pairs -- seqP $ map (\(a,b) -> (a,b,"x")) pairs
where pairUp [] = []
pairUp xs = (0,head xs):(pairUp' xs)
--
pairUp' [] = []
pairUp' (a:[]) = []
pairUp' (a:b:[]) = [(a,1)]
pairUp' (a:b:xs) = (a,b):(pairUp' (b:xs))
--
accum _ [] = []
accum n (a:xs) = (n+a):(accum (n+a) xs)
randStruct n = splitQueries $ Pattern f
where f (s,e) = mapSnds' fromJust $ filter (\(_,x,_) -> isJust x) $ as
where as = map (\(n, (s',e')) -> ((s' + sam s, e' + sam s),
subArc (s,e) (s' + sam s, e' + sam s),
n)
) $ enumerate $ thd' $ head $ arc (randArcs n) (sam s, nextSam s)
compressTo (s,e) p = compress (cyclePos s, e-(sam s)) p
substruct' :: Pattern Int -> Pattern a -> Pattern a
substruct' s p = Pattern $ \a -> concatMap (\(a', _, i) -> arc (compressTo a' (inside (1/toRational(length (arc s (sam (fst a), nextSam (fst a))))) (rotR (toRational i)) p)) a') (arc s a)
then this
d1 $ slow 16 $ substruct' (randStruct 16) $ sound "arpy*16" # gain (scale 0.5 1 sine) # speed (discretise 1 $ scale 1 2 rand)
a bit better:
d1 $ substruct (slow 8 $ randStruct 4) $ sound "arpy*8" # gain (scale 0.5 1 sine) # up (discretise 1 $ choose [0,7,12])
d1 $ substruct (randStruct 2) $ sound "arpy*8" # gain (scale 0.5 1 sine) # up (discretise 1 $ choose [0,7,12,2])
The first pattern sounds like it has no metronomic pulse when you play it on its own but when you add the second pattern you can hear that the cp always aligns perfectly with the start of every fourth repetition of the first pattern
d1 $ slow 4 $ substruct' (randStruct 4) $ stack [n (off 0.125 (+7) $ "e2 d4 e3 [~ g3]") # sound "superzow" # pan saw # lpf (scale 500 1000 sine) # lpq 0.3]
d2 $ slow 4 $ sound "cp" # shape 0.6
I was messing around with this and it feels like it might be slightly off at times choosing values while not at zero. Try this:
d1
$ slow 16
$ substruct' (randStruct 4)
$ s "bass1*64"
# gain (scale 0 1 $ sine)
# up (discretise 1 $ choose [0,2,3,5,7,8,11] + choose [0,12,24,36])
# n (discretise 1 $ choose [5,7,9,13,19])
# pan (discretise 1 $ scale 0 1 $ rand)
Ah! bgolds solution with
0.25 ~> sine
sorted it!