DSPark 1.8.0
Header-only C++20 DSP for real-time and offline audio
Loading...
Searching...
No Matches
dspark::SpectrumAnalyzer< T > Class Template Reference

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()).
 

Detailed Description

template<FloatType T>
class dspark::SpectrumAnalyzer< T >

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.

Template Parameters
TSample type (float or double).

Definition at line 100 of file SpectrumAnalyzer.h.

Member Enumeration Documentation

◆ WindowType

template<FloatType T>
enum class dspark::SpectrumAnalyzer::WindowType
strong

Available window types for the FFT analysis.

Enumerator
Hann 

Default. Good general-purpose choice.

Hamming 

Slightly better side lobe rejection.

Blackman 

High dynamic range.

BlackmanHarris 

Highest side lobe rejection.

FlatTop 

Amplitude-accurate measurement.

Rectangular 

No windowing (transient analysis).

Definition at line 104 of file SpectrumAnalyzer.h.

Member Function Documentation

◆ binToFrequency()

template<FloatType T>
T dspark::SpectrumAnalyzer< T >::binToFrequency ( int  bin) const
inlinenoexcept

Centre frequency of the given bin in Hz (0 before the first successful prepare()).

Definition at line 473 of file SpectrumAnalyzer.h.

◆ getFFTSize()

template<FloatType T>
int dspark::SpectrumAnalyzer< T >::getFFTSize ( ) const
inlinenoexcept

FFT size in samples; 0 before the first successful prepare().

Definition at line 469 of file SpectrumAnalyzer.h.

◆ getFloorDb()

template<FloatType T>
T dspark::SpectrumAnalyzer< T >::getFloorDb ( ) const
inlinenoexcept

Returns the readout floor in decibels.

Definition at line 371 of file SpectrumAnalyzer.h.

◆ getMagnitudesDb()

template<FloatType T>
const T * dspark::SpectrumAnalyzer< T >::getMagnitudesDb ( ) const
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).

Returns
Pointer to an array of size getNumBins(); the size is 0 before the first successful prepare() (a throwing first prepare() included) and the pointer may then be null.

Definition at line 424 of file SpectrumAnalyzer.h.

◆ getNumBins()

template<FloatType T>
int dspark::SpectrumAnalyzer< T >::getNumBins ( ) const
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.

◆ getPeakDecay()

template<FloatType T>
T dspark::SpectrumAnalyzer< T >::getPeakDecay ( ) const
inlinenoexcept

Returns the peak-hold decay rate in dB per second.

Definition at line 365 of file SpectrumAnalyzer.h.

◆ getPeakHoldDb()

template<FloatType T>
const T * dspark::SpectrumAnalyzer< T >::getPeakHoldDb ( ) const
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.

Returns
Pointer to an array of size getNumBins(); the size is 0 before the first successful prepare() (a throwing first prepare() included) and the pointer may then be null.

Definition at line 439 of file SpectrumAnalyzer.h.

◆ getSmoothing()

template<FloatType T>
T dspark::SpectrumAnalyzer< T >::getSmoothing ( ) const
inlinenoexcept

Returns the per-frame magnitude smoothing factor.

Definition at line 362 of file SpectrumAnalyzer.h.

◆ getStaleSnapshotCount()

template<FloatType T>
long long dspark::SpectrumAnalyzer< T >::getStaleSnapshotCount ( ) const
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.

◆ getWindowType()

template<FloatType T>
WindowType dspark::SpectrumAnalyzer< T >::getWindowType ( ) const
inlinenoexcept

Returns the window type in use (set at prepare time).

Definition at line 374 of file SpectrumAnalyzer.h.

◆ isNewDataReady()

template<FloatType T>
bool dspark::SpectrumAnalyzer< T >::isNewDataReady ( )
inlinenoexcept

Consumes and returns the new data flag. True if updated since last call.

Definition at line 458 of file SpectrumAnalyzer.h.

◆ isPeakHoldEnabled()

template<FloatType T>
bool dspark::SpectrumAnalyzer< T >::isPeakHoldEnabled ( ) const
inlinenoexcept

Returns true if peak-hold tracking is enabled.

Definition at line 368 of file SpectrumAnalyzer.h.

◆ prepare()

template<FloatType T>
void dspark::SpectrumAnalyzer< T >::prepare ( double  sampleRate,
int  fftSize = 0,
WindowType  windowType = WindowType::Hann 
)
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.)

Parameters
sampleRateSample rate in Hz.
fftSizeFFT 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.
windowTypeWindow function to use (default: Hann).

Definition at line 166 of file SpectrumAnalyzer.h.

◆ pushSamples()

template<FloatType T>
void dspark::SpectrumAnalyzer< T >::pushSamples ( const T *  samples,
int  numSamples 
)
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.

Parameters
samplesPointer to the continuous audio data.
numSamplesNumber of samples to process.

Definition at line 385 of file SpectrumAnalyzer.h.

◆ reset()

template<FloatType T>
void dspark::SpectrumAnalyzer< T >::reset ( )
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.

◆ setFloorDb()

template<FloatType T>
void dspark::SpectrumAnalyzer< T >::setFloorDb ( T  floorDb)
inlinenoexcept

Sets the readout floor in decibels.

Parameters
floorDbValues below this floor are clamped to it (non-finite values are ignored).

Definition at line 355 of file SpectrumAnalyzer.h.

◆ setPeakDecay()

template<FloatType T>
void dspark::SpectrumAnalyzer< T >::setPeakDecay ( T  decayDbPerSecond)
inlinenoexcept

Sets the peak-hold decay rate.

Parameters
decayDbPerSecondDecay in dB per second (floored at 0; non-finite values are ignored).

Definition at line 338 of file SpectrumAnalyzer.h.

◆ setPeakHoldEnabled()

template<FloatType T>
void dspark::SpectrumAnalyzer< T >::setPeakHoldEnabled ( bool  enabled)
inlinenoexcept

Enables or disables peak-hold tracking.

Definition at line 345 of file SpectrumAnalyzer.h.

◆ setSmoothing()

template<FloatType T>
void dspark::SpectrumAnalyzer< T >::setSmoothing ( T  factor)
inlinenoexcept

Sets the per-frame magnitude smoothing factor.

Parameters
factor0 = 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.


The documentation for this class was generated from the following file: