Signal Rate vs. Frame Rate vs. Max Rate problem when analysing audio in Max/MSP

adamstark's icon

Hi,

I am working on a MSP object that does some audio analysis and calculates a single value from each audio frame of the incoming audio signal. Just as an example...

Lets say the sample rate is 44100 and the frame size is 512 samples, then we have 44100/512 = ~86 audio frames a second - and therefore ~86 analyses a second.

However, as I understand it the Max part of Max/MSP runs at 1000Hz. So at present, in the processing loop I am calling a function to output the data as a float (called using 'defer_low').

These leaves a couple of problems...

* I'm a little unsure of the resulting resolution of my signal, will it output around 86 estimates a second? Or does it re-sample to 1000Hz somehow?

* What if the audio frame size is just 32 samples? This means that there will be 44100/32 = ~1378 estimates a second from the signal, more than the 1000Hz Max rate. Unsurprisingly this crashes at present. Of course one solution is to not use frame sizes of 32 samples or less but I am trying to build software that anyone can use and I don't want to put lots of caveats about what frame sizes they can use.

Calculating a feature from an audio signal should be a fairly standard process. At present, either I am stuck with this method where I am not confident that I am getting an output at ~86 estimates a second [1 estimate per audio frame] or I have to output estimates at the signal rate and have to use something like 'snapshot~' to convert to a number...

Has anyone come across a good way to do this? Thanks in advance,

Adam

mzed's icon

Adam-
Although the Max scheduler can be set to run about once per ms (in preferences), it is probably better to think of these data as asynchronous. If you want output that is sample-accurate, you should stick with signals. Another factor that is going to affect timing for you is Max's audio vector size. Your perform routine will be triggered once per audio vector, which you should probably be detecting in your object. The Max scheduler can also be set to run in the Audio Interrupt: once per vector. That will tighten up the audio/control timing, but impose a granularity that you don't seem to want.

mz

mudang's icon

You can have a look the source code of the sigmund~ external as an example.

It has a circular input buffer, which gets filled in the perform routine.
The actual analysis is done in another procedure which gets called at a regular interval via max's scheduler (clock_new and clock_fdelay).

This way you can make the output timing be independant of the (input) vector size;

seabed's icon

Well, I am having more or less the same problem.

I want to calculate the median of an audio signal every second which means every 44100 samples. I am using zl.group and zl.median so that makes obligatory the use of snapshot. On the other hand, snapshot's minimum rate is 1ms, so obviously there is a loss in audio samples. Any ideas how to solve this?