Get min and max values from the buffer~ without playing it
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
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:
only works for single channel buffers, but you could adapt the code
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
the 1st arg in this:
buf.peek(1, 0, frames);
is the channel nmbe
kbd n wkng :-(
hahahaha. hope your keyboard gets well.
so i could make 6 outputs, and repeat routines with appropriate channel numbers.
buf.peek(2, 0, frames);
buf.peek(3, 0, frames);
actually i just made multuple js objects with code modifications- one for each channel. so fa so good. thanks again :)
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.
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:
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
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
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?
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)
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.
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...
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.
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 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).
maybe try (i) in js to count to one value less that the lenght of the buffer?
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?
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?
just change
i<frames
to
i<frames-1
yeah!
that's it man :)
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).