arduino-audio-tools
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
QualityAnalysisStream Class Reference

Analyzes audio stream quality by detecting clicks/pops, gaps/dropouts, clipping/corruption, and whether the signal is genuine audio or just noise. More...

#include <QualityAnalysisStream.h>

Inheritance diagram for QualityAnalysisStream:
ModifyingStream AudioStream BaseStream AudioInfoSupport AudioInfoSource Stream Print

Public Member Functions

 QualityAnalysisStream ()=default
 
 QualityAnalysisStream (Print &print)
 
 QualityAnalysisStream (Stream &stream)
 
virtual void addNotifyAudioChange (AudioInfoSupport &bi)
 Adds target to be notified about audio changes.
 
virtual AudioInfo audioInfo () override
 provides the actual input AudioInfo
 
virtual AudioInfo audioInfoOut ()
 
int available () override
 
int availableForWrite () override
 
bool begin () override
 
bool begin (AudioInfo info)
 
virtual void clearNotifyAudioChange ()
 Deletes all change notify subscriptions.
 
void clearStats ()
 Reset all statistics and detection state.
 
void clearTonalitySource ()
 
virtual void end ()
 
void flush () override
 
bool isNotifyActive ()
 Checks if the automatic AudioInfo update is active.
 
bool isSignalPresent () const
 
virtual operator bool ()
 
size_t readBytes (uint8_t *data, size_t len) override
 
virtual size_t readSilence (uint8_t *buffer, size_t length)
 Source to generate silence: just sets the buffer to 0.
 
virtual bool removeNotifyAudioChange (AudioInfoSupport &bi)
 Removes a target in order not to be notified about audio changes.
 
void setAudioInfo (AudioInfo info) override
 Defines the input AudioInfo.
 
void setCallback (QualityCallback cb)
 Register a callback for quality issue notifications.
 
void setClickThreshold (float ratio)
 Sample-to-sample jump threshold as ratio of max value (0.0 to 1.0)
 
void setClippingMargin (float ratio)
 Clipping is detected when sample >= max_value * (1 - margin)
 
void setClippingMinSamples (int samples)
 Minimum consecutive samples at max to count as clipping.
 
void setDropoutMinSamples (int samples)
 Minimum consecutive near-silent samples to count as a dropout.
 
void setNoiseFloorBlockSize (int samples)
 Number of samples per RMS/noise-floor block (default 256)
 
void setNoiseFloorTracking (float attack, float release)
 
void setNotifyActive (bool flag)
 Deactivate/Reactivate automatic AudioInfo updates: (default is active)
 
virtual void setOutput (AudioOutput &out)
 Defines/Changes the output target and registers for audio change notifications.
 
void setOutput (Print &out) override
 Defines/Changes the output target.
 
void setReporting (int period_ms, Print &output)
 
void setSignalMargin (float db)
 
void setSignalPresenceMinBlocks (int blocks)
 
void setSilenceThreshold (float ratio)
 Samples below this ratio of max value are considered silent.
 
virtual void setStream (AudioStream &io)
 Defines/Changes the input & output and registers for audio change notifications.
 
void setStream (Stream &io) override
 Defines/Changes the input & output.
 
void setTonalityBufferSize (int samples)
 
void setTonalityEnabled (bool enabled)
 
void setTonalityMinConfidence (float min_confidence)
 
void setTonalitySource (FrequencyDetectorAutoCorrelation &detector, float min_confidence=0.3f, int channel=0)
 
void setWriteBufferSize (int size)
 
const QualityStatsstats () const
 Access the accumulated quality statistics.
 
float tonalityConfidence () const
 
size_t write (const uint8_t *data, size_t len) override
 
virtual size_t write (uint8_t ch) override
 
virtual void writeSilence (size_t len)
 Writes len bytes of silence (=0).
 

Protected Member Functions

void analyze (const uint8_t *data, size_t len)
 
template<typename T >
void analyzeT (const uint8_t *buffer, size_t size)
 
void initTonality ()
 
virtual int not_supported (int out, const char *msg="")
 
void notifyAudioChange (AudioInfo info)
 
void printReport ()
 
void processRmsBlock ()
 
void refillReadBuffer ()
 Refill small read buffer (e.g. 8 bytes) to avoid single byte reads when calling read()
 
void reportIfDue ()
 
void resetState ()
 

Protected Attributes

int _timeout = 10
 
FrequencyDetectorAutoCorrelation auto_tonality
 
QualityCallback callback = nullptr
 
float click_threshold = 0.5f
 
float clipping_margin = 0.01f
 
int clipping_min_samples = 3
 
int consecutive_clipped = 0
 
int consecutive_noise_blocks = 0
 
