Detecting actual blocksize in a plugin that has no audio in


#1

Question: I am working on a series of plugins that just produce Midi out, based on midi in. Think like an arpeggiator for example (I’m not working on an arpeggiatior BTW, just an example). I get blocksize by looking at prepareToPlay(). Say my audio runs at 48K, I report a latency of 1 msec and I get 480 as samples per block. So far so good.

Now I read (e.g. here https://forum.juce.com/t/blocksize-and-buffersize/23204 that when processBlock() gets called, the (audio)buffer may not always have 480 samples in it, or in other words, the actual blocksize may differ from what the host reported when I called prepareToPlay(). I don’t necessarily care since I am not processing any audio; I’m processing midi.

The question now is, can I rely on the host to call processBlock() every 1 millisecond (in the example above)? And if not, how can I detect what the actual blocksize is for every call of processBlock()? If I had audio in I could take a look at the size of the AudioBuffer - but since I have no audio, AudioBuffer is always empty. So how do I detect the blocksize used for every call to processBlock() in this case?

FWIW I am developing this mainly for use in Cantabile as a host, and so far (the last 3-4 months) Cantabile has consistently called processBlock() every millisecond (given the example of 48k audio and 1 millisec latency). Given the link above I’m getting the feeling I should not rely on this …

Anyone any clue?


#2

When i did a midi plugin like that, it was my understanding that the host would pass a reference to an audio buffer anyway. Even if it doesn’t get used, and even if it is “empty” (ie, all zeroes), it still gets passed on and still has a size.

my process block looked the same as for any other plugin:

void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);

Are you just assuming that your audio buffer is “empty”? Did you check that to make sure?

oh, and btw…1ms of audio @ 48k = 48 samples, not 480


#3

Thx for the tip; getNumSamples() does indeed return the blocksize even is the audiobuffer is empty.

And oops I made a calculation mistake in my example ::shameonme::


#4

Few concerns / questions:

  1. is your plug-in designed to run also without playhead / playback?
    if yes… then blocks are the way to go.
    if no… then use PPQ and BPM reported while in playback. might be more useful if you’re only doing midi. - this approach though, won’t work when playhead is stopped or on apps like MainStage / no-sequence hosts.

  2. hosts are tricky, you can only guess what to expect.
    it might be best to normalize your internal position and report block position so you’ll be agnostic to buffer sizes.

  3. allocate while considering worse-case scenario. (so even if you’re being init with 0 samplerate and 32 buffer size, you’ll be able to adjust without allocations to 96k / 2048samples for example).
    (still be able to allocate for even more bizzar buffers but at least avoid allocating for extreme common sizes).


#5

Thx for the feedback!

Re 1. It’s designed to run in 3 use cases: host without playhead; hosts with playhead but ignoring BPM and the playhead commands; and fully according to playhead. All 3 work fine since yesterday.

Re 2. and 3. : it is now completely agnostic to blocksize: it just generates what is needed based on the number of samples as reported by getNumSamples() on the audiobuffer.

What had happened was the following: so far for the last 2-3 months I had only been testing in my main target host ( Cantabile ) which reports a blocksize in prepareToPlay() and just (seems to) stick to that. As soon as I tried it in e.g. Cubase the plugin died - Cubase reported a blocksize much larger than what is actually seems to use (which the plugin ignored - and then crashed because it fed way too much samples in the midibuffer). Anyway, fixed now.


#6

AFAIK, this would have been caught by pluginval: Anouncing "pluginval" an open-source cross-platform plugin validation tool


#7

Actually it didn’t - the plugin passed pluginval without issues. The reason for that is that by default this plugin doesn’t “run” anything - it really needs a preset loaded in it before it tries to output midi. I would actually be very interested in a version of pluginval that lets me load a preset first, and only then run the tests!