Implementing Metric Indispensability for an Algorithmic Rhythm Generator

Leaf's icon

Hello folks,

I'm working on an algorithmic rhythm generator that produces rhythmic accompaniment in response to incoming MIDI notes from a kick and snare drum. I've been stuck on a problem for over a week now and am posting here as a last resort hoping someone could help.

I recently discovered the work of Clarence Barlow, specifically his formula for calculating "Metric Indispensability" of every pulse in a given meter. After a week of digging, I could only find 2 Max4Live implementations of this concept, namely kin.rhythmicator by George Sioros and Carlos Guerdes and DJester by Georg Hajdu. Unfortunately the formula in both of these devices are implemented in externals which are not compatible with Apple Silicon and there don't seem to be any plans to recompile them.

I also read this resource which helped immensely with understanding how the equation symbols translate into numbers. There is also a video and a python implementation by Marc Evanstein, a former student of Barlow's.

Unfortunately implementing it using only Max objects proved far harder than I thought.
For instance, to calculate the value of Ψp_z-1(x) : I'll need to do something like [if p==2 then p-n else if n==p-1 then p/4 else p(n) = (q+ 2 sqrt (q+1/p)] — where q = Ψ_p-1(n - [n/p]) — and it doesn't seem like the [if] nor [expr] objects are capable of evaluating these kinds of expressions.

Here's my attempt (I didn't get very far at all), I only managed to figure out the fraction portion of the equation, but I'm still passing in the $i1 $i2 $i. . . values as static values rather than deriving them from the list of prime factors. Another approach I was thinking of was to implement this in js, although I have no zero experience with the language (I only started learning Max about 2 months ago)

I'd be really grateful if anyone could help out or point me in the right direction. I've spent the entire week hyperfocused on this one specific problem and it's starting to feel a bit dreadful that I can't really figure this out and there aren't that many resources on this topic.

IndispensabilityValues.maxpat
Max Patch

TFL's icon

I would do this kind of math in genexpr (use [codebox] in a [gen], or directly [gen.codebox]) instead of using plain max objects. Javascript is another option.

Roman Thilenius's icon

this is surely pretty easy to realize with basic max objects, but when i read texts like the one on the mutor website i already do not understand several things explained there about this overcerebralized concept.

if your aim is fun and composing music, note that a realtime application lacks looking backwards in time, algorithms which render offline could also take future inputs into account when generating its response...

Leaf's icon

Hey, thanks for the responses.

TFL, I'm indeed taking the Javascript route since I only have the bundled version of Max that comes with Live. Just started learning js last month so I thought I'd give it a shot. I'm stuck on a "too much recursion" error trying to implementing the "else" portion of the equation :

else Ψ_p (n) = q+2 [sqrt(q+1)/p]
where q = Ψ_p-1(n-[n/p])

Here's my js file (as a text file since js format isn't uploadable for some reason)
I'm not quite sure how to proceed here because the entire equation relies on the recursion part... maybe my functions are ordered wrongly, or maybe they should be nested within a larger function?

IndispensabilityValues.txt
txt

Roman, I'm curious how you'd realize this with Max objects themselves. I agree it is overcerebralized to some extent and wish it was much more straightforward. My intended application is quite simple in principle : to calculate which pulses within a given a meter should be weighted higher such that the "character" of the meter is retained even when using random to generate sequences. I know I could simply use a multislider or coll and input pre-calculated values, but then I'd have to calculate for every single meter.

Ideally I'd love to have an approach that works with both multiplicative and arbitrary additive meters, and can be changed in response to real-time rhythm detection based on certain rules that characterise my compositional style.

Also, can you elaborate on your last paragraph? I'm not sure I follow...