Bug or malpractice? (Logic)

Warning, the following will destroy your ears, so lower your volume

So I think I might have afound a bug, where Logic has a feedback loop (?) that will make your ears explode, I managed to fix it but I was wondering if this might be my problem?

The issue happens because logic seems to resize the buffer size when a plugin is added in a virtual instrument track (to my understanding, to half the size of the max buffersize).

The issue happens when using filters in a secondary buffer (haven’t tried in the main)…

To reproduce the bug (in pseudo)

declare an extra tmpBuffer 
declare a IIR filter and set it up

prepareToPlay
   tmpBuffer setsize
   prepare filter(spec)
   reset filter

processBlock
   copy buffer to tmpbuffer
   process filter on tmpbuffer
   copy tmpbuffer back to buffer

If you run that in any DAW, everything works fine, and even in Logic as long as it’s an audio track.
If you run that in an Instrument track in logic, you will have a beautiful +300dB clip that will blow your ears :slight_smile:

To prevent this from happening it, I had to run the following hack

processBlock
 if tmpBuffer.getNumSamples() != buffer.getNumSamples()
    tmpbuffer.setSize(yourchannels, buffer.getNumSamples(),false,true,true);

So basically if Logic dares to resize the buffer (happens ONCE when in an instrument track, and only for some reason if you press play while passing sound through the track), I’ll resize ther tmpbuffer to match the size of buffer, making filter work correctly.

So this is kind of a post to help whoever might find the same problem, but at the same time to ask: Why does this happen? Am I doing something wrong?

The buffer size received in prepareToPlay should be seen as a maximum size. The host is allowed to send smaller buffers to processBlock if it needs to. It’s also allowed to send blocks of varying sizes. In the case of Logic, I think that it sometimes shortens blocks to line up MIDI events with block starts.

On each call to processBlock, you should ensure that you only process the exact number of samples that were passed in. So, if prepareToPlay receives a block size of 256, but processBlock receives a buffer containing 100 samples, you should only process 100 samples. You might need to check the following:

  • When you copy buffer to tmpbuffer, only copy the number of samples in buffer.
  • When you process the filter on tmpbuffer, only process that same number of samples. Don’t run the filter over the full tmpbuffer unless you know that the sizes of buffer and tmpbuffer are equal.
  • When you copy tmpbuffer back to buffer, ensure that you only copy the number of samples originally in buffer.