Now that we’re on the other side of the gig, I’m able to reflect on some of the other things that happened leading up to it.
The one that’s relevant here is that at one point while I was doing some coding on a plane, I noticed I was getting all kinds of errors in one of my patches which I wasn’t getting before. It turned out it was because my headphones set my sampling rate to 48k, which broke a lot of the time-based settings/@attributes
/etc… in my patch.
I decided to somewhat sanitize “time” for that patch by putting in a loadmess
followed by a mstosamps~
, which is easy enough, but it struck me that this will start to become much more complicated as we move forward into TB2 and/or start dealing with musically-relevant units of time (i.e. @tremblap’s APT (ATP?!) stuff).
It seems that if one of the central ideas of the project is to have interoperability, having patches that break when other sampling rates are used isn’t ideal.
Obviously there are some simple things one can do, like setting analysis windows (which are conceived in ms) in ms and dynamically setting them in the patch based on the sample rate being used. Easy peasy.
Where it gets more complicated is where statistics come into play.
For example, in @tremblap’s APT patch, there is a section that is computing statistics for different ranges of frames:
startframe 2, numframes 6, bang, startframe 7, numframes 9, bang, startframe 15, numframes 31, bang
This is only correct at 44.1k. If you go to 48k you’ve “sped things up”, and if you go to 192k you’ve all but reduced the meaning and usefulness of the overall idea.
This can be programmed around, but it requires a lot more surrounding code, for each individual object (ms->samples->frames/offsets->attributes), and also adds more surface area for errors, since I don’t know about you, but I don’t often test my patches at other sample rates.
//////////////////////////////////////////////////////////////////////////////////////////////////////
Something I remember mentioning very early on (I think at a plenary, as I was unable to find it on the forum) is that we tend to think (and speak) in units of time. Like the onset of a sound being within the first 50ms or whatever. Or analyzing 1000ms of audio. An onset doesn’t happen within the first 2205 samples of audio, as that’s a non-specific amount of time. This is obviously critical when trying to decompose and/or reconstruct audio based on temporal units.
I understand the usefulness of having frames/samples as consistent units of processing and audio, since fft stuff happens in that domain, since the alternative can be potentially setting the (presumed) @starttime
@numtimes
in fractional times (i.e. 3.5818ms start time and 13.45351 analysis window) would be super awkward.
But now we have a situation where a significant part of the shared/included code, and nearly all the code that is time-series-specific, is presumed to be at 44.1k. In the best case we get something where the process just happens “faster”. Not great, but not the end of the world. But the bigger concern is where things break and/or throw error messages, as happened to me in one of my patches.
So this thread is mainly about talking about a ‘best practice’ that we can establish, to make patches sample rate agnostic (particularly when it comes to pesky @startframe
/ @numframes
in statistical contexts) and/or coming up with a programmatic solution to this (perhaps something like a @relative
flag in buf-based objects (so that @numframes
/ @startframes
are computed relative to 44.1k).
Maybe this is the job for abstractions, tagged onto every fluid.buf...
object, but if that’s the case, it would be worthwhile establishing some kind of ‘house style’ for that, to make things easier to deal with in the future.