mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
AudioProcessorGraph: Ensure nodes are prepared with correct precision
Previously, if `AudioProcessorGraph::prepareToPlay` was called twice,
interspersed with calls to `setProcessingPrecision`, the graph would
consider the nodes 'prepared' on the second call, and wouldn't
re-prepare the inner nodes with the new precision setting.
graph.setProcessingPrecision (juce::AudioProcessor::singlePrecision);
graph.prepareToPlay (44100, 512);
graph.setProcessingPrecision (juce::AudioProcessor::doublePrecision);
graph.prepareToPlay (44100, 512); // this wouldn't update the nodes
Now, we always explicitly unprepare all nodes at the beginning of
prepareToPlay, so that they'll always receive the newest settings.
This commit is contained in:
parent
0943291990
commit
b41951bc4b
2 changed files with 48 additions and 4 deletions
|
|
@ -1265,6 +1265,22 @@ void AudioProcessorGraph::prepareToPlay (double sampleRate, int estimatedSamples
|
|||
{
|
||||
const ScopedLock sl (getCallbackLock());
|
||||
setRateAndBufferSizeDetails (sampleRate, estimatedSamplesPerBlock);
|
||||
|
||||
const auto newPrepareSettings = [&]
|
||||
{
|
||||
PrepareSettings settings;
|
||||
settings.precision = getProcessingPrecision();
|
||||
settings.sampleRate = sampleRate;
|
||||
settings.blockSize = estimatedSamplesPerBlock;
|
||||
settings.valid = true;
|
||||
return settings;
|
||||
}();
|
||||
|
||||
if (prepareSettings != newPrepareSettings)
|
||||
{
|
||||
unprepare();
|
||||
prepareSettings = newPrepareSettings;
|
||||
}
|
||||
}
|
||||
|
||||
clearRenderingSequence();
|
||||
|
|
@ -1277,16 +1293,23 @@ bool AudioProcessorGraph::supportsDoublePrecisionProcessing() const
|
|||
return true;
|
||||
}
|
||||
|
||||
void AudioProcessorGraph::unprepare()
|
||||
{
|
||||
prepareSettings.valid = false;
|
||||
|
||||
isPrepared = 0;
|
||||
|
||||
for (auto* n : nodes)
|
||||
n->unprepare();
|
||||
}
|
||||
|
||||
void AudioProcessorGraph::releaseResources()
|
||||
{
|
||||
const ScopedLock sl (getCallbackLock());
|
||||
|
||||
cancelPendingUpdate();
|
||||
|
||||
isPrepared = 0;
|
||||
|
||||
for (auto* n : nodes)
|
||||
n->unprepare();
|
||||
unprepare();
|
||||
|
||||
if (renderSequenceFloat != nullptr)
|
||||
renderSequenceFloat->releaseBuffers();
|
||||
|
|
|
|||
|
|
@ -403,6 +403,24 @@ public:
|
|||
void setStateInformation (const void* data, int sizeInBytes) override;
|
||||
|
||||
private:
|
||||
struct PrepareSettings
|
||||
{
|
||||
ProcessingPrecision precision = ProcessingPrecision::singlePrecision;
|
||||
double sampleRate = 0.0;
|
||||
int blockSize = 0;
|
||||
bool valid = false;
|
||||
|
||||
using Tied = std::tuple<const ProcessingPrecision&,
|
||||
const double&,
|
||||
const int&,
|
||||
const bool&>;
|
||||
|
||||
Tied tie() const noexcept { return std::tie (precision, sampleRate, blockSize, valid); }
|
||||
|
||||
bool operator== (const PrepareSettings& other) const noexcept { return tie() == other.tie(); }
|
||||
bool operator!= (const PrepareSettings& other) const noexcept { return tie() != other.tie(); }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
ReferenceCountedArray<Node> nodes;
|
||||
NodeID lastNodeID = {};
|
||||
|
|
@ -412,11 +430,14 @@ private:
|
|||
std::unique_ptr<RenderSequenceFloat> renderSequenceFloat;
|
||||
std::unique_ptr<RenderSequenceDouble> renderSequenceDouble;
|
||||
|
||||
PrepareSettings prepareSettings;
|
||||
|
||||
friend class AudioGraphIOProcessor;
|
||||
|
||||
std::atomic<bool> isPrepared { false };
|
||||
|
||||
void topologyChanged();
|
||||
void unprepare();
|
||||
void handleAsyncUpdate() override;
|
||||
void clearRenderingSequence();
|
||||
void buildRenderingSequence();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue