VST3: assuming constant buffer size or not?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS
rbuse
KVRer
10 posts since 9 Dec, 2014

Post Wed May 03, 2023 4:07 am

Has anyone encountered a host that splits blocks into sizes not divisible by 16 or 8 ?

User avatar
mystran
KVRAF
7664 posts since 12 Feb, 2006 from Helsinki, Finland

Post Wed May 03, 2023 4:11 am

rbuse wrote: Wed May 03, 2023 4:07 am Has anyone encountered a host that splits blocks into sizes not divisible by 16 or 8 ?
Do not assume anything about divisibility of buffers. As far as you care, the driver buffer size could be a prime number. Powers of two are common, but not universal. Hosts that split buffers do so in a way that is essentially random. You can be asked to process buffers of 1 sample.
I'm a useless animal with no marketable skills, besides writing code and thinking DSP. Hire me as a mascot or a pet?

rbuse
KVRer
10 posts since 9 Dec, 2014

Post Wed May 03, 2023 4:35 am

mystran wrote: Wed May 03, 2023 4:11 am Do not assume anything about divisibility of buffers. As far as you care, the driver buffer size could be a prime number. Powers of two are common, but not universal. Hosts that split buffers do so in a way that is essentially random. You can be asked to process buffers of 1 sample.
Perhaps an acceptable strategy would be to detect those odd block sizes, and if they are not compatible with a fixed blocksize then dynamically engage a latency/PDC frontend feeding the fixed blocksize portion of the code.

User avatar
mystran
KVRAF
7664 posts since 12 Feb, 2006 from Helsinki, Finland

Post Wed May 03, 2023 5:12 am

