in pedalboard/ExternalPlugin.h [906:1004]
bool attemptToWarmUp() {
if (!pluginInstance || initializationTimeout <= 0)
return false;
auto endTime = juce::Time::currentTimeMillis() +
(long)(initializationTimeout * 1000.0);
const int numInputChannels = pluginInstance->getMainBusNumInputChannels();
const float sampleRate = 44100.0f;
const int bufferSize = 2048;
if (numInputChannels != 0) {
// TODO: For effect plugins, do this check as well!
return false;
}
// Set input and output busses/channels appropriately:
int numOutputChannels =
std::max(pluginInstance->getMainBusNumInputChannels(),
pluginInstance->getMainBusNumOutputChannels());
setNumChannels(numOutputChannels);
pluginInstance->setNonRealtime(true);
pluginInstance->prepareToPlay(sampleRate, bufferSize);
// Prepare an empty MIDI buffer to measure the background noise of the
// plugin:
juce::MidiBuffer emptyNoteBuffer;
// Send in a MIDI buffer containing a single middle C at full velocity:
auto noteOn = juce::MidiMessage::noteOn(
/* channel */ 1, /* note number */ 60, /* velocity */ (juce::uint8)127);
// And prepare an all-notes-off buffer:
auto allNotesOff = juce::MidiMessage::allNotesOff(/* channel */ 1);
if (juce::MessageManager::getInstance()->isThisTheMessageThread()) {
for (int i = 0; i < 10; i++) {
if (juce::Time::currentTimeMillis() >= endTime)
return false;
juce::MessageManager::getInstance()->runDispatchLoopUntil(1);
}
}
juce::AudioBuffer<float> audioBuffer(numOutputChannels, bufferSize);
audioBuffer.clear();
pluginInstance->processBlock(audioBuffer, emptyNoteBuffer);
auto noiseFloor = audioBuffer.getMagnitude(0, bufferSize);
audioBuffer.clear();
// Now pass in a middle C:
// Note: we create a new MidiBuffer every time here, as unlike AudioBuffer,
// the messages in a MidiBuffer get erased every time we call processBlock!
{
juce::MidiBuffer noteOnBuffer(noteOn);
pluginInstance->processBlock(audioBuffer, noteOnBuffer);
}
// Then keep pumping the message thread until we get some louder output:
bool magnitudeIncreased = false;
while (true) {
auto magnitudeWithNoteHeld = audioBuffer.getMagnitude(0, bufferSize);
if (magnitudeWithNoteHeld > noiseFloor * 5) {
magnitudeIncreased = true;
break;
}
if (juce::MessageManager::getInstance()->isThisTheMessageThread()) {
for (int i = 0; i < 10; i++) {
juce::MessageManager::getInstance()->runDispatchLoopUntil(1);
}
}
if (juce::Time::currentTimeMillis() >= endTime)
break;
audioBuffer.clear();
{
juce::MidiBuffer noteOnBuffer(noteOn);
pluginInstance->processBlock(audioBuffer, noteOnBuffer);
}
if (juce::Time::currentTimeMillis() >= endTime)
break;
}
// Send in an All Notes Off and then reset, just to make sure we clear any
// note trails:
audioBuffer.clear();
{
juce::MidiBuffer allNotesOffBuffer(allNotesOff);
pluginInstance->processBlock(audioBuffer, allNotesOffBuffer);
}
pluginInstance->reset();
pluginInstance->releaseResources();
return magnitudeIncreased;
}