Choosing sounds with a Boolean list

I’m looking for a way (or more precisely, a better way) to apply a list of Bools to a list of notes or sounds to determine which ones get played. Sort of like mask, but applied vertically to a stack of sounds/notes simultaneously, not to successive events in a pattern.

So that if I had a list of samples (e.g., [“bd, “sn”, “hh”, “bass”, “can”]), I could apply a list (?) of Bools such as
[True, False, False, False, True]
and the result would be equivalent to
s “[bd, can]”
or applying:
[False, True, True, False, True],
it would be:
s “[sn, hh, can]”.

I have kludged together something that sort of accomplishes this, but it feels awful.

I convert the Bool list to an Int list such that the indices of the True elements of the Bool list are in the Int list, i.e, [True, False, False, False, True] becomes [0,4] or [False, True, True, False, True] becomes [1,2,4]

Then apply parseBP_E . show to my intList to make a pattern that I can use with fit, like so:

d1 $ s (fit 5 [“bd, “sn”, “hh”, “bass”, “can”], myKludgilyAssembledPattern)

There has to be less awful way of doing this, and I would really appreciate some guidance. FWIW, the use case here would be applying the output of a cellular automaton.

like this?

let pick :: [Bool] -> [a] -> [a]
    pick bs xs = map snd $ filter fst $ zip bs xs
in d1 $ s
      $ stack
      $ pick [True, False, False, False, True]
             ["bd", "sn", "hh", "bass", "can"]

but if you want the Booleans to be patternable, then take

let pick :: [Pattern Bool] -> [Pattern a] -> [Pattern a]
    pick bs xs = map ( \(b,x) -> b >>= \ f -> if f then x else silence) $ zip bs xs
in d1 $ s
      $ stack
      $ pick ["t" , "f  t" , "f" , "f"   , "t"  ]
             ["bd", "sn*2" , "hh", "bass", "can"]

in this variant, you need “sn * 2” for the “f t” to have an effect. This is a property
of the “bind” (>>=) operation.

2 Likes

Fantastic! Thanks so much.

I don’t really need to pattern over bools (but good to know!). I do need to cat together the outputs of a bunch of iterations of my function outputting the bools lis thought.

I probably doesn’t look like idiomatic Haskell, but this seems to work:

pickCat sounds manyBoolLists = cat . map (s . stack) $ map (pick sounds) manyBoolLists where
  pick sounds oneBoolList = map snd $ filter fst $ zip oneBoolList sounds

Thanks again!