1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Plug-In wrappers and hosting code now support infinite tail times

This commit is contained in:
hogliux 2018-06-04 15:13:28 +01:00
parent 102203d8a5
commit 9b81643aa9
6 changed files with 68 additions and 13 deletions

View file

@ -4,6 +4,25 @@ JUCE breaking changes
Develop
=======
Change
------
AudioProcessor::getTailLengthSeconds can now return infinity for VST/VST3/AU/AUv3
Possible Issues
---------------
If you are using the result of getTailLengthSeconds to allocate a buffer in your host,
then your host will now likely crash when loading a plug-in with an infinite tail time.
Workaround
----------
Re-write your code to not use the result of getTailLengthSeconds directly to allocate
a buffer.
Rationale
---------
Before this change there was no way for a JUCE plug-in to report an infinite tail time.
Version 5.3.2
=============

View file

@ -317,12 +317,15 @@ public:
if (processor->supportsDoublePrecisionProcessing())
vstEffect.flags |= vstEffectFlagInplaceDoubleAudio;
vstEffect.flags |= vstEffectFlagDataInChunks;
#if JucePlugin_IsSynth
vstEffect.flags |= vstEffectFlagIsSynth;
#else
if (processor->getTailLengthSeconds() == 0.0)
vstEffect.flags |= vstEffectFlagSilenceInProducesSilenceOut;
#endif
vstEffect.flags |= vstEffectFlagDataInChunks;
activePlugins.add (this);
}
@ -588,7 +591,7 @@ public:
if (getHostType().isAbletonLive()
&& hostCallback != nullptr
&& processor->getTailLengthSeconds() == std::numeric_limits<double>::max())
&& processor->getTailLengthSeconds() == std::numeric_limits<double>::infinity())
{
AbletonLiveHostSpecific hostCmd;
@ -2046,7 +2049,18 @@ private:
pointer_sized_int handleGetTailSize (VstOpCodeArguments)
{
if (processor != nullptr)
return (pointer_sized_int) (processor->getTailLengthSeconds() * sampleRate);
{
int32 result;
auto tailSeconds = processor->getTailLengthSeconds();
if (tailSeconds == std::numeric_limits<double>::infinity())
result = std::numeric_limits<int32>::max();
else
result = static_cast<int32> (tailSeconds * sampleRate);
return result; // Vst2 expects an int32 upcasted to a intptr_t here
}
return 0;
}

View file

@ -2033,6 +2033,9 @@ public:
if (tailLengthSeconds <= 0.0 || processSetup.sampleRate <= 0.0)
return Vst::kNoTail;
if (tailLengthSeconds == std::numeric_limits<double>::infinity())
return Vst::kInfiniteTail;
return (Steinberg::uint32) roundToIntAccurate (tailLengthSeconds * processSetup.sampleRate);
}

View file

@ -2296,7 +2296,14 @@ struct VST3PluginInstance : public AudioPluginInstance
auto sampleRate = getSampleRate();
if (sampleRate > 0.0)
{
auto tailSamples = processor->getTailSamples();
if (tailSamples == Vst::kInfiniteTail)
return std::numeric_limits<double>::infinity();
return jlimit (0, 0x7fffffff, (int) processor->getTailSamples()) / sampleRate;
}
}
return 0.0;

View file

@ -83,11 +83,12 @@ typedef pointer_sized_int (VSTINTERFACECALL* VstHostCallback) (VstEffectInterfac
enum VstEffectInterfaceFlags
{
vstEffectFlagHasEditor = 1,
vstEffectFlagInplaceAudio = 16,
vstEffectFlagDataInChunks = 32,
vstEffectFlagIsSynth = 256,
vstEffectFlagInplaceDoubleAudio = 4096
vstEffectFlagHasEditor = 1,
vstEffectFlagInplaceAudio = 16,
vstEffectFlagDataInChunks = 32,
vstEffectFlagIsSynth = 256,
vstEffectFlagSilenceInProducesSilenceOut = 512,
vstEffectFlagInplaceDoubleAudio = 4096
};
//==============================================================================

View file

@ -1283,12 +1283,23 @@ struct VSTPluginInstance : public AudioPluginInstance,
if (vstEffect == nullptr)
return 0.0;
auto sampleRate = getSampleRate();
if (sampleRate <= 0)
if ((vstEffect->flags & vstEffectFlagSilenceInProducesSilenceOut) != 0)
return 0.0;
return dispatch (plugInOpcodeGetTailSize, 0, 0, 0, 0) / sampleRate;
auto tailSize = dispatch (plugInOpcodeGetTailSize, 0, 0, 0, 0);
auto sampleRate = getSampleRate();
// remain backward compatible with old JUCE plug-ins: anything larger
// than INT32_MAX is an invalid tail time but old JUCE 64-bit plug-ins
// would return INT64_MAX for infinite tail time. So treat anything
// equal or greater than INT32_MAX as infinite tail time.
if (tailSize >= std::numeric_limits<int32>::max())
return std::numeric_limits<double>::infinity();
if (tailSize >= 0 && sampleRate > 0)
return static_cast<double> (tailSize) / sampleRate;
return 0.0;
}
bool acceptsMidi() const override { return wantsMidiMessages; }