Ranking (fft frames) using only vanilla objects? (mp3-ification)
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:
framerank~ is an object to average the values of a specific number of fft frames.
typedef struct _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);
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);
void *framerank_new(long windowsize, long size)
t_framerank *x = (t_framerank *)newobject(this_class);
dsp_setup((t_pxobject *)x, 1);
x->indices = 0;
void framerank_free(t_framerank *x)
void combsort_indices_float (long *indices, float *data, long num_points)
long gap = num_points;
long swaps = 1;
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);
float *out = (float *)(w);
int vectsize = w;
t_framerank *x = (t_framerank *)(w);
long *indices = x->indices;
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)
x->indices = malloc (sizeof(long) * sp->s_n);
dsp_add(framerank_perform, 4, sp->s_vec, sp->s_vec, sp->s_n, x);
void framerank_assist(t_framerank *x, void *b, long m, long a, char *s)
if (m == ASSIST_OUTLET)
sprintf(s,"(signal) FFT Data In");
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.
Hi, did you get any further with this? I am experimenting with similar idea. Too bad framerank is only 32 bit…
Thanks! Still would be nice to have it vanilla… and perhaps be able to tweek the innards of the framerank somewhat for more variation.
…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!
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".
Forums > MaxMSP