|
DSPark 1.8.0
Header-only C++20 DSP for real-time and offline audio
|
Real-time FFT spectrum analyser with per-bin smoothing and peak hold. More...
#include <SpectrumAnalyzer.h>
Public Types | |
| enum class | WindowType { Hann , Hamming , Blackman , BlackmanHarris , FlatTop , Rectangular } |
| Available window types for the FFT analysis. More... | |
Public Member Functions | |
| void | prepare (double sampleRate, int fftSize=0, WindowType windowType=WindowType::Hann) |
| Prepares the analyser and allocates all necessary buffers. | |
| void | reset () noexcept |
| Resets all internal buffers and state to zero/floor values. | |
| void | setSmoothing (T factor) noexcept |
| Sets the per-frame magnitude smoothing factor. | |
| void | setPeakDecay (T decayDbPerSecond) noexcept |
| Sets the peak-hold decay rate. | |
| void | setPeakHoldEnabled (bool enabled) noexcept |
| Enables or disables peak-hold tracking. | |
| void | setFloorDb (T floorDb) noexcept |
| Sets the readout floor in decibels. | |
| T | getSmoothing () const noexcept |
| Returns the per-frame magnitude smoothing factor. | |
| T | getPeakDecay () const noexcept |
| Returns the peak-hold decay rate in dB per second. | |
| bool | isPeakHoldEnabled () const noexcept |
| Returns true if peak-hold tracking is enabled. | |
| T | getFloorDb () const noexcept |
| Returns the readout floor in decibels. | |
| WindowType | getWindowType () const noexcept |
| Returns the window type in use (set at prepare time). | |
| void | pushSamples (const T *samples, int numSamples) noexcept |
| Pushes audio samples into the analyser's internal ring buffer. | |
| const T * | getMagnitudesDb () const noexcept |
| Returns the current magnitude spectrum in decibels. | |
| const T * | getPeakHoldDb () const noexcept |
| Returns the peak-hold spectrum in decibels. | |
| long long | getStaleSnapshotCount () const noexcept |
| Number of getter calls that had to return the previous snapshot because no attempt copied one frame coherently. | |
| bool | isNewDataReady () noexcept |
| Consumes and returns the new data flag. True if updated since last call. | |
| int | getNumBins () const noexcept |
| Number of spectrum bins (fftSize/2 + 1); 0 before the first successful prepare(). Always matches the allocated storage, also after a throwing prepare(). | |
| int | getFFTSize () const noexcept |
| FFT size in samples; 0 before the first successful prepare(). | |
| T | binToFrequency (int bin) const noexcept |
| Centre frequency of the given bin in Hz (0 before the first successful prepare()). | |
Real-time FFT spectrum analyser with per-bin smoothing and peak hold.
The magnitude smoothing is a per-frame exponential (one analysis frame per hop = fftSize/2 samples), so its settling TIME depends on fftSize and the sample rate: frameRate = 2 * sampleRate / fftSize. The automatic default size holds that frame rate near 47 fps from 44.1 to 192 kHz; a fixed count would let it rise with the rate. The peak-hold decay is specified in dB/second and is rate-invariant either way.
| T | Sample type (float or double). |
Definition at line 100 of file SpectrumAnalyzer.h.
|
strong |
Available window types for the FFT analysis.
Definition at line 104 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Centre frequency of the given bin in Hz (0 before the first successful prepare()).
Definition at line 473 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
FFT size in samples; 0 before the first successful prepare().
Definition at line 469 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Returns the readout floor in decibels.
Definition at line 371 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Returns the current magnitude spectrum in decibels.
Adopts the freshest published frame (if any) and copies it into reader-private snapshot storage. Every bin in the returned array comes from the SAME analysis frame no matter how slow this thread is relative to the writer: the copy is validated against the frame's seqlock and, if it did not complete against one frame, it is discarded and the previous (coherent, one frame older) snapshot is returned with getStaleSnapshotCount() incremented. The returned pointer refers to reader-private storage no other thread can reach; the getter alternates between two such buffers, so the pointer survives the reader's next call to THIS getter and its contents are reused by the call after that (or by the setup-only reset()/prepare()), and it is invalidated only by a successful prepare() (see the Threading frame-coherence and pointer-validity contracts).
Definition at line 424 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Number of spectrum bins (fftSize/2 + 1); 0 before the first successful prepare(). Always matches the allocated storage, also after a throwing prepare().
Definition at line 466 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Returns the peak-hold decay rate in dB per second.
Definition at line 365 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Returns the peak-hold spectrum in decibels.
Same frame-coherence, snapshot and pointer-validity semantics as getMagnitudesDb(), over its own pair of reader-private buffers.
Definition at line 439 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Returns the per-frame magnitude smoothing factor.
Definition at line 362 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Number of getter calls that had to return the previous snapshot because no attempt copied one frame coherently.
Diagnostic for the frame-coherence contract, reader thread only (reset to 0 by a successful prepare(), untouched by reset()). It never counts a torn readout – a torn copy is discarded, never returned; it counts how often the reader lost every retry against the writer and therefore repeated the previous frame. Expected to stay 0 outside pathological reader stalls.
Definition at line 455 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Returns the window type in use (set at prepare time).
Definition at line 374 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Consumes and returns the new data flag. True if updated since last call.
Definition at line 458 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Returns true if peak-hold tracking is enabled.
Definition at line 368 of file SpectrumAnalyzer.h.
|
inline |
Prepares the analyser and allocates all necessary buffers.
Release-safe: a non-finite or non-positive sample rate is ignored (conservative no-op); an explicit fftSize is clamped to [256, 16384] and rounded UP to the next power of two; an out-of-range window enum falls back to Hann. May allocate (setup thread only; while re-preparing, the old and the new storage transiently coexist).
RESOLUTION IS A RATIO, NOT A COUNT. Everything the transform resolves is a function of fs/fftSize: the bin width is fs/fftSize (23.44 Hz at 48 kHz/2048), the Hann main lobe spans 4*fs/fftSize (93.75 Hz there), and the analysis frame rate is 2*fs/fftSize (46.9 fps there). A constant sample count therefore delivers a coarser display as the rate rises: measured on two partials a fifth apart in the mid register (D4 293.66 Hz and A4 440.00 Hz), a fixed 2048-point transform separates them into two peaks at 44.1, 48, 88.2 and 96 kHz but merges them into one at 176.4 and 192 kHz, where the 375 Hz main lobe is wider than the interval. The default is therefore AUTOMATIC and holds the span, hence the resolution, constant; getFFTSize(), getNumBins() and binToFrequency() report what it chose. The per-frame smoothing follows the frame rate the same way: at a fixed 2048 the default 0.8 factor settles (90% of a step) in 255 ms at 44.1 kHz but 59 ms at 192 kHz, while the automatic size holds it at 235-255 ms across the range.
On exceptions-enabled builds: if an allocation throws, the analyser is left unprepared (pushSamples is a no-op until a later prepare() succeeds) and NEVER half-configured: every allocation is built into locals and committed only after all of them succeed, so a throw leaves every reader-visible value exactly as it was on entry. After a throwing FIRST prepare() the analyser is still never-prepared: the size getters report 0 and the spectrum getters return zero readable bins (the returned pointer may be null). After a throwing RE-prepare() the sizes, the storage, the last published frame and any held snapshot pointers are exactly the ones from before the call – only the pushSamples gate is off. getNumBins() therefore always matches the allocated storage, throw or no throw. (With -fno-exceptions an allocation failure terminates instead of throwing, as elsewhere in the framework, so none of the post-throw states above is observable there.)
| sampleRate | Sample rate in Hz. |
| fftSize | FFT size. Values <= 0 (the default) select the AUTOMATIC size: the smallest power of two in [256, 16384] spanning at least 2048/48000 s (~42.7 ms) at sampleRate – 2048 at 44.1/48 kHz, 4096 at 88.2/96 kHz, 8192 at 176.4/192 kHz, 16384 at 384 kHz, 512 at 8 kHz. Above 384 kHz the 16384 ceiling binds and the bins widen again (documented, not fixed). Explicit positive values (power of two, 256 to 16384) are honoured as given. |
| windowType | Window function to use (default: Hann). |
Definition at line 166 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Pushes audio samples into the analyser's internal ring buffer.
Computes the FFT synchronously when the internal hop size (50% overlap) is met. No-op before prepare() or with a null/empty input.
| samples | Pointer to the continuous audio data. |
| numSamples | Number of samples to process. |
Definition at line 385 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Resets all internal buffers and state to zero/floor values.
Setup thread only. Rewrites the hand-off slots AND the reader-private snapshots, so values read through a held getter pointer drop to the floor (see the Threading pointer-validity contract).
Definition at line 295 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Sets the readout floor in decibels.
| floorDb | Values below this floor are clamped to it (non-finite values are ignored). |
Definition at line 355 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Sets the peak-hold decay rate.
| decayDbPerSecond | Decay in dB per second (floored at 0; non-finite values are ignored). |
Definition at line 338 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Enables or disables peak-hold tracking.
Definition at line 345 of file SpectrumAnalyzer.h.
|
inlinenoexcept |
Sets the per-frame magnitude smoothing factor.
| factor | 0 = no smoothing, 0.99 = heaviest. Applied once per analysis frame (hop), so the settling time scales with fftSize / sampleRate. Non-finite values are ignored. |
Definition at line 327 of file SpectrumAnalyzer.h.