Setting buffer sizes for BPM synced delays ?

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

When doing a delay plugin with a typical circular buffer, such as e.g. here
http://www.kvraudio.com/forum/viewtopic.php?t=226681

and say I want it
- BPM synced
- max. supported delay time: one bar (1/1)
- max. supported sample rate 192 kHz

Trying to calculate required buffer size:
With worst case scenario DAW tempo : 1 BPM => length of one bar (in 4/4) = 2400 [should say 240] sec. X 192000 samples / sec = 460800000 samples required buffer size.
If we process in double precision thats 8 bytes per sample: 460800000 * 8 = 3686400000 bytes ~ 3.6 GB RAM usage.
Ugh ! Is my calculation correct ?
How is this usually dealt with in BPM synced delays ?

edit:
Redone calculations (corrected seconds calc.) @ 1BPM:
using doubles, supported SR 192 kHz: : 240 * 192000 * 8 ~ 368 MB
using floats, supported SR 192 kHz: ~ 184 MB
using doubles, supported SR 96 kHz: : 240 * 96000 * 8 ~ 184 MB
using floats, supported SR 96 KhZ: 240 * 96000 * 4 ~ 92 MB

Ok, these seem more reasonable values. :)
Last edited by No_Use on Tue Aug 14, 2018 4:24 pm, edited 5 times in total.

Post

Your seconds calculation is out by a factor of 10.

Post

Plain silly numbers. 1 BPM: seriously?? Also 8 bytes per sample: why??

Other than that: it's not your ram, but of the user that sets the controls to extremes, and thus may suffer the consequences. Just don't allocate for the worst case scenario in advance.
We are the KVR collective. Resistance is futile. You will be assimilated. Image
My MusicCalc is served over https!!

Post

Plus sample rate generally is set outside of the process loop, so there's no need to allocate for 192 if the project is at 44.1, for example.

However during the process loop it would be a bad idea to keep allocating/deallocating as the user adjusts the delay time parameter. So, I think it's sensible to set an upper delay time, but who would ever need 4 minutes between delay taps?

Post

matt42 wrote:Your seconds calculation is out by a factor of 10.
Thanks, corrected in OP.
BertKoor wrote:1 BPM: seriously??
Well some DAWs support that low BPM, I know at least mine does.*
Surely a good delay plugin should support all possible scenarios, instead of either
- displaying a lame message: sorry not supported or, even worse
- crash because allocation failed

*Well ok, Reaper seems to reject 1 BPM but 2 BPM is possible.

Image
Also 8 bytes per sample: why??
I'm using iPlug and it uses doubles by default, and a double is of size 8 bytes.
Well, I probably still could use floats instead (4 bytes) that would could RAM usage in half but it'd still be quite a lot.
Other than that: it's not your ram, but of the user that sets the controls to extremes, and thus may suffer the consequences. Just don't allocate for the worst case scenario in advance.
Ok, but how you suggest should I deal if the worst case scenario ever happens ?
matt42 wrote:Plus sample rate generally is set outside of the process loop, so there's no need to allocate for 192 if the project is at 44.1, for example.

However during the process loop it would be a bad idea to keep allocating/deallocating as the user adjusts the delay time parameter. So, I think it's sensible to set an upper delay time, but who would ever need 4 minutes between delay taps?
Yes, I see this with some non-BPM synced delays, that max. delay time changes on sample rate change, but as said, it's about a BPM synced delay here. Imo it's not about the usefulness or not about "who would ever need 4 minutes between delay taps?" but the fact that such a scenario is possible in principle and how I should properly deal with it if it occurs.

Post

2400 seconds is 40 minutes.. you may as well save the data to the hard drive and restore it later, rather than keep it all in RAM.

Post

camsr wrote:2400 seconds is 40 minutes.. you may as well save the data to the hard drive and restore it later, rather than keep it all in RAM.
Initial seconds calculation was off by factor ten indeed, sorry.
Corrected already in OP.

Post

Never pre-allocate anything that isn't a fixed buffer.

For example if you're doing Fourier transforms of length = 128, it makes perfect sense to pre-allocate the buffers, compute the tables and so on.

When you're dealing with variable length buffers though: never pre-allocate anything!

You have two options to deal with frequent allocation:
  1. Grow the buffer
  2. Fully dynamic
With a growing buffer you need to handle the buffer using some sort of GC-like (garbage collector) system. For example allow the buffer to grow as needed, but measure the time since it last grew. Every N seconds (240?) allow the buffer to shrink to the average peak size while throwing out exceptional outlier cases. This optimization will allow you to minimize re-allocating the same buffer lengths frequently when the buffer size is changing via modulation where that is a problem.

The fully dynamic solution is often the best: there is rarely any need to allow for that sort of modulation. For example your plug-in might have a "max length" control and all your modulation occurs inside that range. So you only need to allocate the max length once, then modulate knowing the range is fixed. This is a question of how you design the system and which parameters you offer. Rather than a single "delay time" setting you might provide "max delay" from 0 to N and "delay scale" from 0 to 1 for modulation.

While it's entirely possible to do 1 BPM, how often will you actually see it? Remember this means there will be a full minute between two beats. Are we producing ambient tracks 58 hours long? If not this is likely an exceptional outlier that will almost never happen.

Sure you can make it possible to handle the situation gracefully if it does happen. Just don't design it with that as the primary purpose of the system. There is no trade-off here so the best possible system will be a dynamic one. If you need static allocation because say during live performance the latency introduced by reallocating a huge buffer is unacceptable: provide that "max length" parameter that can be set ahead of time. Then you have the best of both worlds.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Thanks aciddose .
I'm having a bit of difficulty imagining how to best implement your "max length" parameter suggestion though.
As said my delay plugin works BPM synced and can switch between 1/16, 1/8, 1/4, 1/2 and 1/1 delays or unsnyced.
In unsynced mode it seems straightforward, but how would the "max length" parameter work in BPM synced mode ?

Post

It's just a limit for the size. So you can call it "min BPM". If you know ahead of time your track never dips below 60 BPM and you need a delay time of at least 10 beats you then need 10 seconds.

So you have:
  • Min BPM = 60
  • Max time = BPM/10
  • Seconds = 60 / (BPM/10) = 10
So you allocate 10 seconds of buffer.

When the BPM goes below that you either clamp it to 10 seconds or divide it by half until it's less than 10 seconds.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

I'd probably just pick a maximum delay, based on some minimum "reasonable" BPM and the maximum time-measure you support, then allocate a buffer for that once sampling rate is known and if the actual calculated delay is longer either cap it to the maximum or just show an error (or both).

If you want to support 32-bit programs, then also keep in mind that while the total heap is capped at 3GB or so, you'll typically start to get allocation failures as soon as you ask for a couple of hundred megabytes in a single block (even if you could allocate the same amount of memory in smaller blocks just fine)... so like if you REALLY want to support very long delays you'll probably need to think about the memory allocation strategy some more than just "how much space do I need." :)

Post Reply

Return to “DSP and Plugin Development”