Looking for a more controllable fastcat

Inspired by the circuit vstplugin by xoxos, itself inspired by the tala structure in indian music, I would like to define a structure in my cycle by groups of 2,3 or 4 beats, and be able to dynamically map patterns to each group while respecting the measure structure.

or instance if I structure my cycle as [3,3,2] I have 3 groups, two of 3 beats and one of 2 beats. I tried to do something like this :

let
  groupP:: Int -> Pattern ControlMap
  groupP 2 = (struct "f t" $ sound "sd " # n "0")
  groupP 3 = (struct "t f t" $ sound "bd" # n "0")

d1 $ fastcat (map groupP [3,3,2])
d2 $ sound "bd ~ bd bd ~ bd ~ sd"

but that does not work as fastcat allocates each group to 1/3 of the cycle, so d1 is not in sync with d2. Is there some fastcat like function where I can better control the portion of the cycle allocated to each pattern in the list ?

did you try just the normal slowcat aka cat? sounds pretty good to my ears but i'm not quite sure what you are wanting to hear ultimately?

From what I understand he'd like d1 and d2 to play the same pattern (the first one being more controllable than the second and thus more interesting).

@abertier64 I'm pretty sure a careful use of ur could allow for that, if you're having trouble getting hold of it we can brainstorm that together!

Howabout inhabit?

let
  groups = [("a", (struct "f t" $ sound "sd " # n "0")),
            ("b", (struct "t f t" $ sound "bd" # n "0"))
           ]
in
d1 $ inhabit groups "b@3 b@3 a@2"

You could indeed do something similar with ur

3 Likes

I want to hear in d1 the pattern I have in d2.

I am not clear on how to achieve this with ur. I tried this :

let
  groups = [("a", (struct "f t" $ sound "sd " # n "0")),
            ("b", (struct "t f t" $ sound "bd" # n "0"))  ]
in
  d1 $ ur 1  "b@3 b@3 a@2" groups []

but the result is weird and not what I expect.

Yes ! inhabit seems to be the right tool. Now how could I generate the Pattern String "b@3 b@3 a@2" from an array of int [3,3,2] ? I always end up with something that does not match as the second parameter for inhabit...

inhabit seems to work most of the time, but I have a hard time making the second parameter more dynamic. selecting a literal string within an array works :

let   groups = [("1", (struct "t" $ sound "cowbell" # n "0")),
                ("2", (struct "f t" $ sound "cpu2 " # n "4")),
                ("3", (struct "t f t" $ sound "cpu2" # n "1")),
                ("4", (struct "f f t t" $ sound "cpu2" # n "10")) ]      
      inhabitable2 = ["3@3 3@3 4@4 3@3 3@3 ",
                      "3@3 2@2 4@4 3@3 4@4 ",
                      "3@3 3@3 4@4 4@4 2@2 ",
                      "4@4 2@2 2@2 3@3 2@2 3@3 ",
                      "2@2 2@2 4@4 2@2 4@4 2@2 ",
                      "3@3 3@3 3@3 3@3 3@3 1@1 ",
                      "2@2 2@2 3@3 3@3 3@3 2@2 1@1 "  ]

do
  x <-  randomRIO (0,99)
  d1 $  timeLoop 2 $ slow 2 $ inhabit groups (inhabitable2 !!! x)

but I could not find a way to dynamically get [3,3,2] to "3@3 3@3 2@2" in a way that was working with inhabit : most of the time I have type errors, and in some cases I have no error but nothing seems to happen...

Any idea how to dynamically generate the Patten String expected by inhabit as second parameter ?