In the same way you can inv a euclidean rhythm and produce a second rhythm, i'm trying to split time into four interlocking parts using two euclidean functions. The inv part i've got down, but i don't know how to subset a euclidean rhythm with another euclidean function.
Is there a way in Tidal to take a subset of a euclidean rhythm with another euclidean function? That is, a way to euclid a euclid?
euclid 3 5 of euclid 5 8
struct t(5,8) is like euclid 5 8 which is t f t t f t t f.
struct t(3,5) or euclid 3 5 is t f t f t
Applying the second to the first, (keeping only 3 out the 5 Trues, by alternating according to "euclid 3 5") would give t f f t f f t f. I'm dropping 2 Trues according to the order in euclid 3 5.
Since what I'm talking about would only make sense for when the parameters set to 5 in my example are matching, there are really on 3 parameters for this operation.
For euclid 3 5 of euclid 5 8, the syntax might be something like this euclidNested 3 5 8
euclidNested would be like first doing euclid 5 8 then applying euclid 3 5 to only the true values, resulting in t f F t f F t f, where the capital 'F's are the 't's that were converted (eliminated) by euclid 3 5.
I see the first euclidean rhythm as choosing the division of time and selecting an approximately evenly distributed subset. From that subset, the outer eucliidean rhythm selects a smaller subset (sub-subset) that is approximately evenly distributed.
Does this make any sense? If so is there already a way to do this?
although it works weeeeeird af (when using complex patterns, keep it one note and it'll work as expected, which seems to be your use case). i sent a message in the discord saying "this is unexplainable"
--ok this is just like euclid
d1 $ s $ distrib ["5","8"] "bd"
--ok sure, it distributes 4 notes between the 5,8 euclid
d1 $ s $ distrib ["4","5","8"] "bd"
d1 $ s $ distrib ["5","8"] "bd*8"
--that sounded like
d1 $ mask "t(5,8)" $ s "bd*8"
--ok, it sort of acts like a mask then
--mhmhm what if i use a more complex pattern
d1 $ s $ distrib ["5","8"] "bd*8 sd"
--wait! that doesn't sound like
d1 $ mask "t(5,8)" $ s "bd*8 sd"
--well, sure, maybe it doesn't mask. it takes each element as contiguous, so if a sound has already been started it'll still play it...
--wait no what is this
d1 $ s $ distrib ["5","8"] "bd*8 sd*3"
From the commit message, we learn that distrib is "for meta-bjorklund stuff", i.e. meta level euclidean rythms.
I think it would be good to document that it exists but write that it's challenging to completely grasp all interactions. Perhaps @yaxu can enlighten us about the design some day, or we will learn from experimentation / find an improved design.
Heh yes it seems distrib is a bit unpredictable - it's taking structure from both the boolean euclidean pattern that comes from the numbers and the pattern that it's working on, so you get a weird mash up. Changing a <*> to a <* in the implementation is enough to get a better behaved version that only takes the structure from the boolean pattern. It'll be fixed in the next release, or you can try it now by running:
import Prelude hiding ((<*), (*>))
_distrib :: [Int] -> Pattern a -> Pattern a
_distrib xs p = boolsToPat (foldr distrib' (replicate (last xs) True) (reverse $ layers xs)) p
distrib' :: [Bool] -> [Bool] -> [Bool]
distrib'  _ = 
distrib' (_:a)  = False : distrib' a 
distrib' (True:a) (x:b) = x : distrib' a b
distrib' (False:a) b = False : distrib' a b
layers = map bjorklund . (zip<*>tail)
boolsToPat a b' = flip const <$> filterValues (== True) (fastFromList a) <* b'
distrib :: [Pattern Int] -> Pattern a -> Pattern a
distrib ps p = do p' <- sequence ps
_distrib p' p