int consecutive_signal_blocks = 0
 
int consecutive_silent = 0
 
int dropout_min_samples = 10
 
bool has_prev_sample = false
 
bool in_clipping = false
 
bool in_dropout = false
 
AudioInfo info
 
bool is_notify_active = true
 
uint32_t last_report_time = 0
 
float max_value = 32767.0f
 
float noise_floor_attack = 0.3f
 
bool noise_floor_initialized = false
 
float noise_floor_release = 0.01f
 
Vector< AudioInfoSupport * > notify_vector
 
bool owns_tonality = true
 
Streamp_io = nullptr
 
Printp_out = nullptr
 
Printp_report = nullptr
 
FrequencyDetectorAutoCorrelationp_tonality = nullptr
 
Vector< float > prev_sample
 
int report_period_ms = 0
 
int rms_block_count = 0
 
int rms_block_size = 256
 
double rms_sum_sq = 0
 
float signal_margin_db = 6.0f
 
int signal_present_min_blocks = 3
 
float silence_threshold = 0.01f
 
QualityStats stats_data
 
RingBuffer< uint8_t > tmp_in {0}
 
RingBuffer< uint8_t > tmp_out {0}
 
int tonality_channel = 0
 
bool tonality_enabled = true
 
float tonality_min_confidence = 0.3f
 
int write_buffer_size = MAX_SINGLE_CHARS
 

Detailed Description

Analyzes audio stream quality by detecting clicks/pops, gaps/dropouts, clipping/corruption, and whether the signal is genuine audio or just noise.

Insert this stream into an audio pipeline to monitor signal quality in real time. Data passes through unmodified.

Results are available via stats() or through a callback.

Author
Phil Schatzmann

Constructor & Destructor Documentation

◆ QualityAnalysisStream() [1/3]

QualityAnalysisStream ( )
default

◆ QualityAnalysisStream() [2/3]

QualityAnalysisStream ( Print print)
inline

◆ QualityAnalysisStream() [3/3]

QualityAnalysisStream ( Stream stream)
inline

Member Function Documentation

◆ addNotifyAudioChange()

virtual void addNotifyAudioChange ( AudioInfoSupport bi)
inlinevirtualinherited

◆ analyze()

void analyze ( const uint8_t *  data,
size_t  len 
)
inlineprotected

◆ analyzeT()

template<typename T >
void analyzeT ( const uint8_t *  buffer,
size_t  size 
)
inlineprotected

◆ audioInfo()

virtual AudioInfo audioInfo ( )
inlineoverridevirtualinherited

◆ audioInfoOut()

virtual AudioInfo audioInfoOut ( )
inlinevirtualinherited

◆ available()

int available ( )
inlineoverridevirtual

Reimplemented from BaseStream.

◆ availableForWrite()

int availableForWrite ( )
inlineoverridevirtual

Reimplemented from BaseStream.

◆ begin() [1/2]

bool begin ( )
inlineoverridevirtual

Reimplemented from BaseStream.

◆ begin() [2/2]

bool begin ( AudioInfo  info)
inline

◆ clearNotifyAudioChange()

virtual void clearNotifyAudioChange ( )
inlinevirtualinherited

Deletes all change notify subscriptions.

Reimplemented in RTSPClient< TcpClient, UdpSocket >.

◆ clearStats()

void clearStats ( )
inline

Reset all statistics and detection state.

◆ clearTonalitySource()

void clearTonalitySource ( )
inline

Reverts to the built-in tonality detector (the default), undoing a prior setTonalitySource().

◆ end()

virtual void end ( )
inlinevirtualinherited

◆ flush()

void flush ( )
inlineoverridevirtual

Reimplemented from BaseStream.

◆ initTonality()

void initTonality ( )
inlineprotected

(Re-)initializes the built-in tonality detector to match the current AudioInfo, unless an external one was set via setTonalitySource() or the tonality gate was disabled via setTonalityEnabled(false).

◆ isNotifyActive()

bool isNotifyActive ( )
inlineinherited

Checks if the automatic AudioInfo update is active.

◆ isSignalPresent()

bool isSignalPresent ( ) const
inline

True while the signal is currently considered present (see setSignalMargin())

◆ not_supported()

virtual int not_supported ( int  out,
const char *  msg = "" 
)
inlineprotectedvirtualinherited

◆ notifyAudioChange()

void notifyAudioChange ( AudioInfo  info)
inlineprotectedinherited

◆ operator bool()

virtual operator bool ( )
inlinevirtualinherited

◆ printReport()

void printReport ( )
inlineprotected

◆ processRmsBlock()

void processRmsBlock ( )
inlineprotected

