treble_tsdk.scene.snr_utils

Two distinct SNR estimation paths live here — do not confuse them:

  • Predicted (predict_snr_breakdown(), wrapped by predict_snr()/predict_snr_breakdown) — a fast, metadata-only estimate from per-band octave SPL values already attached to the source samples and IRs, without rendering or convolving any audio. Requires enrich_with_acoustic_parameters() on the IR collection and enrich_with_spl() on every audio dataset involved, run before the tracks in track_map were generated (not merely before this function is called): each generated track embeds a snapshot AudioSampleReference at generation time (see enrich_with_spl()). Accuracy against measured SNR is roughly -0.2 dB mean error, 1.5 dB standard deviation.

  • Measured (estimate_snr()) — ground truth, computed from actually rendered audio via the ITU-T P.56 active-speech level (see active_signal_level()), but requires the audio to already be rendered.

Functions

active_signal_level(signal)

Measure the active speech level (ITU-T P.56) of a mono signal and return it together with a per-sample active-speech mask.

apply_active_speech_mask(audio_signal)

Return a new AudioSignal containing only the samples flagged as active speech by the ITU-T P.56 detector (see active_signal_level()).

bandwidths(bands)

Compute the bandwidth (Hz) of each octave band.

estimate_snr(speech, noise[, return_per_band])

Estimate the signal-to-noise ratio between a speech signal and a noise signal, returning one SNR value per channel.

predict_snr_breakdown(track_map, ...[, ...])

Estimate the SNR of an audio scene together with the target and noise levels.

Classes

SNRBreakdown

Detailed result of an SNR prediction.

class treble_tsdk.scene.snr_utils.SNRBreakdown

Detailed result of an SNR prediction.

Levels are expressed in decibels on the same (pressure-squared pseudo-power) scale used internally by the estimator, so snr_db == target_level_db - noise_level_db by construction. They are time-weighted by the target’s active intervals, matching the SNR computation.

__init__(snr_db: float, target_level_db: float, noise_level_db: float) None
noise_level_db: float
snr_db: float
target_level_db: float
treble_tsdk.scene.snr_utils.active_signal_level(signal: AudioSignal | ConvolvedAudioSignal) tuple[float, np.ndarray]

Measure the active speech level (ITU-T P.56) of a mono signal and return it together with a per-sample active-speech mask.

The level is reported in dBov (decibels relative to a digital full scale of 1.0). If a non-zero signal is too quiet/steady for P.56 to classify any part of it as active, the level falls back to the signal’s own long-term level and the mask is all-True. Empty or zero-energy signals return the silence floor with an all-False mask.

Implementation follows the algorithm in clause 8 of Recommendation ITU-T P.56 (12/2011):

  • Process 1 accumulates the long-term energy (sum of squares).

  • Process 2 forms the envelope via two-stage exponential smoothing of the rectified signal, compares it against a geometric ladder of fixed thresholds, and accumulates an activity count (with hangover) per threshold.

  • For each threshold j, active-level estimate A_j and threshold level C_j (both in dB) bracket the true active level at the point where A - C equals margin M, found by interpolating on the decibel scale between the two bracketing thresholds.

Parameters:

signal – Mono input signal (channel 0 is used).

Returns:

(active_level_dbov, active_mask).

treble_tsdk.scene.snr_utils.apply_active_speech_mask(audio_signal: AudioSignal) AudioSignal | None

Return a new AudioSignal containing only the samples flagged as active speech by the ITU-T P.56 detector (see active_signal_level()).

Parameters:

audio_signal (AudioSignal) – Input mono signal (channel 0 is used).

Return AudioSignal | None:

A new AudioSignal with only the active-speech samples, or None if no active speech was detected.

treble_tsdk.scene.snr_utils.bandwidths(bands: dict[int, OctaveBand]) numpy.ndarray

Compute the bandwidth (Hz) of each octave band.

Parameters:

bands – The octave bands to measure, keyed by their integer label.

Returns:

An array with one bandwidth value (upper - lower) per band, in the same order as bands.

treble_tsdk.scene.snr_utils.estimate_snr(speech: AudioSignal | ConvolvedAudioSignal, noise: AudioSignal | ConvolvedAudioSignal, return_per_band: bool = False) list[float] | None | tuple[list[float] | None, list[dict[str, float]] | None]

Estimate the signal-to-noise ratio between a speech signal and a noise signal, returning one SNR value per channel.

Channel count follows from how the scene was rendered: render_mode sets the noise’s channel count (mono for RenderMode.MONO, multichannel for RenderMode.DEVICE) and target_render_mode sets the speech/target’s (mono for *_MONO modes, multichannel for device modes). The output has as many channels as the larger signal: a mono signal broadcasts to every output channel, and two equal-width multichannel signals pair one-to-one. Two multichannel signals with different channel counts (only possible from a SPATIAL render) have no meaningful pairing and raise.

The P.56 active-speech mask is derived from channel 0 of speech and applied to every paired speech/noise channel.

Parameters:
  • speech – Speech signal (one or more channels).

  • noise – Noise signal (one or more channels).

  • return_per_band – When True, also return per-octave-band SNR values per channel.

Returns:

snr_db_per_channel (one entry per output channel) by default, or (snr_db_per_channel, per_band_snr_db_per_channel) when return_per_band is True. Returns None for the SNR values when no active speech is detected.

treble_tsdk.scene.snr_utils.predict_snr_breakdown(track_map: list['TrackMap'], scene_duration_s: float, target_indices: list[int], device_noise: StaticNoiseTrack | list[StaticNoiseTrack] | None = None, listener_filter_definitions: list[FilterDefinition] | None = None) SNRBreakdown | None

Estimate the SNR of an audio scene together with the target and noise levels.

Requires per-band SPL metadata already attached: enrich_with_acoustic_parameters() on the IR collection the tracks’ IRs came from, and enrich_with_spl() on every audio dataset feeding a track in track_map (target and noise alike) — run before the tracks in track_map were generated, since each generated track’s samples are frozen AudioSampleReference snapshots that don’t pick up enrichment applied afterward. See the module docstring for the full predicted-vs-measured SNR distinction and accuracy caveats.

Parameters:
  • track_map – The track map to use for the SNR estimation.

  • scene_duration_s – Total scene duration in seconds.

  • target_indices – Indices into track_map designating the target tracks; every other track is treated as noise.

  • device_noise – The device noise definitions.

  • listener_filter_definitions – Filters applied by the scene listener (filter_definitions) to the final mixed signal. Unlike a track’s own filter_definitions (which only shape that track’s contribution), these apply equally to every track’s estimated power.

Returns:

An SNRBreakdown, or None when SNR cannot be estimated.