Forums > MaxMSP

Ranking (fft frames) using only vanilla objects? (mp3-ification)

Apr 13 2013 | 1:31 pm

I’ve been using this custom external for the ranking of fft frames to produce an mp3 type compression. I really dig the sound of it, particularly when used with bit/sample reduction or other extreme distortion.

Now what I have works great, but it’s mac only (which makes sharing the patch difficult), and is also 32bit. So I want to try to remove the dependency altogether, if possible.

Now I kind of understand sorting algorithms (framerank~ uses combsort if I understand correctly), but I have no idea how this kind of sorting is handled in Max, much less fft max.

Here is the patch and external.

And here is the .c from the xcode project:


#include "ext.h"
#include "z_dsp.h"

framerank~ is an object to average the values of a specific number of fft frames.

void *this_class;

typedef struct _framerank
t_pxobject x_obj;

long *indices;

} t_framerank;

void *framerank_new (long windowsize, long size);
t_int *framerank_perform(t_int *w);
void framerank_dsp(t_framerank *x, t_signal **sp, short *count);
void framerank_free(t_framerank *x);
void framerank_assist (t_framerank *x, void *b, long m, long a, char *s);

int main(void)
setup((t_messlist **) &this_class, (method) framerank_new, (method)framerank_free, (short)sizeof(t_framerank), 0L, A_DEFLONG, A_DEFLONG, 0);
addmess((method)framerank_dsp, "dsp", A_CANT, 0);
addmess ((method)framerank_assist, "assist", A_CANT, 0);

return 0;

void *framerank_new(long windowsize, long size)
t_framerank *x = (t_framerank *)newobject(this_class);

dsp_setup((t_pxobject *)x, 1);
outlet_new(x, "signal");

x->indices = 0;

return (x);

void framerank_free(t_framerank *x)
if (x->indices)
free (x->indices);

void combsort_indices_float (long *indices, float *data, long num_points)
long gap = num_points;
long swaps = 1;
long index;
long gap_index;
long i;

while (gap > 1 || swaps)
if (gap > 1)
gap = (gap * 10) / 13;
if (gap == 9 || gap == 10)
gap = 11;
if (gap < 1) gap = 1;

for (i = 0, swaps = 0; i + gap < num_points; i++)
index = indices[i];
gap_index = indices[i + gap];
if (data[index] < data[gap_index])
indices[i] = gap_index;
indices[i + gap] = index;
swaps = 1;

t_int *framerank_perform(t_int *w) // Here we just store the incoming vals if we are taking a sample and then decide when to output
float *in = (float *)(w[1]);
float *out = (float *)(w[2]);
int vectsize = w[3];
t_framerank *x = (t_framerank *)(w[4]);

long *indices = x->indices;
long i;

if (x->x_obj.z_disabled)
goto out;

for (i = 0; i < vectsize; i++)
indices[i] = i;

combsort_indices_float(indices, in, vectsize);

for (i = 0; i < vectsize; i++)
out[indices[i]] = i + 1;

return w + 5;

void framerank_dsp(t_framerank *x, t_signal **sp, short *count)
free (x->indices);
x->indices = malloc (sizeof(long) * sp[0]->s_n);

dsp_add(framerank_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n, x);

void framerank_assist(t_framerank *x, void *b, long m, long a, char *s)
sprintf(s,"(signal) Ranking");
sprintf(s,"(signal) FFT Data In");

Apr 13 2013 | 11:57 pm

Ok, thinking about this further I’m thinking I might be able to get there doing some kind of spectral gate, where only bins above a certain threshold pass through. Though not exactly ordered, it’s unlikely they would have the same magnitudes, so adjusting the threshold should drop out bins one at a time.

Basically like the spectral gate in the MSP examples.

Though this doesn’t sound as interesting as framerank. With a low setting in framerank you get all these fft/bubbly kind of things, where as the spectral gate sounds very gate-y regardless.

Not sure what’s different about those two approaches though.

Apr 14 2013 | 11:30 pm

Here’s a comparison between the two.

Jul 30 2016 | 3:11 pm

Hi, did you get any further with this? I am experimenting with similar idea. Too bad framerank is only 32 bit…

Jul 30 2016 | 3:20 pm

Nope, nothing further.

BUT you’ll be pleased to know framerank~ is now 32/64 (attached).

Jul 31 2016 | 5:15 am

Thanks! Still would be nice to have it vanilla… and perhaps be able to tweek the innards of the framerank somewhat for more variation.

Jul 31 2016 | 8:22 am

…and still get some error message trying to use it in 64bit max: "msp object needs to be updated for msp64", but you are sure it is recompiled? Thanks for all help!

Jul 31 2016 | 8:29 am

Ah weird, yeah I see that. I guess I hadn’t tested it properly since I’m still running 32bit for the most part.

It’s also a different type/color error too, I’ve mainly seen that red "could not load" error, instead of this more polite yellow "framerank~: msp object needs to be updated for msp64".

Viewing 8 posts - 1 through 8 (of 8 total)

Forums > MaxMSP