diff --git a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp index 0a617d7d16..ee778098db 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp @@ -23,8 +23,8 @@ namespace juce { -AudioProcessLoadMeasurer::AudioProcessLoadMeasurer() {} -AudioProcessLoadMeasurer::~AudioProcessLoadMeasurer() {} +AudioProcessLoadMeasurer::AudioProcessLoadMeasurer() = default; +AudioProcessLoadMeasurer::~AudioProcessLoadMeasurer() = default; void AudioProcessLoadMeasurer::reset() { @@ -33,43 +33,55 @@ void AudioProcessLoadMeasurer::reset() void AudioProcessLoadMeasurer::reset (double sampleRate, int blockSize) { - cpuUsageMs = 0; + cpuUsageProportion = 0; xruns = 0; if (sampleRate > 0.0 && blockSize > 0) { - msPerBlock = 1000.0 * blockSize / sampleRate; - timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0; + msPerSample = 1000.0 / sampleRate; + timeToCpuScale = (msPerSample > 0.0) ? (1.0 / msPerSample) : 0.0; } else { - msPerBlock = 0; + msPerSample = 0; timeToCpuScale = 0; } } void AudioProcessLoadMeasurer::registerBlockRenderTime (double milliseconds) { - const double filterAmount = 0.2; - cpuUsageMs += filterAmount * (milliseconds - cpuUsageMs); + registerRenderTime (milliseconds, samplesPerBlock); +} - if (milliseconds > msPerBlock) +void AudioProcessLoadMeasurer::registerRenderTime (double milliseconds, int numSamples) +{ + const auto maxMilliseconds = numSamples * msPerSample; + const auto usedProportion = milliseconds / maxMilliseconds; + const auto filterAmount = 0.2; + cpuUsageProportion += filterAmount * (usedProportion - cpuUsageProportion); + + if (milliseconds > maxMilliseconds) ++xruns; } -double AudioProcessLoadMeasurer::getLoadAsProportion() const { return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs); } +double AudioProcessLoadMeasurer::getLoadAsProportion() const { return jlimit (0.0, 1.0, cpuUsageProportion); } double AudioProcessLoadMeasurer::getLoadAsPercentage() const { return 100.0 * getLoadAsProportion(); } int AudioProcessLoadMeasurer::getXRunCount() const { return xruns; } AudioProcessLoadMeasurer::ScopedTimer::ScopedTimer (AudioProcessLoadMeasurer& p) - : owner (p), startTime (Time::getMillisecondCounterHiRes()) + : ScopedTimer (p, p.samplesPerBlock) +{ +} + +AudioProcessLoadMeasurer::ScopedTimer::ScopedTimer (AudioProcessLoadMeasurer& p, int numSamplesInBlock) + : owner (p), startTime (Time::getMillisecondCounterHiRes()), samplesInBlock (numSamplesInBlock) { } AudioProcessLoadMeasurer::ScopedTimer::~ScopedTimer() { - owner.registerBlockRenderTime (Time::getMillisecondCounterHiRes() - startTime); + owner.registerRenderTime (Time::getMillisecondCounterHiRes() - startTime, samplesInBlock); } } // namespace juce diff --git a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h index ffd113d6d7..ea0c1f76e7 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h +++ b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h @@ -72,11 +72,13 @@ public: struct JUCE_API ScopedTimer { ScopedTimer (AudioProcessLoadMeasurer&); + ScopedTimer (AudioProcessLoadMeasurer&, int numSamplesInBlock); ~ScopedTimer(); private: AudioProcessLoadMeasurer& owner; double startTime; + int samplesInBlock; JUCE_DECLARE_NON_COPYABLE (ScopedTimer) }; @@ -87,9 +89,15 @@ public: */ void registerBlockRenderTime (double millisecondsTaken); + /** Can be called manually to add the time of a callback to the stats. + Normally you probably would never call this - it's simpler and more robust to + use a ScopedTimer to measure the time using an RAII pattern. + */ + void registerRenderTime (double millisecondsTaken, int numSamples); + private: - double cpuUsageMs = 0, timeToCpuScale = 0, msPerBlock = 0; - int xruns = 0; + double cpuUsageProportion = 0, timeToCpuScale = 0, msPerSample = 0; + int xruns = 0, samplesPerBlock = 0; }; diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp index 198885a86e..1c6633adaf 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp @@ -909,7 +909,7 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat if (callbacks.size() > 0) { - AudioProcessLoadMeasurer::ScopedTimer timer (loadMeasurer); + AudioProcessLoadMeasurer::ScopedTimer timer (loadMeasurer, numSamples); tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true);