AudioSig API Reference
Core Functions
Waveform Construction and Channels
generate_silence(duration, sample_rate, *, dtype=np.float32)
Return a newly allocated one-dimensional mono NumPy buffer filled with zeros.
Duration is in seconds, sample rate is in samples per second, and the sample
count is exactly int(duration * sample_rate), so fractional sample counts
are truncated. dtype must be a real NumPy floating dtype; the default is
float32. Invalid duration, sample rate, and dtype values raise
InvalidParameterError. Long silence creation should use bounded
application-level chunks rather than one arbitrarily large array.
downmix_to_mono(audio, *, channel_axis=-1)
Return a caller-owned mono array by taking the arithmetic mean over the
explicit channel axis. Input must be a finite real floating one- or
two-dimensional NumPy array; the source dtype and frame order are preserved.
One-dimensional input is already mono and is copied. The operation does not
clip or normalize amplitude. Invalid shape, axis, dtype, or sample values
raise AudioShapeError; the result is contiguous.
from audiosig import downmix_to_mono, generate_silence
silence = generate_silence(0.5, 24_000)
mono_soundfile = downmix_to_mono(frames_first, channel_axis=1)
mono_audiosig = downmix_to_mono(channels_first, channel_axis=0)
These functions do not perform file decoding/encoding, URL handling, playback, streaming, or audiobook composition.
Time and Pitch Effects
time_stretch(audio, rate, *, sample_rate=None, method='phase_vocoder', axis=-1, n_fft=2048, hop_length=None)
Change audio duration while approximately preserving pitch.
Parameters:
audio(np.ndarray): Input audio arrayrate(float): Stretch factor. Values > 1.0 make audio faster/shorter, < 1.0 slower/longersample_rate(int, optional): Required whenmethod='wsola'ormethod='esola'; used for speech-time geometrymethod('phase_vocoder','wsola', or'esola'): Select the generic or speech-oriented backend.'td_psola'is intentionally not atime_stretchmethod.axis(int): Sample axis (default: -1)n_fft(int): FFT window size (default: 2048)hop_length(int, optional): Hop size. Defaults to n_fft // 4
Returns: np.ndarray - Stretched audio with same dtype as input
Raises:
InvalidParameterError: If rate is not positive or parameters are invalidAudioShapeError: If audio array is invalid
ESOLA is an experimental speech backend with exact output length
round(input_samples / rate) and supported rates from 0.5 through 2.0. It
does not make a general music-quality or formant-preservation claim.
Example:
import numpy as np
from audiosig import time_stretch
audio = np.random.randn(24000).astype(np.float32)
faster = time_stretch(audio, rate=1.2) # 20% faster
slower = time_stretch(audio, rate=0.8) # 20% slower
pitch_shift(audio, *, sample_rate, semitones, bins_per_octave=12, method='phase_vocoder', axis=-1, n_fft=2048, hop_length=None, filter_width=32, rolloff=0.945)
Shift pitch by semitones while preserving exact input duration.
Parameters:
audio(np.ndarray): Input audio arraysample_rate(int): Audio sample rate in Hzsemitones(float): Pitch shift in semitones (positive = higher, negative = lower)bins_per_octave(int): Semitones per octave (default: 12)axis(int): Sample axis (default: -1)n_fft(int): FFT window size (default: 2048)hop_length(int, optional): Hop sizefilter_width(int): Resampling filter width (default: 32)method('phase_vocoder','wsola','esola', or'td_psola'): Pitch method.td_psoladirectly synthesizes voiced speech and does not resample the complete waveform.rolloff(float): Pitch-resampler rolloff (default: 0.945)
Returns: np.ndarray - Pitch-shifted audio with exact same length as input
Example:
from audiosig import pitch_shift
# Raise pitch by 2 semitones
higher = pitch_shift(audio, sample_rate=24000, semitones=2.0)
# Lower pitch by 5 semitones
lower = pitch_shift(audio, sample_rate=24000, semitones=-5.0)
apply_speech_effects(audio, *, sample_rate, rate=1.0, semitones=0.0, gain_db=0.0, axis=-1, clip=False, method='wsola', n_fft=2048, hop_length=None, filter_width=32, rolloff=0.945)
Apply numeric speech effects using one planned pitch/rate time-scale pass,
optional resampling, and gain. WSOLA is the default speech backend;
method='phase_vocoder' selects the generic reference path,
method='esola' selects the experimental epoch-synchronous path, and
method='td_psola' selects the experimental direct speech pitch/prosody path.
The output length is exactly round(input_samples / rate) for non-empty input.
TD-PSOLA supports 0.75 <= rate <= 1.5 and -6 <= semitones <= 6; it does not
guarantee vocal-formant preservation. This compositor does not parse SSMD strings and raises typed
AudioSig exceptions for invalid input or parameters.
apply_speech_effects_envelope(audio, *, sample_rate, rate_points=(), pitch_points=(), time_base='output', interpolation='linear', method='wsola', axis=-1)
Apply continuously varying playback rate and pitch controls in one speech-processing operation. AudioSig 0.1.5 is the minimum version containing this API.
Control points:
rate_points:(output_seconds, rate_factor)pairs. Factors must be finite and positive.1.0is unchanged, values below1.0slow playback, and values above1.0speed it up.pitch_points:(output_seconds, semitones)pairs. Values are finite semitone offsets, where0.0is unchanged and positive values raise pitch.At least one curve must be non-empty. Omitted rate and pitch curves mean constant
1.0and0.0, respectively.Every non-empty curve starts exactly at
0.0seconds. Times increase strictly.interpolation='linear'interpolates rate factors and semitones; the last value is held after the final point.time_base='output'is the supported time base. Point times refer to the transformed output, so a transition ending at0.3seconds lasts 0.3 seconds in the result regardless of rate changes.methodaccepts'wsola'or'td_psola'. For nonconstant rate with neutral pitch, WSOLA selects mapped WSOLA and TD-PSOLA selects voiced pulse synthesis with mapped WSOLA fallback. Any nonconstant pitch uses the coordinated TD-PSOLA voiced path and mapped WSOLA fallback for unvoiced spans.axisselects the sample dimension. Every channel uses the same timing curves and frame count.
The rate map integrates r(y) to obtain source time x(y). The output duration is the inverse-map time satisfying x(y) = input_frames / sample_rate, and the returned frame count is round(y * sample_rate) using float64 timing calculations. Pitch-only automation preserves the input frame count. A short clip evaluates only the portion of each curve reached by its output; AudioSig does not compress the curve to force its final value.
Constant curves agree with apply_speech_effects. Identity curves return an independent copy. Silence remains zero. The operation is deterministic for the same input and AudioSig version, but exact PCM is not promised across versions.
from audiosig import apply_speech_effects_envelope, speech_effects_output_frames
out = apply_speech_effects_envelope(
audio,
sample_rate=24_000,
rate_points=((0.0, 1.0), (0.45, 0.85)),
pitch_points=((0.0, 0.0), (0.30, 2.0)),
)
predicted_frames = speech_effects_output_frames(
audio.shape[-1],
sample_rate=24_000,
rate_points=((0.0, 1.0), (0.45, 0.85)),
)
assert out.shape[-1] == predicted_frames
Malformed points, unsupported method/options, and invalid sample rates raise InvalidParameterError; malformed audio shapes use AudioShapeError.
Resampling
resample(audio, *, source_rate, target_rate, axis=-1, filter_width=32, rolloff=0.945, length_mode='round')
Resample audio with a windowed-sinc anti-aliasing filter.
Parameters:
audio(np.ndarray): Input audio arraysource_rate(float): Source sample rate in Hztarget_rate(float): Target sample rate in Hzaxis(int): Sample axis (default: -1)filter_width(int): Filter kernel width (default: 32)rolloff(float): Filter rolloff frequency (default: 0.945)length_mode(str): Length calculation mode (‘round’ or ‘ceil’)
Returns: np.ndarray - Resampled audio
Output Length:
length_mode='round':round(input_length * target_rate / source_rate)length_mode='ceil':ceil(input_length * target_rate / source_rate)
Example:
from audiosig import resample
# Downsample from 48kHz to 16kHz
downsampled = resample(audio_48k, source_rate=48000, target_rate=16000)
# Upsample from 8kHz to 24kHz
upsampled = resample(audio_8k, source_rate=8000, target_rate=24000)
resample_to_length(audio, length, *, axis=-1, filter_width=32, rolloff=0.945)
Resample audio to an exact sample count along the selected sample axis. This
is a sample-count operation, not a sample-rate conversion. length may be
zero; an empty input can only be resampled to zero samples.
resample_speed(audio, speed, *, axis=-1, filter_width=32, rolloff=0.945)
Change playback speed by resampling. Values above one make audio shorter and
higher pitched; values below one make it longer and lower pitched. Use
time_stretch when pitch should remain approximately unchanged.
from audiosig import resample_speed, resample_to_length
exact = resample_to_length(audio_48k, 12_000)
faster = resample_speed(audio_48k, speed=1.25)
Amplitude Processing
apply_gain_db(audio, db, *, clip=False)
Apply a decibel gain to audio.
Parameters:
audio(np.ndarray): Input audio arraydb(float): Gain in decibels (negative = attenuation)clip(bool): If True, clip output to [-1.0, 1.0] (default: False)
Returns: np.ndarray - Gain-adjusted audio
Example:
from audiosig import apply_gain_db
louder = apply_gain_db(audio, db=6.0) # +6 dB gain
quieter = apply_gain_db(audio, db=-3.0) # -3 dB attenuation
clipped = apply_gain_db(audio, db=12.0, clip=True)
peak_normalize(audio, *, peak=1.0, eps=1e-12)
Scale audio so its absolute peak equals the target value.
Parameters:
audio(np.ndarray): Input audio arraypeak(float): Target peak amplitude (default: 1.0)eps(float): Silence threshold (default: 1e-12)
Returns: np.ndarray - Normalized audio
Example:
from audiosig import peak_normalize
# Normalize to 0.9 peak
normalized = peak_normalize(audio, peak=0.9)
# Silent audio is returned unchanged
silent = np.zeros(1000, dtype=np.float32)
still_silent = peak_normalize(silent)
Loudness Measurement
integrated_loudness(audio, *, sample_rate, axis=-1)
Return BS.1770-style integrated programme loudness in LUFS. Audio is K-weighted, divided into complete 400 ms blocks with a 100 ms hop, then processed with the -70 LUFS absolute gate and -10 LU relative gate. Signals shorter than one complete block return -math.inf without invented padding. V1 accepts one-dimensional mono float32/float64 arrays; the mandatory sample rate is 24,000 Hz, and 44,100 and 48,000 Hz are also supported. Digital silence returns -math.inf.
sample_peak_dbfs(audio, *, axis=-1)
Return 20 * log10(max(abs(audio))) in dBFS. Digital silence returns -math.inf. This is a sample peak measurement, not a loudness normalization operation.
true_peak_dbtp(audio, *, sample_rate, axis=-1, oversample=4)
Estimate inter-sample peak in dBTP using AudioSig’s NumPy windowed-sinc resampler. oversample must be a positive integer; 1 is equivalent to sample peak. The function never clips, limits, or modifies the source audio. Digital silence returns -math.inf.
LoudnessMetrics and measure_loudness(audio, *, sample_rate, axis=-1, true_peak_oversample=4)
LoudnessMetrics is an immutable dataclass containing integrated_lufs, sample_peak_dbfs, and true_peak_dbtp. measure_loudness composes the three measurements without applying policy or changing the input. Stable imports are available from audiosig; the PyKokoro minimum release is 0.1.3.
Silence Detection
Voice Activity Detection
normalized_energy_vad(audio, sample_rate, *, frame_duration_ms=5.0, energy_threshold=0.02, axis=-1, pad_end=False)
Detect voice activity using normalized RMS energy.
Parameters:
audio(np.ndarray): Input audio arraysample_rate(int): Audio sample rate in Hzframe_duration_ms(float): Frame duration in milliseconds (default: 5.0)energy_threshold(float): Threshold in [0, 1] (default: 0.02)axis(int): Sample axis (default: -1)pad_end(bool): Include trailing partial frame (default: False)
Returns: np.ndarray - Boolean array indicating active frames
Example:
from audiosig import normalized_energy_vad
activity = normalized_energy_vad(
audio,
sample_rate=24000,
frame_duration_ms=10,
energy_threshold=0.15,
)
# Count active frames
active_frames = np.sum(activity)
relative_db_vad(audio, *, frame_length=2048, hop_length=512, threshold_db=40.0, top_db=None, axis=-1, pad_end=False)
Detect voice activity using relative dB threshold.
Parameters:
audio(np.ndarray): Input audio arrayframe_length(int): Analysis frame length (default: 2048)hop_length(int): Hop length (default: 512)threshold_db(float): dB below peak to consider active (default: 40.0)top_db(float, optional): Alias for threshold_dbaxis(int): Sample axis (default: -1)pad_end(bool): Include trailing partial frame (default: False)
Returns: np.ndarray - Boolean array indicating active frames
energy_based_vad(audio, sample_rate=None, *, frame_duration_ms=5.0, energy_threshold=None, frame_length=2048, hop_length=512, threshold_db=40.0, top_db=None, axis=-1, pad_end=False)
Unified voice activity detection interface.
Algorithm Selection:
With
sample_rate: Usesnormalized_energy_vadWithout
sample_rate: Usesrelative_db_vad
Returns: np.ndarray - Boolean array indicating active frames
Speech Bounds
find_speech_start(audio, sample_rate=None, **kwargs)
Find the first active sample index.
Returns: int - First active sample index, or 0 if no activity
find_speech_bounds(audio, sample_rate=None, **kwargs)
Find speech start and end bounds.
Returns: np.ndarray - [start, end] sample indices, or [0, 0] if no speech
Example:
from audiosig import find_speech_bounds
bounds = find_speech_bounds(audio, sample_rate=24000)
if not np.array_equal(bounds, [0, 0]):
start, end = bounds
speech = audio[start:end]
Smooth Cut-Point Selection
find_smooth_cut_point(audio, *, start, end, anchor=None, window_length=120, axis=-1)
Select a deterministic waveform boundary in the half-open sample interval [start, end). The candidate minimizes a fixed combination of local RMS, adjacent endpoint amplitude, cross-boundary slope, and distance from the preferred anchor. This is not a silence detector and returns a legal candidate for continuous voiced or noisy audio.
Parameters:
audio(np.ndarray): Finite float32 or float64 audio arraystart,end(int): Legal half-open search bounds with0 <= start < end <= sample_countanchor(int, optional): Preferred sample index; defaults to the middle legal candidate and may lie outside the intervalwindow_length(int): Local RMS analysis length in samples, at least 1axis(int): Sample axis, default-1; all other dimensions are conservatively aggregated
Returns: int for a legal candidate, or None only for the explicit empty case start=0, end=0 on empty audio.
Invalid arrays, axes, bounds, anchors, and parameters raise AudioShapeError or InvalidParameterError. Ties are resolved by total score, anchor distance, then lower sample index. The caller remains responsible for semantic interval legality and retry policy.
Silence Trimming
trim(audio, *, top_db=60.0, ref=np.max, frame_length=2048, hop_length=512, aggregate=np.max, axis=-1, center=True, pad_mode='constant')
Trim leading and trailing silence.
Parameters:
audio(np.ndarray): Input audio arraytop_db(float): Silence threshold in dB (default: 60.0)ref(float or callable): Reference amplitude (default: np.max)frame_length(int): Analysis frame length (default: 2048)hop_length(int): Hop length (default: 512)aggregate(callable): Aggregation function (default: np.max)axis(int): Sample axis (default: -1)center(bool): Use centered frames (default: True)pad_mode(str): Padding mode (default: ‘constant’)
Returns: tuple[np.ndarray, np.ndarray] - (trimmed_audio, [start, end])
Example:
from audiosig import trim
trimmed, interval = trim(audio, top_db=40.0)
print(f"Kept samples {interval[0]} to {interval[1]}")
split(audio, *, top_db=60.0, ref=np.max, frame_length=2048, hop_length=512, aggregate=np.max, axis=-1, center=True, pad_mode='constant')
Split audio into non-silent intervals.
Parameters: Same as trim()
Returns: np.ndarray - Array of [start, end) half-open intervals, shape (n_intervals, 2)
Example:
from audiosig import split
intervals = split(audio, top_db=40.0, frame_length=512, hop_length=128)
for start, end in intervals:
segment = audio[start:end]
process(segment)
Frame Analysis
frame_signal(audio, *, frame_length=None, hop_length=None, sample_rate=None, frame_ms=20.0, hop_ms=10.0, axis=-1, center=False, pad_mode='constant', pad_end=False)
Split audio into overlapping frames.
Parameters:
audio(np.ndarray): Input audio arrayframe_length(int, optional): Frame length in sampleshop_length(int, optional): Hop length in samplessample_rate(int, optional): Sample rate (for ms conversion)frame_ms(float): Frame duration in ms (default: 20.0)hop_ms(float): Hop duration in ms (default: 10.0)axis(int): Sample axis (default: -1)center(bool): Center frames with padding (default: False)pad_mode(str): Padding mode (default: ‘constant’)pad_end(bool): Pad to include trailing samples (default: False)
Returns: np.ndarray - Framed audio with shape (..., n_frames, frame_length)
frame_rms(audio, *, frame_length=2048, hop_length=512, axis=-1, center=True, pad_mode='constant', pad_end=False, normalize=False, dtype=np.float32)
Compute RMS amplitude for each frame.
Returns: np.ndarray - RMS values per frame
Set pad_end=True to include a zero-padded trailing partial frame. Set
normalize=True to scale each leading-dimension slice independently to
[0, 1].
short_time_energy(audio, *, frame_length=2048, hop_length=512, axis=-1, center=False, pad_end=False)
Calculate mean-square energy for each frame.
Returns: np.ndarray - Energy values per frame
zero_crossing_rate(audio, *, frame_length=2048, hop_length=512, axis=-1, center=False, pad_end=False, normalize=False)
Calculate zero-crossing rate for each frame.
Parameters:
normalize(bool): Normalize to [0, 1] range (default: False)
Returns: np.ndarray - Zero-crossing rates per frame
spectral_flux(audio, *, frame_length=2048, hop_length=512, axis=-1, center=False, pad_end=False, window='hann', normalize=False)
Calculate spectral flux between adjacent frames.
Parameters:
window(str): Window function (‘hann’ or ‘hamming’)normalize(bool): Normalize to [0, 1] range (default: False)
Returns: np.ndarray - Spectral flux values per frame
Spectral and Pitch Analysis
These stable submodule APIs are imported from audiosig.spectral and
audiosig.pitch; they are intentionally not re-exported through the root
namespace.
Spectral features (audiosig.spectral)
stft(audio, *, n_fft, hop_length, center=True)returns the existing Hann-windowed complex STFT with shape(..., n_fft // 2 + 1, frames). It preserves the private spectral path’s conventions.istft(spectrum, *, n_fft, hop_length, length=None, center=True, dtype=np.float64)uses the existing overlap-add inverse and returnsfloat32orfloat64samples.power_spectrogram(audio, *, n_fft, hop_length, center=True, power=2.0)returns linearabs(STFT) ** power, without normalization or dB conversion.mel_filterbank(*, sample_rate, n_fft, n_mels, f_min=0.0, f_max=None, mel_scale='slaney', norm='slaney')creates Slaney mel triangles on exact real-FFT bin centers.norm=Nonedisables area normalization.mel_spectrogram(..., log=False, log_floor=1e-10)returns linear mel power by default.log=Truereturnsln(max(mel_power, log_floor)); it does not apply a power-to-dB transform.mfcc(..., n_fft=1024, hop_length=256, n_mfcc=13, n_mels=40, center=True, ...)computes an orthonormal DCT-II of natural-log mel power. Output shape is(..., n_mfcc, frames); coefficient zero is included.frame_times(n_frames, *, sample_rate, hop_length, frame_length=None, center=True)returns frame-center times in seconds. Forcenter=False,frame_lengthis required.match_frames(reference, estimate, *, frame_axis=-1)accepts only arrays with identical shape. It validates correspondence and never crops or aligns.
Pitch tracking (audiosig.pitch)
PitchTrack is a frozen, slotted result object with frame_times_s, f0_hz,
voiced, and confidence arrays. pitch_track(audio, *, sample_rate, hop_length=None, f0_min=60.0, f0_max=500.0) accepts only mono arrays shaped
(samples,). The optional hop changes analysis geometry; None preserves the
legacy tracker default. Callers with multiple channels must explicitly select a
channel or downmix before analysis. Unvoiced frames are identified by voiced;
consult the track’s voicing mask rather than treating all F0 values as speech
pitch.
Reference Metrics
Import metrics from audiosig.metrics; intelligibility functions live in
audiosig.intelligibility. Here, a reference is decoded reference waveform
samples, not a transcript or reference text. Each function returns a frozen,
slotted MetricResult containing name, value, unit, higher_is_better,
parameters, and diagnostics. Every feature and transformation parameter used
by a metric is recorded in parameters. value is float | None; undefined
pitch RMSE is represented by None, not a fabricated zero.
All pairwise metrics require finite floating-point arrays with identical shape
and sample count, and require estimate_sample_rate (when supplied) to equal
sample_rate. The default alignment='none' is the only supported alignment.
No metric implicitly aligns, resamples, truncates, normalizes loudness, or
converts channels. axis selects the sample dimension where supported. Any
necessary preparation is the caller’s responsibility.
Function |
Unit |
Direction |
Definition / notes |
|---|---|---|---|
|
dB |
higher |
Global reference energy over residual energy; no gain fitting. |
|
dB |
higher |
Explicitly unscaled reference-residual SDR; numerically equal to SNR. |
|
dB |
higher |
Scale-invariant projection, with optional per-lane mean removal. |
|
dB |
lower |
Mean per-frame RMS absolute log-magnitude STFT distance. |
|
dB |
lower |
Mean per-frame RMS mel-power dB distance. |
|
ln-power |
lower |
Global mean absolute natural-log mel-power difference. |
|
dB |
lower |
Orthonormal-DCT-II MFCC distance, with optional c0; no DTW. |
|
ln-Hz |
lower |
Natural-log F0 RMSE on jointly voiced frames; |
|
fraction |
lower |
Fraction of pitch frames with a voicing-decision mismatch. |
Formula conventions and comparability
Let r be the reference waveform and y the estimate. SNR and this package’s
explicitly unscaled SDR both use
10 * log10(sum(r**2) / sum((r - y)**2))
There is no gain fit or centering in these two metrics. A zero-energy reference
is invalid; an exact reconstruction has zero residual and returns positive
infinity. SI-SDR optionally removes each lane’s mean first (default true), then
flattens the remaining samples and fits one global scale
alpha = dot(y, r) / dot(r, r). Its score is
10 * log10(sum((alpha*r)**2) / sum((y - alpha*r)**2)).
Let X_r and X_y be reference/estimate STFTs, and M_r and M_y their
mel-power features. Means below cover every lane and frame (and, for log-mel,
every mel band); spectral distances take an RMS across frequency or mel bands
before averaging lanes and frames.
LSD = mean(lane, frame) sqrt(mean_bin(
(max(20*log10(abs(X_r)), db_floor)
- max(20*log10(abs(X_y)), db_floor))**2))
mel_spectral_distance = mean(lane, frame) sqrt(mean_mel(
(max(10*log10(M_r), db_floor)
- max(10*log10(M_y), db_floor))**2))
log_mel_l1 = mean(abs(ln(max(M_r, log_floor)) - ln(max(M_y, log_floor))))
Defaults are n_fft=1024, hop_length=256, center=True, n_mels=80,
db_floor=-120.0, and log_floor=1e-10, as applicable. Mel features use
Slaney scaling and area normalization. The complete chosen recipe is recorded
in MetricResult.parameters.
For MFCC vectors c_r and c_y, MCD is
mean(lane, frame) (10*sqrt(2)/ln(10)) *
sqrt(sum_{k in K} (c_r[k] - c_y[k])**2)
where K={1,...,n_mfcc-1} by default and K={0,...,n_mfcc-1} with
include_c0=True. There is no DTW. MCD scores are comparable only when the
complete MFCC recipe, including sample rate, FFT/hop, mel scale and count,
frequency limits, log floor, centering, coefficient count, and c0 policy,
matches.
For pitch, log_f0_rmse is
sqrt(mean((ln(f0_reference) - ln(f0_estimate))**2)) over jointly voiced
frames. It returns None when there are no such frames. The V/UV error is the
number of differing voiced/unvoiced decisions divided by all pitch frames.
MetricResult.higher_is_better states the direction for each metric; values
are not clipped to an arbitrary range.
Spectral and pitch parameters, floors, feature geometry, and diagnostics are recorded in each result. Pitch metrics are mono-only. Log-F0 RMSE compares only jointly voiced frames; V/UV error compares the complete voicing masks.
STOI and ESTOI (audiosig.intelligibility)
stoi(reference, estimate, *, sample_rate, estimate_sample_rate=None, alignment='none') and estoi(...) return higher-is-better scores. The
reference is waveform audio, not a transcript. Both effective sample rates must
be exactly 10,000 Hz; when estimate_sample_rate is omitted it defaults to
sample_rate. Inputs must be finite mono float32 or float64 arrays with
identical sample counts. Other rates, stereo, unequal lengths, unsupported
alignment, and fewer than 30 active frames after silence removal are rejected.
All transformations are caller-owned: AudioSig does no file decoding, trimming,
resampling, time alignment, truncation, loudness normalization, or downmixing.
Both implementations use complete 256-sample frames at a 128-sample hop,
symmetric Hann weighting, a 512-point FFT, 15 one-third-octave bands beginning
at 150 Hz, and contiguous 30-frame segments. Reference frames below -40 dB of
the peak weighted RMS are removed and the remaining active frames are
compressed. Band edges are assigned to nearest FFT bins. These fixed algorithm
settings, the score-specific parameters, and input rates are recorded in each
MetricResult.parameters.
STOI norm-matches each estimate segment to its reference segment, clips the
normalized estimate at reference * (1 + 10**(15/20)), computes mean-centered
correlation for each band and segment, and averages those correlations. ESTOI
centers and unit-normalizes each band’s 30-frame trajectory, then centers and
unit-normalizes across bands at each frame; normalized segment inner products
are averaged across frames and segments.
These are signal-based intelligibility measures, not MOS prediction, human listening, or model inference. See the quality-evaluation notes for paper references and the independent numerical-oracle procedure.
Utility Functions
Decibel Conversion
amplitude_to_db(amplitude, *, ref=1.0, amin=1e-5, top_db=None)
Convert amplitude to decibels.
Parameters:
amplitude(np.ndarray): Input amplitude valuesref(float or callable): Reference amplitude (default: 1.0)amin(float): Minimum amplitude floor (default: 1e-5)top_db(float, optional): Clip to this range below peak
Returns: np.ndarray - Decibel values
power_to_db(power, *, ref=1.0, amin=1e-10, top_db=None)
Convert power to decibels.
Parameters:
power(np.ndarray): Input power valuesref(float or callable): Reference power (default: 1.0)amin(float): Minimum power floor (default: 1e-10)top_db(float, optional): Clip to this range below peak
Returns: np.ndarray - Decibel values
Other Utilities
rms(audio, *, axis=-1)
Compute overall RMS amplitude.
Returns: np.ndarray - RMS value(s)
abs2(values, *, dtype=None)
Compute squared magnitude for real or complex values.
Returns: np.ndarray - Squared values
frames_to_samples(frames, *, hop_length=512, n_fft=None)
Convert frame indices to sample indices.
Returns: int or np.ndarray - Sample indices
median_filter_numpy(values, size=3, *, window_size=None, mode='edge')
Apply median filter along the final axis.
Parameters:
mode(str): Boundary mode (‘edge’ or ‘truncate’)
Returns: np.ndarray - Filtered values
non_silent_frames(audio, *, top_db=60.0, ref=np.max, frame_length=2048, hop_length=512, aggregate=np.max, axis=-1, center=True, pad_mode='constant')
Return boolean mask of non-silent frames.
Returns: np.ndarray - Boolean mask
activity_to_intervals(activity, *, hop_length, sample_count, min_frames=1)
Convert frame activity mask to clipped sample intervals. min_frames filters
out active runs shorter than the requested number of frames.
Returns: np.ndarray - Half-open [start, end) intervals
Exceptions
AudioSignalError
Base exception for all AudioSig operations.
InvalidParameterError(AudioSignalError, ValueError)
Raised when a parameter is outside the supported domain.
AudioShapeError(AudioSignalError, ValueError)
Raised when audio array shape or dtype is unsupported.
Type Annotations
All public functions include full type annotations. The package is PEP 561 compatible with a py.typed marker.
import numpy as np
from audiosig import time_stretch
# Type checking works with mypy/pyright
result: np.ndarray = time_stretch(audio, rate=1.1)