Get min and max values from the buffer~ without playing it

i.m.klif's icon

Hi

I'm trying to get maximum and minimum values from the buffer~. So far I can only get them by playing the buffer~ and running it through minmax~. I would prefer to do it without playing the buffer. Is there some way to do this?

Klif

Floating Point's icon

javascript to the rescue!

save this code as bufMinMax.js :

outlets = 2;
var buf;
function bufname(name)
{
     buf= new Buffer(name);
     var frames = buf.framecount()
       var samples = new Array;
           samples= buf.peek(1, 0, frames);
           var max= -99999999.;
           var min = 99999999;
    for (var i=0; i<frames; i++){
            if (samples[i]>max)
            max=samples[i];
            if (samples[i]<min)
            min=samples[i];
                }
        outlet(1, max);
        outlet(0, min);
}


then load this patch:
Max Patch
Copy patch and select New From Clipboard in Max.

only works for single channel buffers, but you could adapt the code

i.m.klif's icon

hey, thanks a lot :)

this is very neat solution. clean and efficient.

any hints on how to adapt this script to 3 channel buffer? i never worked with js so don't know where to start :(

klif

Floating Point's icon

the 1st arg in this:

buf.peek(1, 0, frames);

is the channel nmbe

kbd n wkng :-(

i.m.klif's icon

hahahaha. hope your keyboard gets well.

i.m.klif's icon

so i could make 6 outputs, and repeat routines with appropriate channel numbers.

buf.peek(2, 0, frames);

buf.peek(3, 0, frames);

i.m.klif's icon

actually i just made multuple js objects with code modifications- one for each channel. so fa so good. thanks again :)

i.m.klif's icon

hm, i suspect possible bugs here.

i get different results from minmax object and js. both are kind of inconsistent.

i made a test patch that demonstrates this behaviour. will post it to forums in a separate thread.

test js buffer minmax.maxpat
Max Patch

i.m.klif's icon

and javascript

bufMinMax.js
text/javascript 0.38 KB

Floating Point's icon

ok got a new keyboard;-)

you've got a number of small errors in the patch, mainly to do with message ordering--

here's a modified version:

Max Patch
Copy patch and select New From Clipboard in Max.

note that the float outputs of minmax are consistent with my js version-- the sig min output goes to zero because the input goes to zero (output of play~) when it gets to the end of the buffer

Floating Point's icon

here's a version which allows you to specify the channel:

outlets = 2;

var maximum;
var min;
var samples = new Array;
var frames;
var buf;
var name='';
var chan=0;

function bufname(_name)
{
    buf= new Buffer(_name);
    frames = buf.framecount();    
    
    if (name !== _name) //if buffer name is changed reset channel to zero
        chan=0;
    name=_name;
}

function channel(_chan)
{
    if (_chan>0)
        chan=_chan;
}

function bang()
{
    if(name!==''){
        if(chan>0)
            calculate();            
        else
            post("No channel specified \n");
    }
    else
        post("No buffer specified \n");
}


function calculate()
{    
    maximum= -99999999.;
    min = 99999999;    
    samples= buf.peek(chan, 0, frames);
    
    for (var i=0; i<frames; i++){
        if (samples[i]>maximum)
            maximum=samples[i];
        if (samples[i]<min)
            min=samples[i];
    }
outlet(1, maximum);
outlet(0, min);
}

note that it needs a bang to trigger calculation, once buffer and channel messages have been received.

here's a patch to demo it

Max Patch
Copy patch and select New From Clipboard in Max.

i.m.klif's icon

thanks a lot

there is still a problem with js. it behaves the same in my patch and your corrected patch - if you crop the buffer few times it starts reporting 0 as minimum altough it is impossible. in my patch, when i press (253, 254) message box i get 0 as minimum - can you reproduce on your computer?

Floating Point's icon

well the message box shouldn't have a comma in it, but aside from that I think you might have discovered some sort of a bug. the minmax works when cropping some values (100ms) but not others (250ms). I thought it might be to do with converting ms to samps but that doesn't seem to be the case. Here's a patch that should work (but doesn't sometimes)

Max Patch
Copy patch and select New From Clipboard in Max.

i.m.klif's icon

comma in a message box means it first sends 253 and then 254 - it's an old max feature. and that was the intention. this seems to be a bug. it is repeatable and makes no sense.

unfortunately i need it to work all the time. i'll file a bug report.

thank you for your help again - i really like js solution to this problem.

Floating Point's icon

yes I used commas in message boxes in an example patch I posted earlier-- the way you do it doesn't make sense because you crop it to 253 ms then 254 ms which is bigger than the first crop; also what's the point of cropping twice in quick succession...?

but let me know how you go with any response from your bug report...

i.m.klif's icon

ah, yes, i reversed the order. sorry, didn't realise that.

cropping slow and fast gave same results - that's why i did it this way.

i.m.klif's icon

god.... i made so many small mistakes in my patch..... i guess i'm getting a bit rusty :)

but i still get the same strange behaviour

i.m.klif's icon

i think i got it.

it has to do with lenght of the buffer (as reported by info~). see attached patch. this is consistent with the behaviour in my bigger patch (with 3 channel buffers).

floating point korekcija 7.maxpat
Max Patch

i.m.klif's icon

maybe try (i) in js to count to one value less that the lenght of the buffer?

Floating Point's icon

you didn't include the bufMinMax3 file, but I get it-- that's very strange behaviour-- excellent detective work btw-- you should probably report it, or at least seek an "official" explanation from c74. did you try only looping to i<frames-1? did that work?

i.m.klif's icon

could you try to make the script that counts to one value shorter than the whole lenght of the buffer? i suspect that might be a quick fix?

Floating Point's icon

just change

i<frames

to

i<frames-1

i.m.klif's icon

yeah!

that's it man :)

i.m.klif's icon

now it works as expected.

in what units does javascript measure buffer? how do frames relate to miliseconds? i guess the problem was that it rounds the value to a slightly longer duration, and reports 0 as there is nothing written there (altough it doesn't make sense as buffer is as long as the sample is).