Hearing and listening¶
Hearing and listening are different things. Hearing perceives the signal: is there sound, is it loud enough, is it clipped, are both channels alive. Listening attends to meaning: were the right words said, could someone follow them, and did the message land.
Audel does both:
| Hearing | Listening | |
|---|---|---|
| Entry point | check |
listen (runs check first) |
| Question | Is the signal healthy and on spec? | Was the right thing said, and can a listener follow it? |
| Grounding | ffmpeg BS.1770 meters, signal statistics | word-timed transcript (local faster-whisper) |
| Network | never | never, unless you add understand |
What listen checks¶
Everything in this table is deterministic and offline. It needs the [asr] extra.
detail.check |
Finds | Severity |
|---|---|---|
script_omission |
script words that were never read, time-grounded to the gap | error for 3 or more words, else warning |
script_substitution |
words read differently from the script | error for 5 or more words, else warning |
script_insertion |
unscripted runs of 3 or more words (ad-libs) | warning |
script_adherence |
overall word error rate above 25 % | error |
required_term |
wording that must be said and was not, such as a legal line or sponsor read | error |
forbidden_term |
wording that must not be said, with a span for each occurrence | error |
speech_rate |
overall pace outside 110 to 190 words per minute | warning |
rushed_passage |
10-second stretches well above the pace ceiling | warning |
long_pause |
3 s or more of dead air inside the read | warning |
low_intelligibility |
a second or more the recogniser itself could barely make out | warning, low confidence |
track_language |
an audio track in the wrong language | error |
caption_text |
a cue that says something different from the audio | error or warning |
caption_offset |
captions consistently early or late | error |
caption_timing |
a single cue off the speech | warning |
caption_reading_rate |
a cue faster than 20 characters per second | warning |
caption_missing |
3 s or more of speech with no caption | warning |
caption_format |
zero-length or overlapping cues | warning |
Recognition is not ground truth. Audel treats a run of missing script words as the strong
signal and a single changed word as a weak one. Use a larger whisper model (AUDEL_ASR_MODEL=small
or large-v3, with AUDEL_ASR_DEVICE=cuda on a GPU host) when you need fewer recognition errors.
Understanding (opt-in)¶
With understand=True, a model also answers what a deterministic pass cannot:
- Key messages. Did each intended message come across? Each one becomes a
Conformanceclaim. A miss is a warning, or an error if the message has amust:prefix. - Takeaway. The one sentence an ordinary listener would leave with.
- Delivery. An audio-capable model hears excerpts from the beginning, middle and end, and labels
delivery, pace and intelligibility. When the brief names a
tone, a mismatch is reported.
Every model finding is advisory, marked source: audio_llm with medium or low confidence. The
transcript is passed as untrusted, delimited data, and the model is told never to follow
instructions inside it.
Example¶
This is real output for a short news read. The run used the approved script, an SRT file, one required line, two key messages and an expected calm tone. Understanding ran on an on-prem model (see On-prem inference).
audel listen read.wav --script script.txt --captions caps.srt \
--require "terms and conditions apply" \
--understand --key-message "must: heavy rain is coming tonight" \
--key-message "the bridge on the A1 is closed" --tone calm
FAIL 10 issue(s) — 28 words at 197 wpm, script adherence 74%, 3 caption cues
• [loudness/warning] [0–10337ms] integrated loudness (programme) -20.2 LUFS is 4.2 LU quieter than the preset.podcast target (-16 ±2 LU)
• [other/warning] [0–9860ms] speech rate 197 words/min is rushed (comfortable range 110-190)
• [transcript_mismatch/warning] [1600–2180ms] script says "news at six", heard "new matrix"
• [transcript_mismatch/error] [5200–5480ms] script line not heard: "with flooding possible near the river"
• [transcript_mismatch/error] [0–10337ms] read departs from the script: 74% adherence (word error rate 26%)
• [other/warning] [2600–3200ms] cue 2 reads at 132 characters/s (limit 20): too fast to read
• [transcript_mismatch/error] [2600–3200ms] cue 2 says "Heavy rain will spread across the north tonight and into tomorrow morning across all regions." but the audio there says "heavy rain will"
• [transcript_mismatch/error] [6000–9000ms] cue 3 says "Sport is next." but the audio there says "drivers are urged to take care on the roads terms and conditions"
• [intent_mismatch/warning] [0–10337ms] key message not conveyed: the bridge on the A1 is closed (The transcript does not mention the A1 bridge.)
• [intent_mismatch/warning] [0–9860ms] delivery heard as urgent; the brief asks for calm
takeaway: Heavy rain is expected across the North tonight, and drivers are advised to be cautious.
heard [0–9860ms]: urgent, pace normal, clear
[must] satisfied: heavy rain is coming tonight
[should] violated: the bridge on the A1 is closed
The "new matrix" substitution is a recognition error on robotic synthesized speech. Audel graded it as a warning, not an error, for exactly that reason.
Python¶
from audel import listen
report = await listen(
"promo.wav",
spec="ebu_r128_s1",
script=open("promo_script.txt").read(),
required=["terms and conditions apply"],
forbidden=["acme"],
captions=open("promo.srt").read(),
languages={1: "es"}, # track 1 must be Spanish
understand=True, key_messages=["the offer ends Friday"], tone="warm",
)
print(report.verdict, report.listening.wpm, report.listening.script_adherence)
report.listening holds the measurements behind the findings. It has the language, word count,
words per minute, longest pause, mean word confidence, script adherence and WER, term hits,
caption statistics, per-track languages, the takeaway and the delivery readings.
REST and MCP¶
POST /listen takes the media file plus form fields: script, captions (SRT or WebVTT text),
repeatable require, forbid, language (TRACK=CODE) and key_message, and also tone,
spec and content. Understanding over REST is off unless the operator sets
AUDEL_REST_ALLOW_UNDERSTAND=true, and the backend allowlist still applies.
The MCP tool listen_audio takes script and caption text, never file paths, so an agent
cannot use it to read files on the host.