AU/Logic: Different latency for offline rendering


#1

We’re observing an issue in a plugin in Logic Pro X where we use different latencies for online (latency = 0) and offline (latency > 0) rendering. As a result, the (offline) rendered audio is out of sync.

Using the latest tip I had a look at what happens during the rendering process and noticed that AudioProcessor::prepareToPlay() where the latency is set (via AudioProcessor::setLatencySamples()) isn’t called. I added calls to AudioProcessor::releaseResources() and JuceAU::prepareToPlay() in the AU wrapper’s SetProperty() handling of [font=Courier]kAudioUnitProperty_OfflineRender[/font]:

case kAudioUnitProperty_OfflineRender:
    if (juceFilter != nullptr)
    {
        juceFilter->setNonRealtime ((*(UInt32*) inData) != 0);

        PluginHostType host;

        if (host.isLogic())  // other hosts seem to work without this
        {
            juceFilter->releaseResources();
            prepareToPlay();
        }
    }

    return noErr;

This way, AudioProcessor::prepareToPlay() is called before the rendering starts but still Logic Pro won’t compensate the latency correctly.
Generally, this should be possible as it seems to work with The Glue (cytomic) when setting online oversampling to 1x and offline oversampling to 2x or higher.

Any idea what can be done to solve this?
If it helps, I can post the example plugin I used which mainly introduces a delay of 1000 samples in offline mode.


#2

Thanks, I'll have a look!


#3

Can you replace your code with the following code and let me know if this works for you:

               case kAudioUnitProperty_OfflineRender:
                    if (juceFilter != nullptr)
                    {
                        const bool nonRealTime = ((*(UInt32*) inData) != 0);

                        if (nonRealTime != juceFilter->isNonRealtime())
                        {
                            const int lastLatency = juceFilter->getLatencySamples();
                            juceFilter->setNonRealtime ((*(UInt32*) inData) != 0);

                            if (prepared) juceFilter->releaseResources();

                            prepareToPlay();
                            prepared = true;

                            if (lastLatency != juceFilter->getLatencySamples())
                                PropertyChanged (kAudioUnitProperty_Latency,       kAudioUnitScope_Global, 0);
                        }
                    }

                    return noErr;

#4

Unfortunately, with the code above the latency still won’t be compensated during offline rendering.

On a completely unrelated matter, how do you get these fancy (black background & syntax highlighting) code sections?


#5

Hmm.. I've done some more debugging today. The way AudioUnit works is that the host needs to call into the audiounit to probe the current latency. It does this once when you add the AudioUnit to the track but never probes the latency again even when bouncing a track. I though the PropertyChanged (kAudioUnitProperty_Latency,       kAudioUnitScope_Global, 0); would nudge Logic to query the latency again but to no avail. Right now, I am out of ideas how to fix this.

 

P.S: Not sure if the highlited code needs special admin permission but I use "code: highlited C++" from the Paragraph drop down menu.