Function to clamp note values

@eris mentions in this post using a helper function to clamp note values to within some octave range. This sounded like a really useful idea, and I thought I'd give it a try.

What I imagine would be something like this - It would take a note pattern, say
pt = n (scale "dorian" (run 16))

and a function like
clamp numOct = (|% (numOct * 12))

to constrain its values to numOct octaves. But this doesn't work because the |% operator expects real numbers. How would I get the output of a note pattern (using floats) to act as valid input for |%?

And obviously it would be much cooler if this function were patternable, i.e., could do things like
clamp "<1 2>" $ n (scale "dorian" (run 16))

How much extra leg work would be involved with that?

1 Like

Hey @crashingbooth!

The old version I had of this used withI to be smart about this and only operate on note params, so it could be applied to complex ParamMaps/Patterns rather than just numeric patterns.

I'd really like to figure out how to use something like contrast or fix to make this possible again, but in the meanwhile here's a little something that will let you do this similarly to using scale.

do
  let octceil by upper noteval = if noteval>upper then octceil by upper (noteval - by) else noteval
  let octfloor by lower noteval = if noteval<lower then octfloor by lower (noteval + by) else noteval
  let wramp lower upper p = ((octfloor 12 lower).(octceil 12 upper)) <$> p
  d1 $ s "pluck" + note (wramp 10 25 ("[7 0 3 0]*4" + ((* 7) <$> (slow 4 $ (run 8)))))

I've called it invert because what it does is much like the theoretical concept of "inversions" of chords, arpeggios, or other groups of pitches. I used to call it clampoctaves, which I think is a bit more intuitive but it's also somewhat verbose. Perhaps clamp is better. Unclear!

Invert is probably bad though now that I think of it, because it's doing more than that.

It's constraining pitches to a range by...wrapping them. Maybe wramp because it's wrapping and clamping?

3 Likes

Thanks @eris!

I like that this is more general than what I had in mind. And recursively adding or subtracting sidesteps the type issue.

I've added it as

wramp lower upper p = ((octfloor 12 lower).(octceil 12 upper)) <$> p where
    octceil by upper noteval = if noteval>upper then octceil by upper (noteval - by) else noteval
    octfloor by lower noteval = if noteval<lower then octfloor by lower (noteval + by) else noteval

to my BootTidal.hs

And I get the struggle to make names that are both accurate and easy to type. I've never had to worry about that before in languages that I wouldn't be live coding in. I generally go for overly verbose (and hopefully clear) names in other situations.

3 Likes