The AudioUnit format is calling updateLatency() before the plugins prepareToPlay() is being called. if a plugin is changing it’s latency following a change of sample rate and block size then calling getLatencySamples() will report an incorrect value that is not in sync with the plugin.
For example I created a plugin using the projucer and then added this to prepareToPlay()…
void LatencyTestPluginAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
DBG ("plugin: setting latency to " << (int) sampleRate);
setLatencySamples ((int) sampleRate);
}
I then created a simple command line host like so…
#include "../JuceLibraryCode/JuceHeader.h"
String getFileForFormat (const String& formatName)
{
if (formatName == "AudioUnit")
return String("/Users/an/Library/Audio/Plug-Ins/Components/LatencyTestPlugin.component");
if (formatName == "VST")
return String("/Users/an/Library/Audio/Plug-Ins/VST/LatencyTestPlugin.vst");
if (formatName == "VST3")
return String("/Users/an/Library/Audio/Plug-Ins/VST3/LatencyTestPlugin.vst3");
return String();
}
class Application : public JUCEApplicationBase
{
public:
const String getApplicationName() override { return ProjectInfo::projectName; }
const String getApplicationVersion() override { return ProjectInfo::versionString; }
bool moreThanOneInstanceAllowed() override { return true; }
void initialise (const String& commandLineParameters) override
{
AudioPluginFormatManager formatManager;
formatManager.addDefaultFormats();
for (int formatIndex = 0; formatIndex < formatManager.getNumFormats(); ++formatIndex)
{
if (AudioPluginFormat* format = formatManager.getFormat (formatIndex))
{
DBG ("Testing " << format->getName());
PluginDescription description;
description.fileOrIdentifier = getFileForFormat (format->getName());
if (ScopedPointer<AudioPluginInstance> plugin = format->createInstanceFromDescription (description, 44100.0, 1024))
{
for (auto sampleRate : { 22050.0, 24000.0, 44100.0, 48000.0, 88200.0, 96000.0 })
{
DBG ("Sample Rate: " << sampleRate);
plugin->prepareToPlay (sampleRate, 1024);
DBG ("Host: reported latency is " << plugin->getLatencySamples());
plugin->releaseResources();
}
}
DBG ("");
}
}
quit();
}
void shutdown() override {}
void anotherInstanceStarted (const String& commandLine) override {}
void systemRequestedQuit() override {}
void suspended() override {}
void resumed() override {}
void unhandledException (const std::exception*, const String& sourceFilename, int lineNumber) override {}
};
START_JUCE_APPLICATION (Application)
…the output of which looks like this…
JUCE v5.2.1
Testing AudioUnit
JUCE v5.2.1
Sample Rate: 22050
void juce::AudioUnitPluginInstance::updateLatency()
plugin: setting latency to 22050
plugin: setting latency to 22050
Host: reported latency is 0
plugin: setting latency to 22050
Sample Rate: 24000
void juce::AudioUnitPluginInstance::updateLatency()
plugin: setting latency to 24000
Host: reported latency is 22050
plugin: setting latency to 24000
Sample Rate: 44100
void juce::AudioUnitPluginInstance::updateLatency()
plugin: setting latency to 44100
Host: reported latency is 24000
plugin: setting latency to 44100
Sample Rate: 48000
void juce::AudioUnitPluginInstance::updateLatency()
plugin: setting latency to 48000
Host: reported latency is 44100
plugin: setting latency to 48000
Sample Rate: 88200
void juce::AudioUnitPluginInstance::updateLatency()
plugin: setting latency to 88200
Host: reported latency is 48000
plugin: setting latency to 88200
Sample Rate: 96000
void juce::AudioUnitPluginInstance::updateLatency()
plugin: setting latency to 96000
Host: reported latency is 88200
plugin: setting latency to 96000
Testing VST
Attempting to load VST: /Users/an/Library/Audio/Plug-Ins/VST/LatencyTestPlugin.vst
JUCE v5.2.1
Creating VST instance: LatencyTestPlugin
Initialising VST: LatencyTestPlugin (1.0.0.0)
Sample Rate: 22050
plugin: setting latency to 22050
Host: reported latency is 22050
Sample Rate: 24000
plugin: setting latency to 24000
Host: reported latency is 24000
Sample Rate: 44100
plugin: setting latency to 44100
Host: reported latency is 44100
Sample Rate: 48000
plugin: setting latency to 48000
Host: reported latency is 48000
Sample Rate: 88200
plugin: setting latency to 88200
Host: reported latency is 88200
Sample Rate: 96000
plugin: setting latency to 96000
Host: reported latency is 96000
Note that the AU plugin is always behind on the changes to the latency but the VST isn’t.
I’ve created a PR that fixes this issue here https://github.com/WeAreROLI/JUCE/pull/363