rbuse wrote: Wed May 03, 2023 4:35 am
mystran wrote: Wed May 03, 2023 4:11 am Do not assume anything about divisibility of buffers. As far as you care, the driver buffer size could be a prime number. Powers of two are common, but not universal. Hosts that split buffers do so in a way that is essentially random. You can be asked to process buffers of 1 sample.
Perhaps an acceptable strategy would be to detect those odd block sizes, and if they are not compatible with a fixed blocksize then dynamically engage a latency/PDC frontend feeding the fixed blocksize portion of the code.
Changing reported latency on the fly generally doesn't work well though; you'll need at least a plugin reset (and likely the host needs to recalculate latencies across it's DSP graph, potentially reallocating buffers for compensation).

I would really recommend just writing your code in such a way that it doesn't really make any assumptions about blocksize whatsoever (except possibly the maximum for allocation purposes). It's not really that difficult and the performance impact of potentially having to keep track of a few extra counters is mostly negligible.

Forcing fixed buffers internally mostly makes sense if you're using something like FFT where you really can't easily avoid fixed framerate and in this case you should buffer yourself and report the latency.. but for pretty much everything else I'd just try to find a way to do it without relying on specific blocksizes.

Note that while very short blocks (eg. 1 sample) do have at times, those are typically not the norm, so performance-wise you don't really need to be prepared to process everything 1 sample at a time as long as you can handle the occasional short block here and there without too much of a CPU spike.
I'm a useless animal with no marketable skills, besides writing code and thinking DSP. Hire me as a mascot or a pet?

User avatar
Markus Krause
KVRAF
1743 posts since 2 Jul, 2018

Post Thu May 04, 2023 12:52 am

Short answer: you can't assume a constant buffer size because of the default settings of FL Studio.

One might argue that the VST specification allows a variable buffer size, but this DAW pushes things to the extreme which can result in audible crackles and angry customers.
All Daws except FL Studio seem to request a constant buffer size. FL Studio seems to be the only DAW that does things here differently and in a very bad way. They request completely random sizes with extreme jitter. The buffer size can even go down to 1 (!) single sample. This is really bad software design as it:
- completely messes up the CPU cache
- causes unnecessary and extreme overhead in the context switch
- can cause extreme CPU spikes if the plugin needs to process stuff in blocks
- causes heavy jitter in the CPU load
- causes crackles

What really upset me was this:
In a recent version some years ago Imageline even blamed the plugin developers for their own badly done software-design. In the plugin settings there was an option called "enable fixed buffers for buggy plugins". We lost customers because people falsely assumed that our plugins would not work properly.
In the current version they removed the term 'buggy plugins' from their settings page.

Workaround:
Our plugins are able to detect FL Studio. If FL Studio is detected an additional circular buffer of 32 samples delay is used which smooths the CPU spikes and fixes their mess.
If there is interest I can post the code here which fixes FL Studio.
Tone2 Audiosoftware https://www.tone2.com

rbuse
KVRer
10 posts since 9 Dec, 2014

Post Thu May 04, 2023 7:02 am

Thanks for that write-up. I would be very interested in seeing your FL Studio detection /workaround.
Markus Krause wrote: Thu May 04, 2023 12:52 am
Workaround:
Our plugins are able to detect FL Studio. If FL Studio is detected an additional circular buffer of 32 samples delay is used which smooths the CPU spikes and fixes their mess.
If there is interest I can post the code here which fixes FL Studio.

User avatar
hugoderwolf
KVRist
284 posts since 1 Apr, 2009 from Hannover, Germany

Post Thu May 04, 2023 7:10 am

If you're on JUCE you can use the PluginHostType class to detect specific hosts:
https://docs.juce.com/master/classPluginHostType.html

2DaT
KVRian
613 posts since 21 Jun, 2013

Post Thu May 04, 2023 8:57 am

mystran wrote: Wed May 03, 2023 4:11 am
rbuse wrote: Wed May 03, 2023 4:07 am Has anyone encountered a host that splits blocks into sizes not divisible by 16 or 8 ?
Do not assume anything about divisibility of buffers. As far as you care, the driver buffer size could be a prime number. Powers of two are common, but not universal. Hosts that split buffers do so in a way that is essentially random. You can be asked to process buffers of 1 sample.
If for example one uses a vectorization and processes things in multiples of 8s, it is probably somewhat safe to process a full vector and discard the samples you don't need and just eat the overhead.

Realistically, the users won't be using less than 32 samples real buffer, which will amount to 25% extra work for an unlucky single split. The benefit of a vectorization should outweight the extra penalty is almost all cases.

User avatar
Markus Krause
KVRAF
1743 posts since 2 Jul, 2018

Post Thu May 04, 2023 10:51 pm

hugoderwolf wrote: Thu May 04, 2023 7:10 am If you're on JUCE you can use the PluginHostType class to detect specific hosts:
https://docs.juce.com/master/classPluginHostType.html
For the ones that are not seniors and use JUCE: Fruityloops = FL Studio. They had to change the name because of tradamark issues (with Kellogs?).
Tone2 Audiosoftware https://www.tone2.com

User avatar
quikquak
KVRian
865 posts since 6 Aug, 2005 from England

Post Sat May 20, 2023 7:24 am

I find it best to treat the input as single sample streams, and never do anything special on each block process - do everything on a sample base count.
That way I can never be surprised about block sizes, and gather in as much as I need internally before processing it.

FL studio is my go to development host. Not only does it boot up quickly, it also has the shortcut 'alt-1' which loads the last project. Which I find is a very fluid way of working.
*edit*
As mentioned, Juce calls your override function prepareToPlay(int samplesPerBlockExpected, double sampleRate). https://docs.juce.com/develop/classAudi ... e5933a063d
So processing will NEVER go above that first parameter, samplesPerBlockExpected

umd
KVRian
1120 posts since 26 Feb, 2006 from Fartland

Post Mon May 29, 2023 6:58 am

old problems again?
Free MIDI plugins and other stuff:
https://jstuff.wordpress.com
"MIDI 2.0 is an extension of MIDI 1.0. It does not replace MIDI 1.0(...)"

Return to “DSP and Plugin Development”