Why is internalRenderBlock fetched and used before allocateRenderResources() is called?

I have a working AUv3 AUAudioUnit app extension but I had to work around a strange issue: I found that the internalRenderBlock value is fetched and invoked before allocateRenderResources() is called. I have not found any documentation stating that this would be the case, and intuitively it does not make any sense. Is there something I am doing in my code that would be causing this to be the case? Should I *force* a call to allocateRenderResources() if it has not been called before internalRenderBlock is fetched? Thanks! Brad
Answered by DTS Engineer in 662088022
I suggest you try logging (or otherwise examining) the AudioUnitRenderActionFlags being passed into the render proc. Some flags look like they might make sense of this behavior.
Accepted Answer
I suggest you try logging (or otherwise examining) the AudioUnitRenderActionFlags being passed into the render proc. Some flags look like they might make sense of this behavior.

I spent some time on this a few years ago, so I can confirm.

In my auv3 tutorial code I added checks to see if the cached blocks that should have been initialized in allocateRenderResources were nil or not. It worked but it has the feeling of fixing an airplane wing with bubble gum.

I have seen Gene's solution from the AU MIDI processor tutorial (thanks, BTW!), which is to duplicate a bit of the code from allocateRenderResourcesAndReturnError() to capture an instance property. Was this your workaround as well? If the render block and its captures are being fetched before what is ostensibly the render initialization for the AU, then should we force call it, or just put any init in internalRenderBlock and ignore allocateRenderResourcesAndReturnError altogether?

I also noticed this happed when running auvaltool. As with all things AU, I find it better to err on the safe side and do (what should be unnecessary) checks in the render block. The flags can be useful but not always.

Also it's certainly a good idea to always assume the host app will do something horrible. IMHO ( and it's only my opinion) This day and age with CPUs being so much faster, it's not so bad to do a few checks at the start of the render block before proceeding with the main DSP ...

Contrary to @Polyphonic's answer, I don't believe this is related to the flags at all. I also wonder if @bradhowes is mistaken that the block is called before allocateRenderResources is called. In my experience, that has not occurred.

However, internalRenderBlock is called every time renderBlock is called, which can be multiple times during an audio graph setup, and will happen before the alloc method. It seems odd, but It Just Is.

Consequently, general advice for everyone is that you should make sure your block doesn't capture any variable values which are not immutable after the audio unit's initialization, otherwise those captured values can be different in different calls to internalRenderBlock and cause subtle bugs. (Been there.) If you look at Apple's example code ("Creating Custom Audio Effects" / AUv3Filter), this is (part of) why all the state that is referred to by internalRenderBlock is stored in a separate struct/C++ class instance; The pointer to that struct/instance never changes, as that pointer is the only thing the block captures. Any time internalRenderBlock is called, therefore, returns the same exact block and captures and has identical behavior.

Here's some logging to show the sequence of events. The image below shows my constructor being called to create my custom AUAudioUnit. After construction, there is a solitary call to internalRenderBlock. The audio unit is part of a graph but the graph has not been started yet.

Here are the log lines after the graph starts and audio is flowing:

There is a second call to internalRenderBlock before my allocateRenderResources method is invoked. When rendering starts, my audio unit's own allocateRenderResources method is invoked, and when I call AUAudioUnit's allocateRenderResources, the internalRenderBlock is called a third time. After that, no more.

Why is internalRenderBlock fetched and used before allocateRenderResources() is called?
 
 
Q