Called once per rms_block_size samples: updates rms_level, noise_floor, snr_db and the signal_present flag/callbacks.

◆ readBytes()

size_t readBytes ( uint8_t *  data,
size_t  len 
)
inlineoverridevirtual

Reimplemented from AudioStream.

◆ readSilence()

virtual size_t readSilence ( uint8_t *  buffer,
size_t  length 
)
inlinevirtualinherited

Source to generate silence: just sets the buffer to 0.

◆ refillReadBuffer()

void refillReadBuffer ( )
inlineprotectedinherited

Refill small read buffer (e.g. 8 bytes) to avoid single byte reads when calling read()

◆ removeNotifyAudioChange()

virtual bool removeNotifyAudioChange ( AudioInfoSupport bi)
inlinevirtualinherited

Removes a target in order not to be notified about audio changes.

Reimplemented in RTSPClient< TcpClient, UdpSocket >.

◆ reportIfDue()

void reportIfDue ( )
inlineprotected

◆ resetState()

void resetState ( )
inlineprotected

◆ setAudioInfo()

void setAudioInfo ( AudioInfo  info)
inlineoverridevirtual

Defines the input AudioInfo.

Reimplemented from AudioStream.

◆ setCallback()

void setCallback ( QualityCallback  cb)
inline

Register a callback for quality issue notifications.

◆ setClickThreshold()

void setClickThreshold ( float  ratio)
inline

Sample-to-sample jump threshold as ratio of max value (0.0 to 1.0)

◆ setClippingMargin()

void setClippingMargin ( float  ratio)
inline

Clipping is detected when sample >= max_value * (1 - margin)

◆ setClippingMinSamples()

void setClippingMinSamples ( int  samples)
inline

Minimum consecutive samples at max to count as clipping.

◆ setDropoutMinSamples()

void setDropoutMinSamples ( int  samples)
inline

Minimum consecutive near-silent samples to count as a dropout.

◆ setNoiseFloorBlockSize()

void setNoiseFloorBlockSize ( int  samples)
inline

Number of samples per RMS/noise-floor block (default 256)

◆ setNoiseFloorTracking()

void setNoiseFloorTracking ( float  attack,
float  release 
)
inline

How quickly the noise floor tracks a falling level (0.0-1.0, default 0.3). Higher = faster. How slowly it tracks a rising level (0.0-1.0, default 0.01). Lower = slower, so brief loud transients don't raise the estimated floor.

◆ setNotifyActive()

void setNotifyActive ( bool  flag)
inlineinherited

Deactivate/Reactivate automatic AudioInfo updates: (default is active)

◆ setOutput() [1/2]

virtual void setOutput ( AudioOutput out)
inlinevirtualinherited

Defines/Changes the output target and registers for audio change notifications.

Reimplemented in TimedStream, VolumeMeter, AudioInputMonitor, ReformatBaseStream, FormatConverterStream, and EncodedAudioStream.

◆ setOutput() [2/2]

void setOutput ( Print out)
inlineoverridevirtual

Defines/Changes the output target.

Implements ModifyingStream.

◆ setReporting()

void setReporting ( int  period_ms,
Print output 
)
inline

Enable periodic reporting of quality KPIs

Parameters
period_msReporting interval in milliseconds
outputPrint target (e.g. Serial)

◆ setSignalMargin()

void setSignalMargin ( float  db)
inline

dB the RMS level must stay above the noise floor to count as signal (default 6dB)

◆ setSignalPresenceMinBlocks()

void setSignalPresenceMinBlocks ( int  blocks)
inline

Consecutive blocks required above/below the margin before toggling signal_present (default 3)

◆ setSilenceThreshold()

void setSilenceThreshold ( float  ratio)
inline

Samples below this ratio of max value are considered silent.

◆ setStream() [1/2]

virtual void setStream ( AudioStream io)
inlinevirtualinherited

Defines/Changes the input & output and registers for audio change notifications.

Reimplemented in VolumeMeter, AudioInputMonitor, FormatConverterStream, ReformatBaseStream, TimedStream, and EncodedAudioStream.

◆ setStream() [2/2]

void setStream ( Stream in)
inlineoverridevirtual

Defines/Changes the input & output.

Implements ModifyingStream.

◆ setTonalityBufferSize()

void setTonalityBufferSize ( int  samples)
inline

Analysis buffer size (in samples) used by the built-in tonality detector. Larger = more accurate/expensive, smaller = cheaper/less accurate. Only relevant while using the built-in detector (i.e. before calling setTonalitySource()). Applied on the next begin()/setAudioInfo().

◆ setTonalityEnabled()

void setTonalityEnabled ( bool  enabled)
inline

