Analyze speech quality
Request
- Base URL: https://audiolab.tools
- URL: https://audiolab.tools/v1/voicelab/qa
- Auth: HTTP bearer
Request body
Public http(s) URL to the audio file (alternative to multipart upload).
Path returned by /api/upload-url, for audio that has no public URL. Readable only by the key that uploaded it, and kept for about an hour so a follow-up question about the same file does not need a re-upload.
Send the curves as well: rmsEnvelope, voicedMask, segments and segmentalSnrPerSegmentDb. Off by default since 22 September 2026, because they are ~98% of the payload and no answer needs them. Raw or multipart callers use ?series=true.
Round the numbers to what the measurement is worth: dB and LUFS to 2 decimals, seconds to 3, shares to 3, Hz to 1. Same keys, same types, only fewer decimals. Off by default: without it you get the full precision, exactly as before. Supported on mixlab/analyze, voicelab/qa, signallab and analyze/profile.
Add one extra key, measureStatus, with the status (validated, proxy, beta, withdrawn, planned), the basis, how it works (dsp, model, mixed) and, where known, the margin of every measure in the answer. Off by default: without it the answer has no extra key. Supported on mixlab/analyze, voicelab/qa, signallab and analyze/profile.
Which speech detector finds the speech in the recording; it decides speechRatio, speechSec, silenceSec, longSilences, segments and the measures that read the pauses. v1 is the first detector and is the default until 15 January 2027; k2 lets a phrase run on into its soft word starts and endings (by at most 100 ms per side) and was better on new speakers in the tests (frame F1 from 0.88 to 0.94 on clean audio and noise at 20 and 10 dB; see the status of voice.speechRatio at https://audiolab.tools/lenses). The same keys and types in both, only the values differ: with k2 the speech ratio reads about 5 to 14 points higher, everything that reads the speech frames or the pauses moves with it, signalToNoiseDb is corrected below 16 dB and reads about 4 to 5 dB lower at 10 dB noise and below (closer to the true ratio), and a pause measure is null when no pause frame is left; brightness, sibilanceRisk, noiseFloorDb and peakDb do not move (details: https://audiolab.tools/docs/start/changes-and-deprecation). From 15 January 2027 the default becomes k2 and v1 stays selectable until at least 15 April 2027. Supported on voicelab/qa, voicelab/segments and analyze/profile.
Example request
{
"url": "https://audiolab.tools/reference/is-original.mp3"
}Response
Voice analysis complete.
Speech bursts per second, counted from deep dips in the envelope. Not a syllable count.
Mean spectral centre of every non-silent frame (pauses with noise included) over 2500 Hz, capped at 1.
What the active material looks like, from the frame labels shared with the SignalLab timeline: voice, music or noise. Voice QA assumes speech input, so read every voice figure as a figure about the material rather than about a voice as soon as this is not "voice". Null when nothing rises above the silence gate.
Share of active frames labelled voice, 0 to 1. Music with vocals genuinely sits in the middle. Null when nothing is active.
Energy left in the pauses after speech: the 60 to 420 ms tail after each phrase against the phrase itself. Noise OR reverb, and this number does not separate the two, so do not read it as a room verdict. Tested on 27 Sep 2026 against 24 measured room responses: it tracked the measured RT60 at Spearman 0.06 and a 1.71 s room scored below a 0.18 s booth, while it does rise with background noise. The field name is kept for compatibility with saved history and existing integrations. Null when no speech was found to read it from.
SNR measured per phrase and averaged, dB.
Spread of the per-phrase SNR, dB.
2 to 8 Hz share of the gap-envelope energy: speech rhythm where the target is silent.
Share of the movement in the pauses between 8 and 16 Hz, from pauses of at least 1.4 s. Flat noise already reads about 0.5.
Autocorrelation peak of the gap envelope at syllable lags.
Mean level of the gaps, dBFS.
Mains hum in the pauses, dB above the 30 to 600 Hz floor. Null when no 0.34 s window fits inside a pause.
50, 60, or null when the hum stays under 6 dB or was not measured.
The take opens mid-sound.
The take is cut off at the end.
Envelope level at the first frame, dBFS.
Envelope level at the last frame, dBFS.
What fills the speech pauses, read after the first 0.4 s of each: quiet, stationary (a machine), program (a second voice or music), unsteady (moves without cadence or pitch). Null under one second of pause.
0 to 1: how strongly the pauses carry a program, from level movement times speech cadence or a moving pitch. Above 0.5 the label reads program.
0 to 1: how still the pause floor stands in level and in spectral shape. Above 0.5 the label reads stationary.
Share of the pause power below 500 Hz.
Share of the pause power between 300 and 3400 Hz.
Standard deviation, dB, of the quieter half of the pause frames (20 ms each).
Share of 40 ms pause frames with a clear, moving pitch between 70 and 400 Hz: a second voice or music. A fixed pitch is reported as sceneGapToneHz instead.
One steady tone filling the pauses (a fan, a transformer), Hz, or null.
0 to 1: how much the spectral shape of the pause floor changes between 0.4 s windows. Under 0.06 a machine, above 0.2 music or speech.
Mean speech level minus the mean pause floor level, dB.
A proxy, not an STI: the weaker of the worst-tenth per-phrase SNR and speech over background (3 dB reads 0, 18 dB reads 1), reduced for clipping. Null under two measurable phrases.
The intelligibility proxy as a number, 0 to 1.
Tenth percentile of the per-phrase SNR, dB: what the weakest phrases measure against the noise beside them.
Level envelope, at most 2000 points. Longer takes are reduced by keeping the PEAK per bucket, so a short clip or a hot moment survives; seriesIntervalSec says how much time one point covers.
Speech present per envelope point, same length and interval as rmsEnvelope. A bucket reads true when any of its points did.
Seconds covered by one point of rmsEnvelope and voicedMask, so the series still maps onto the timeline after reduction.
Speech segments the engine found, before any cap.
Segments in this response. Lower than totalSegments when truncated.
True when more than 500 segments were found and only the longest 500 are returned, with segmentalSnrPerSegmentDb kept in step.
Example response
{
"measureStatus": {
"legend": "https://audiolab.tools/docs/start/read-a-response#the-five-statuses"
}
}Changes
No recorded changes to this operation across all 1 revision of this API.