Quickstart
Scoring Two Files
The simplest usage: pass two file paths and read the score back.
from audio_samples_qoe import visqol
score = visqol("reference.wav", "degraded.wav")
print(f"MOS-LQO: {score:.3f}") # e.g. 3.842
Files are decoded with the native Rust reader, so no Python audio library is needed. WAV and FLAC are supported. Any sample rate and channel count is accepted; the pipeline mixes down to mono and resamples internally.
Scoring In-Memory Signals
Build signals with the audio_samples generators. They return
audio_samples.AudioSamples already carrying a sample rate, so you can
pass them straight in:
from audio_samples import sine_wave, white_noise
from audio_samples_qoe import visqol
RATE = 48_000
ref = sine_wave(440, 5.0, RATE)
deg = ref + white_noise(5.0, RATE, amplitude=0.02, seed=0)
score = visqol(ref, deg)
Mixing Paths and In-Memory Signals
The two arguments are independent, and any combination works:
from pathlib import Path
score = visqol(Path("reference.wav"), deg) # path + AudioSamples
score = visqol(ref, "degraded.wav") # AudioSamples + path
score = visqol("reference.wav", "degraded.wav") # both paths
score = visqol(ref, deg) # both in-memory
Selecting a Mode
audio mode (the default) is for full-bandwidth content; speech mode is
for narrowband and wideband voice:
score = visqol(ref, deg, mode="speech")
See Scoring Modes for the differences between them.
Parallel Scoring
The GIL is released while ViSQOL computes, so many pairs can be scored
concurrently with a thread pool — file paths, in-memory AudioSamples
objects, and a single AudioSamples shared across calls (e.g. one clean
reference scored against many candidates) are all safe to use this way:
from concurrent.futures import ThreadPoolExecutor
from audio_samples_qoe import visqol
pairs = [("ref1.wav", "deg1.wav"), ("ref2.wav", "deg2.wav")]
with ThreadPoolExecutor() as pool:
scores = list(pool.map(lambda p: visqol(*p), pairs))
# A single shared reference, scored concurrently against many candidates:
with ThreadPoolExecutor() as pool:
scores = list(pool.map(lambda deg: visqol(reference, deg), candidates))