CPU Load Meter Module
This module provides real-time CPU load measurement for audio processing. Measures the percentage of available time consumed by the audio callback, helping identify performance bottlenecks and optimize DSP algorithms.
Key Features:
- Real-time CPU load monitoring (0-100%)
- Tracks minimum, maximum, and smoothed average load
- Configurable smoothing filter for average calculation
- Integration with audio callback timing
- Zero overhead when not actively reading values
Usage Example:
import nimphea_cpuload import nimphea_seed var seed: Seed cpuMeter: CpuLoadMeter proc audioCallback(input: ptr float32, output: ptr float32, size: csize_t) {.cdecl.} = cpuMeter.onBlockStart() # Your DSP processing here for i in 0 ..< size: output[i] = input[i] # Simple passthrough cpuMeter.onBlockEnd() seed.init() seed.setAudioBlockSize(48) cpuMeter.init(seed.audioSampleRate(), 48, smoothingCutoff = 1.0) seed.startAudio(audioCallback) # Monitor in main loop while true: let avgLoad = cpuMeter.getAvgCpuLoad() let maxLoad = cpuMeter.getMaxCpuLoad() echo "CPU: ", int(avgLoad * 100), "% (max ", int(maxLoad * 100), "%)" seed.delayMs(1000)
Performance Notes:
- OnBlockStart/End calls are lightweight (just timestamp reads)
- Load values range from 0.0 (idle) to 1.0 (100% utilized)
- Values > 1.0 indicate audio dropouts/overruns
- Smoothing filter reduces jitter in average reading
- Reset() clears min/max/avg for new measurement period
Types
CpuLoadMeter {.importcpp: "daisy::CpuLoadMeter", header: "util/CpuLoadMeter.h".} = object
-
Real-time CPU load measurement for audio processing.
Tracks the fraction of available time consumed by audio callbacks. Initialize with sample rate and block size, then call OnBlockStart/OnBlockEnd at the beginning and end of each audio callback.
Source Edit
Procs
proc getAvgCpuLoad(this: CpuLoadMeter): float32 {. importcpp: "#.GetAvgCpuLoad()", header: "util/CpuLoadMeter.h", ...raises: [], tags: [], forbids: [].}
-
Get the smoothed average CPU load.
Parameters:
- this: The CpuLoadMeter instance
Returns: Average CPU load in range 0.0 to 1.0 (multiply by 100 for percentage) Values > 1.0 indicate audio buffer underruns
Note: This value is smoothed by a lowpass filter configured in Init().
Example:
let load = cpuMeter.getAvgCpuLoad() echo "CPU Load: ", int(load * 100), "%"
Source Edit proc getMaxCpuLoad(this: CpuLoadMeter): float32 {. importcpp: "#.GetMaxCpuLoad()", header: "util/CpuLoadMeter.h", ...raises: [], tags: [], forbids: [].}
-
Get the maximum CPU load observed since initialization or last Reset().
Parameters:
- this: The CpuLoadMeter instance
Returns: Maximum CPU load in range 0.0 to 1.0 (values > 1.0 indicate dropouts)
Note: Useful for identifying worst-case performance spikes.
Example:
let maxLoad = cpuMeter.getMaxCpuLoad() if maxLoad > 0.95: echo "Warning: CPU usage spike at ", int(maxLoad * 100), "%"
Source Edit proc getMinCpuLoad(this: CpuLoadMeter): float32 {. importcpp: "#.GetMinCpuLoad()", header: "util/CpuLoadMeter.h", ...raises: [], tags: [], forbids: [].}
-
Get the minimum CPU load observed since initialization or last Reset().
Parameters:
- this: The CpuLoadMeter instance
Returns: Minimum CPU load in range 0.0 to 1.0
Note: Useful for understanding best-case performance.
Example:
let minLoad = cpuMeter.getMinCpuLoad() echo "Best case: ", int(minLoad * 100), "%"
Source Edit proc init(this: var CpuLoadMeter; sampleRateInHz: float32; blockSizeInSamples: int; smoothingFilterCutoffHz: float32 = 1.0) {. importcpp: "#.Init(@)", header: "util/CpuLoadMeter.h", ...raises: [], tags: [], forbids: [].}
-
Initialize the CPU load meter.
Parameters:
- this: The CpuLoadMeter instance
- sampleRateInHz: Audio sample rate in Hz (e.g., 48000.0)
- blockSizeInSamples: Audio buffer size in samples (e.g., 48)
- smoothingFilterCutoffHz: Cutoff frequency for average smoothing (default: 1.0 Hz)
Note: The smoothing filter is a 1-pole lowpass that reduces jitter in the average CPU load reading. Lower cutoff = more smoothing but slower response.
Example:
var meter: CpuLoadMeter meter.init(48000.0, 48) # 48kHz, 48 samples per block
Source Edit proc onBlockEnd(this: var CpuLoadMeter) {.importcpp: "#.OnBlockEnd()", header: "util/CpuLoadMeter.h", ...raises: [], tags: [], forbids: [].}
-
Call this at the very end of the audio callback.
Parameters:
- this: The CpuLoadMeter instance
Note: Calculates elapsed time since OnBlockStart() and updates load statistics.
Example:
proc audioCallback(input: ptr float32, output: ptr float32, size: csize_t) {.cdecl.} = cpuMeter.onBlockStart() # ... DSP processing ... cpuMeter.onBlockEnd()
Source Edit proc onBlockStart(this: var CpuLoadMeter) {.importcpp: "#.OnBlockStart()", header: "util/CpuLoadMeter.h", ...raises: [], tags: [], forbids: [].}
-
Call this at the very beginning of the audio callback.
Parameters:
- this: The CpuLoadMeter instance
Note: Records the current timestamp. Must be paired with OnBlockEnd().
Example:
proc audioCallback(input: ptr float32, output: ptr float32, size: csize_t) {.cdecl.} = cpuMeter.onBlockStart() # ... DSP processing ... cpuMeter.onBlockEnd()
Source Edit proc reset(this: var CpuLoadMeter) {.importcpp: "#.Reset()", header: "util/CpuLoadMeter.h", ...raises: [], tags: [], forbids: [].}
-
Reset the min, max, and average load readings.
Parameters:
- this: The CpuLoadMeter instance
Note: Use this to start a new measurement period. All values will be recalculated from scratch after the next OnBlockEnd() call.
Example:
# Measure load for a specific operation cpuMeter.reset() # ... perform operation ... seed.delayMs(5000) # Measure for 5 seconds echo "Operation CPU usage: ", int(cpuMeter.getMaxCpuLoad() * 100), "%"
Source Edit