Enable/disable the tonality gate (enabled by default using a built-in FrequencyDetectorAutoCorrelation). When disabled, signal_present depends only on the level/noise-floor gate. Re-enabling restores the built-in detector unless an external one was set via setTonalitySource().

◆ setTonalityMinConfidence()

void setTonalityMinConfidence ( float  min_confidence)
inline

Minimum tonality confidence (0.0-1.0, default 0.3) for a block to count as signal rather than noise.

◆ setTonalitySource()

void setTonalitySource ( FrequencyDetectorAutoCorrelation detector,
float  min_confidence = 0.3f,
int  channel = 0 
)
inline

Overrides the built-in tonality detector with an externally-owned one that you feed yourself (e.g. because you already run it elsewhere in the pipeline). You are responsible for calling begin()/write() on it; this class only reads its confidence().

Parameters
detectorThe autocorrelation detector to query.
min_confidenceMinimum tonality confidence (0.0-1.0, default 0.3).
channelChannel to query on the detector (default 0).

◆ setWriteBufferSize()

void setWriteBufferSize ( int  size)
inlineinherited

◆ stats()

const QualityStats & stats ( ) const
inline

Access the accumulated quality statistics.

◆ tonalityConfidence()

float tonalityConfidence ( ) const
inline

Last tonality/periodicity confidence reported by the tonality source (0 if none is set), see setTonalitySource()

◆ write() [1/2]

size_t write ( const uint8_t *  data,
size_t  len 
)
inlineoverridevirtual

Reimplemented from AudioStream.

◆ write() [2/2]

virtual size_t write ( uint8_t  ch)
inlineoverridevirtualinherited

◆ writeSilence()

virtual void writeSilence ( size_t  len)
inlinevirtualinherited

Writes len bytes of silence (=0).

Member Data Documentation

◆ _timeout

int _timeout = 10
protectedinherited

◆ auto_tonality

FrequencyDetectorAutoCorrelation auto_tonality
protected

◆ callback

QualityCallback callback = nullptr
protected

◆ click_threshold

float click_threshold = 0.5f
protected

◆ clipping_margin

float clipping_margin = 0.01f
protected

◆ clipping_min_samples

int clipping_min_samples = 3
protected

◆ consecutive_clipped

int consecutive_clipped = 0
protected

◆ consecutive_noise_blocks

int consecutive_noise_blocks = 0
protected

◆ consecutive_signal_blocks

int consecutive_signal_blocks = 0
protected

◆ consecutive_silent

int consecutive_silent = 0
protected

◆ dropout_min_samples

int dropout_min_samples = 10
protected

◆ has_prev_sample

bool has_prev_sample = false
protected

◆ in_clipping

bool in_clipping = false
protected

◆ in_dropout

bool in_dropout = false
protected

◆ info

AudioInfo info
protectedinherited

◆ is_notify_active

bool is_notify_active = true
protectedinherited

◆ last_report_time

uint32_t last_report_time = 0
protected

◆ max_value

float max_value = 32767.0f
protected

◆ noise_floor_attack

float noise_floor_attack = 0.3f
protected

◆ noise_floor_initialized

bool noise_floor_initialized = false
protected

◆ noise_floor_release

float noise_floor_release = 0.01f
protected

◆ notify_vector

Vector<AudioInfoSupport*> notify_vector
protectedinherited

◆ owns_tonality

bool owns_tonality = true
protected

◆ p_io

Stream* p_io = nullptr
protected

◆ p_out

Print* p_out = nullptr
protected

◆ p_report

Print* p_report = nullptr
protected

◆ p_tonality

FrequencyDetectorAutoCorrelation* p_tonality = nullptr
protected

◆ prev_sample

Vector<float> prev_sample
protected

◆ report_period_ms

int report_period_ms = 0
protected

◆ rms_block_count

int rms_block_count = 0
protected

◆ rms_block_size

int rms_block_size = 256
protected

◆ rms_sum_sq

double rms_sum_sq = 0
protected

◆ signal_margin_db

float signal_margin_db = 6.0f
protected

◆ signal_present_min_blocks

int signal_present_min_blocks = 3
protected

◆ silence_threshold

float silence_threshold = 0.01f
protected

◆ stats_data

QualityStats stats_data
protected

◆ tmp_in

RingBuffer<uint8_t> tmp_in {0}
protectedinherited

◆ tmp_out

RingBuffer<uint8_t> tmp_out {0}
protectedinherited

◆ tonality_channel

int tonality_channel = 0
protected

◆ tonality_enabled

bool tonality_enabled = true
protected

◆ tonality_min_confidence

float tonality_min_confidence = 0.3f
protected

◆ write_buffer_size

int write_buffer_size = MAX_SINGLE_CHARS
protectedinherited

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