60db Logo
  • Guides

8 kHz phone audio and wideband ASR

8 kHz phone audio needs honest format and bandwidth boundaries. Run PCM checks and design paired wideband ASR evaluation.

Editorial date
Reading time
24 min
Captured audio bandwidth remains separate from a wider endpoint sample grid

TL;DR: Resampling 8 kHz phone audio can satisfy an ASR input contract, but it cannot recover acoustic information removed before capture. Keep encoding, sample rate, captured bandwidth, and RTP clock separate, then compare paired speech conditions with a transformation manifest and explicit task outcomes.


A recognizer accepts a file labeled 16 kHz, yet identifiers remain wrong. The conversion completed without an exception, so the application team starts adjusting language prompts. The missing diagnostic is whether the input contains genuine wideband speech or narrowband speech represented on a denser sample grid.

Begin by reading the actual bytes and their provenance. The SIP audio troubleshooting guide provides the transport checks that should precede a recognizer comparison. A file extension, an endpoint setting, or a successful upload is insufficient evidence about captured audio.

This guide gives you a bounded PCM validation artifact and a paired evaluation design. It does not report recognition results, reconstruct missing frequencies, or establish a carrier benchmark. Every numerical fixture below is synthetic unless it describes a named format standard.

The current Google Speech-to-Text best practices recommend preserving a suitable native capture rate and accurately describing input. That guidance belongs to that service; inspect the exact model and endpoint contract before deciding that every input needs conversion.

Table of contents

  1. Separate four audio dimensions
  2. Find the real capture boundary
  3. Choose a conversion contract
  4. Run the PCM boundary checker
  5. Build paired speech conditions
  6. Measure recognition and task outcomes
  7. Diagnose failures before tuning prompts
  8. Decide what to deploy
  9. Keep conversion evidence replayable
  10. Review the paired result without hiding coverage
  11. Frequently asked questions
  12. Validate one source path first

Separate four audio dimensions

Sample rate counts samples per second in a decoded signal. Captured bandwidth describes which acoustic frequencies survived microphones, filters, codecs, and the source path. Encoding describes how sample information becomes bytes. The RTP clock supplies timestamp units for a negotiated payload. Each answers a different question.

A synthetic one-second mono PCM16 recording at 8,000 samples per second contains 8,000 samples and 16,000 sample bytes, excluding any container header. A genuine conversion to 16,000 samples per second should preserve the intended one-second duration while producing the corresponding output frame count. Merely rewriting the header changes the interpretation of the existing samples.

That arithmetic is useful for catching a rate-label defect. It says nothing about whether the recording contains the consonants, names, or background conditions your task requires. Audio can pass every structural check and still contain clipped speech, the wrong microphone, overlapping voices, or a language the endpoint is not configured to recognize.

RFC 3551 defines the public RTP audio profile, including PCMU and PCMA mappings and an important G.722 exception. G.722 audio uses a 16 kHz sampling rate while its RTP timestamp clock is 8 kHz. Treating every payload described with an 8 kHz RTP clock as narrowband sampled audio would therefore misclassify a valid negotiated format.

Keep a codec descriptor rather than a bare integer called rate. It should distinguish payload name, RTP clock, decoded sample rate, channel count, and the source of that mapping. The mapping comes from the actual negotiated context; a packet payload-type value without that context is incomplete evidence.

The distinction becomes practical when an application crosses WebRTC, WebSocket, and SIP boundaries. A WebSocket field may describe raw audio bytes, a WAV header describes a container, and an SDP attribute describes a negotiated RTP payload. None can safely be substituted for the others without an adapter that understands the relevant format.

Four audio dimensions with the G.722 sampling and RTP-clock exception

A denser sample grid does not imply a wider captured band. Interpolation creates values between existing samples according to a reconstruction method. It does not provide independent observations of speech energy that a previous capture or filtering stage removed. A recognizer can still behave differently after a required conversion, but that is an empirical model-input result rather than recovered source evidence.

Find the real capture boundary

Start the investigation at the earliest accessible recording boundary. Record whether that boundary is microphone capture, decoded provider media, an application buffer, or a saved file. Describe which upstream stages are outside your visibility. A statement that audio is native is useful only when native has a named reference point.

For each fixture, retain a source checksum, recording permission, declared format, verified format, transformation chain, and label version. The checksum makes accidental replacement visible. It does not prove consent or audio quality; those remain separate records with their own authority and retention rules.

Do not turn an evaluation corpus into a copy of customer calls. Use consented material with a documented purpose, access boundary, and deletion process. The regional speech dataset guide develops that collection process. Synthetic tones are suitable for structural checks, while actual speech evaluation requires appropriately collected speech.

Check the source before it reaches ASR. Decode a short known segment with an independent reader, inspect channels, compare declared duration with sample count, and listen through an approved local workflow when permission allows. Listening can expose obvious defects, but a plausible sounding sample does not establish every byte-level property.

A stereo file can contain different speakers, duplicated channels, or phase relationships that a careless mixdown changes. Decide which channel operation your application needs. Document the choice rather than silently accepting whichever default a library provides. The same caution applies to gain adjustment and silence trimming.

The audio boundary guide explains why an otherwise valid signal can lose useful phonetic evidence at segment boundaries. If a decoder drops a partial final frame or a segmenter cuts the first consonant, increasing the output sample rate does not repair that loss.

Preserve source and transformed files as separate artifacts. Never overwrite the source while experimenting with endpoint settings. A source manifest should make it possible to rebuild a derived condition without guessing which intermediate file someone last edited. Reproducibility depends on those identities as much as on the converter command.

When you cannot access the earliest recording, state that limit directly. You can validate the application-visible representation and compare its downstream behavior. You cannot then attribute a recognition difference to the microphone, carrier filter, or an earlier codec stage without additional evidence from those boundaries.

Choose a conversion contract

A conversion contract names what enters, what exits, and which properties should remain invariant. For this guide the narrow local contract is mono, signed PCM16, little-endian samples, a positive declared sample rate, and duration calculated from complete frames. It intentionally excludes raw G.711 bytes and compressed WAV formats.

The current Google audio encoding documentation distinguishes encoding from sample-rate configuration. Use that distinction when reading any provider interface. A declaration that says LINEAR16 does not decode a PCMU payload automatically, and a sample-rate setting cannot change the meaning of the incoming bytes by itself.

Decode the source law or codec first. Then perform a real rate conversion only if the destination contract requires it or a controlled experiment justifies it. When testing PCMU and PCMA inputs, use the public companding fixture guide to resolve byte interpretation before comparing recognizers.

Use a maintained converter with a recorded version and documented filtering behavior. The FFmpeg resampler documentation describes rate-conversion and filter options. This article does not publish an untested command as a universal recipe; the executable artifact below validates metadata and accounting rather than pretending a short interpolator is a production resampler.

Conversion chain preserving source checksum and transform version

A transform manifest should contain source identity, converter version, requested output contract, actual output metadata, and validation disposition. If a tool selects a different channel layout or sample format from the one requested, preserve the actual result and reject that condition for the intended comparison. Do not repair the manifest to match expectations.

Define tolerances before seeing model outcomes. Some conversions require a documented boundary policy for filter delay or output frame rounding. If you allow a frame-count tolerance, express it in frames and derive the resulting duration bound. Avoid using a broad percentage tolerance that conceals a header-only rate error.

The checker below uses exact rational duration equality for deliberately exact synthetic fixtures. That is a smaller promise than validating every real converter. A production evaluation adapter must either provide exact counts for its supported transformations or record a separate, justified tolerance rule and test its boundary cases.

Use the chunk-size accounting guide when transformed files become streaming chunks. Whole-file duration correctness does not guarantee that each chunk carries complete frames, that chunk timestamps are accurate, or that buffering delay remains acceptable for a conversation.

Run the PCM boundary checker

The complete Python example runs on Python 3.11 and newer using the standard library. It constructs synthetic WAV bytes in memory, verifies the supported PCM boundary, takes an immutable owned metadata snapshot, and compares exact duration. It does not resample audio, inspect acoustic bandwidth, or call an ASR endpoint.

The Python wave documentation defines the container reader used here. The program relies only on integer PCM operations available in the stated runtime range. Newer documentation can describe additional capabilities; that does not make those capabilities available to an older interpreter.

Python struct provides explicit little-endian sample packing. A WAV reader validates its supported container, while the separate raw validator catches partial PCM frames. A raw payload and a WAV file are different input types, so the example gives them separate entry points. Reading one frame beyond the declared complete-frame count exposes a trailing partial WAV data frame, which the container reader otherwise hides by flooring its frame count.

from dataclasses import dataclass
from fractions import Fraction
from hashlib import sha256
from io import BytesIO
import struct
import wave

@dataclass(frozen=True)
class PCM:
    digest: str
    rate: int
    frames: int
    channels: int = 1
    width: int = 2

    @property
    def duration(self):
        return Fraction(self.frames, self.rate)


def inspect_raw(payload, rate, channels=1, width=2):
    if not isinstance(payload, (bytes, bytearray, memoryview)):
        raise ValueError("byte payload required")
    owned = bytes(payload)
    if type(rate) is not int or rate <= 0:
        raise ValueError("positive integer rate required")
    if channels != 1 or width != 2:
        raise ValueError("only mono PCM16 supported")
    if not owned or len(owned) % (channels * width):
        raise ValueError("empty or partial PCM frame")
    return PCM(sha256(owned).hexdigest(), rate, len(owned) // 2)


def inspect_wav(blob):
    owned = bytes(blob)
    try:
        with wave.open(BytesIO(owned), "rb") as reader:
            if reader.getcomptype() != "NONE":
                raise ValueError("integer PCM required")
            n = reader.getnframes()
            raw = reader.readframes(n + 1)
            if len(raw) != n * reader.getnchannels() * reader.getsampwidth():
                raise ValueError("truncated frames")
            return inspect_raw(raw, reader.getframerate(),
                               reader.getnchannels(), reader.getsampwidth())
    except (wave.Error, EOFError) as exc:
        raise ValueError("unsupported WAV") from exc


def same_duration(source, output):
    if source.duration != output.duration:
        raise ValueError("duration mismatch")
    return True


def wav_bytes(raw, rate):
    target = BytesIO()
    with wave.open(target, "wb") as writer:
        writer.setnchannels(1)
        writer.setsampwidth(2)
        writer.setframerate(rate)
        writer.writeframes(raw)
    return target.getvalue()


def expect_error(fn):
    try:
        fn()
    except ValueError:
        return
    raise AssertionError("expected rejection")


def fixtures():
    # Synthetic example: 8 samples, no recognition result.
    raw = struct.pack("<8h", 0, 1, -1, 100, -100, 200, -200, 0)
    source = inspect_wav(wav_bytes(raw, 8000))
    relabeled = inspect_wav(wav_bytes(raw, 16000))
    expect_error(lambda: same_duration(source, relabeled))
    # A duration-shaped fixture, NOT an actual resampling algorithm.
    shaped = inspect_raw(bytes(32), 16000)
    assert same_duration(source, shaped)
    mutable = bytearray(raw)
    snapshot = inspect_raw(mutable, 8000)
    mutable[0] = 99
    assert snapshot.digest == source.digest
    from dataclasses import FrozenInstanceError
    try:
        snapshot.rate = 1
    except FrozenInstanceError:
        pass
    else:
        raise AssertionError("mutable snapshot")
    for rate in (0, -1, True, 8000.5):
        expect_error(lambda rate=rate: inspect_raw(raw, rate))
    expect_error(lambda: inspect_raw(b"", 8000))
    expect_error(lambda: inspect_raw(b"\x00", 8000))
    expect_error(lambda: inspect_raw(raw, 8000, channels=2))
    expect_error(lambda: inspect_raw(raw, 8000, width=1))
    expect_error(lambda: inspect_wav(b"not a WAV"))
    expect_error(lambda: inspect_wav(wav_bytes(raw, 8000)[:-2]))
    for size in (3, 17):
        expect_error(lambda size=size: inspect_wav(wav_bytes(bytes(size), 8000)))
    # A payload descriptor, not a sample-rate inference from RTP clock.
    g722 = {"payload": "G722", "rtp_clock": 8000, "sample_rate": 16000}
    assert g722["rtp_clock"] != g722["sample_rate"]
    print("synthetic PCM boundary fixtures passed")

if __name__ == "__main__":
    fixtures()

Save the entire fence as a file and run it with your supported interpreter. A successful run establishes the local assertions represented by the fixtures. It does not prove that an arbitrary byte sequence is acoustically valid speech, that its declared rate is truthful, or that a real converter preserves quality.

The duration-shaped fixture deliberately uses zero bytes rather than claiming to perform interpolation. It proves the accounting comparison accepts a correctly sized output representation. A genuine transformation test must invoke the chosen converter, inspect its actual output, and retain the transformation evidence alongside the result.

Validation table separating real conversion from a header-only relabel

A corrupted sample-rate header can still be internally self-consistent. Without a trusted source duration or upstream contract, a WAV parser cannot infer that the rate label lies. That limitation is why provenance is part of the evaluation design and why the checker receives separate source and output snapshots.

Build paired speech conditions

Use the same consented utterances to construct the conditions you want to compare. A useful design distinguishes an available native wideband source, a deliberately bandwidth-limited narrowband derivative, and a resampled representation of that narrowband derivative. The last condition changes representation while retaining the source limitation.

Do not compare unrelated wideband and phone-call corpora and attribute every difference to sample rate. Speakers, microphones, languages, tasks, labels, noise, and speaking styles can differ simultaneously. The multilingual benchmark method explains how cohort and task definitions shape what a comparison can support.

Record the filter and conversion chain used to construct each derivative. A downsample operation needs appropriate anti-alias filtering; a mislabeled or poorly filtered derivative introduces a separate defect. If the chain changes, treat the resulting condition as a new version rather than merging its results into the old cohort.

Keep an untouched source branch for rebuilding. The working manifest should identify which transformed artifact came from which source artifact and which transcript label. If the transcript changes after review, rerun the affected comparison or explicitly version the old outcome. Combining old outcomes with new labels breaks the meaning of a paired test.

Three paired input conditions sharing utterances and task criteria

A task corpus should include the fields that make errors expensive for the application. Names, dates, codes, and short confirmations can have different acceptance criteria from ordinary dictation. Use the confirmation prosody guide when playback wording influences the caller's ability to correct a recognized value.

Avoid repeatedly tuning on the same evaluation material. Split development fixtures from a held-out consented set, preserve source identities, and record which endpoint settings were selected before the held-out run. A successful setting on the development set is a candidate, not an unbiased estimate of deployment behavior.

Handle missing pairs explicitly. If one condition fails conversion or the ASR request times out, retain the fixture and failure disposition. Reporting only utterances that produced transcripts in every condition changes the tested population. You may report a paired transcript subset, but its coverage must accompany the result.

Use the voice regression testing guide to turn the manifest into a repeatable suite. Stable fixture identity lets you separate a conversion regression from a label revision, a model change, or an application policy change. Those causes deserve different recovery actions.

Measure recognition and task outcomes

Choose outcome definitions before running requests. Transcript error, exact critical-field match, confirmed field value, correction attempts, and completed task are different observations. A recognizer can improve aggregate transcription while still failing the identifiers your workflow must capture reliably.

For each request, retain the source condition, endpoint model identifier when available, input declaration, language policy, request disposition, transcript label version, and scoring version. Preserve failure outcomes even when there is no transcript to score. A blank transcript is not interchangeable with a rejected request or an expired local wait.

The voice outcome metrics guide provides the denominator discipline for task reporting. Describe both the population offered to the endpoint and the subset eligible for each transcript metric. A score computed on successful transcripts should never silently represent all scheduled fixtures.

Timing needs its own boundary. Measure conversion duration separately from request time and from user-perceived response behavior. The voice latency benchmark guide distinguishes named timing endpoints. If you report a faster ASR response after a conversion, state whether conversion cost is included.

The following criteria table uses ✓ to mean that a method can establish the stated local property under its declared inputs. A ✗ means it cannot establish that property by itself. Neither mark is a claim about a particular provider's recognition quality.

Method Detect partial PCM frames Check paired duration Establish captured bandwidth Establish task success
Raw PCM structural checker ✓ ✓ with trusted source ✗ ✗
Header metadata alone ✗ for arbitrary raw input ✗ without source ✗ ✗
Versioned transformation manifest ✓ with validation ✓ with output evidence ✓ only with source/filter evidence ✗
Consented task evaluation ✗ without format checks ✗ without accounting ✗ without source evidence ✓ within declared task criteria

Do not collapse all these outcomes into one audio quality number. If a conversion reduces structural failures but adds unacceptable delay, that is a real trade-off. If task outcomes remain uncertain because the corpus is too narrow, keep that uncertainty visible rather than assigning a winner.

The observability guide helps structure the trace that connects a request to its condition and disposition. Record only the evidence needed for diagnosis. Raw recordings and transcripts require separate access and retention controls; a trace identifier does not justify copying sensitive content into routine logs.

Synthetic tone checks and consented speech evaluation establish different properties

Diagnose failures before tuning prompts

When results look implausible, inspect format failures before interpreting model behavior. Compare actual channel count, decoded sample count, sample width, and declared rate with the endpoint contract. Then inspect transformation provenance. An endpoint accepting bytes does not guarantee that it interpreted them as intended.

Two public developer questions illustrate recurring boundary confusion. One asks why converting 8 kHz audio to 16 kHz can still sound poor; another asks why a mel-filter configuration conflicts with its sample rate. These are real diagnostic questions, not evidence for a converter recipe, a recognition result, or current provider behavior.

A wrong-law decode can preserve duration while damaging reconstructed amplitudes. A header relabel can preserve byte length while changing interpreted duration. A stereo mixdown can preserve duration and nominal bandwidth while suppressing a useful speaker. These cases require different fixtures because a single duration assertion cannot identify them all.

Separate packet damage from bandwidth limits. The burst versus random packet-loss guide addresses missing-media patterns that a whole-file metadata check cannot reveal. If a recording already contains concealment or discontinuities, document that condition rather than calling it clean narrowband speech.

Language configuration is another independent variable. The Hindi-English language-hint guide explains why language policy belongs in the experiment record. Changing a language hint at the same time as conversion prevents a clean attribution to the audio transformation.

Check output trimming and padding. A converter can introduce boundary behavior that affects an early consonant or a short response. Compare known synthetic impulses or edges for structural diagnosis, then evaluate appropriately consented speech for practical recognition impact. A tone fixture cannot stand in for the latter assessment.

For browser capture, device processing can alter the signal before your application receives it. The mobile browser latency guide describes device-path limits that a server test omits. Keep those conditions separate from a server-side file conversion comparison.

When a change appears helpful, reproduce it from the immutable source branch. Rebuilding catches accidental gain changes, stale intermediate files, and configuration drift. Preserve the old condition until the new one has passed the same structural checks and task criteria; a renamed file is not a reproducible experiment.

Decide what to deploy

Prefer the simplest input path that satisfies the actual endpoint contract and passes your declared evaluation criteria. If the endpoint accepts the verified native representation and the task results are acceptable, an extra conversion stage needs a demonstrated reason. Every stage adds configuration, cost, and another place for provenance to become ambiguous.

When conversion is necessary, make its rejection behavior explicit. Unsupported channels, unexpected encodings, truncated frames, and a missing source contract should produce distinguishable operational dispositions. A silent fallback to guessed metadata can make an apparently healthy pipeline fail only on the most important short utterances.

Deploy configuration and transform versions together. A model or endpoint change can alter which input declarations are valid. Keep an observable association between the deployed model setting and the transform that prepared its requests, then make rollback restore a coherent pair rather than just one side.

The streaming voice consistency guide offers a related configuration-control principle: compare stable, named conditions instead of mixing versions inside one aggregate. Although that guide concerns output speech, the same experiment discipline applies to input preparation.

For an application using 60db Agent, attach this manifest at the observable integration boundary. Evaluate the actual documented audio interface available to your deployment. This guide does not imply a private codec path, a particular recognition architecture, or a universal benefit from converting every phone call to one sample rate.

Write down the release decision in terms a future engineer can retest: supported source contract, required transform, rejected inputs, retained evidence, task criteria, and rollback condition. That record makes the next format incident easier to diagnose without treating an old endpoint setting as a permanent acoustic truth.

Keep conversion evidence replayable

A conversion job should have an identity independent of its output filename. Associate that identity with an immutable source checksum, a complete transform specification, the converter version, and the requested output contract. If the output already exists, compare those inputs before deciding that the file is reusable. A plausible filename is a weak cache key.

Separate a successful process exit from successful validation. A process can exit successfully after producing a different format than your integration expects, and an interrupted filesystem write can leave a previous output at the requested path. Create a new output artifact, validate it, and only then make it eligible for evaluation. Keep failed attempts visible in the job record.

The source checksum and output checksum answer different questions. Source identity tells you what entered the transformation. Output identity tells you which actual bytes were inspected and submitted. Retain both when an endpoint comparison depends on exact inputs. A manifest containing only the source checksum cannot distinguish two converter versions that produce different bytes.

Do not overwrite a failed output to make the manifest look clean. Store its disposition, then create a new attempt with a new transform identity if you change the configuration. That history helps explain why one batch contains fewer eligible requests without turning a missing artifact into an unexplained scoring exclusion.

A streaming adapter also needs ownership. If a call changes format during an active session, the adapter must decide which decoder owns each payload and which buffered bytes belong to the previous configuration. Do not feed old bytes into a new decoder merely because the current metadata says a different law or rate. Flush and transition behavior belongs in the adapter's tested contract.

Record the boundary of each successful assertion. A WAV inspection can establish the reader's interpretation of supported header fields and complete sample bytes. It cannot establish that an upstream device used those settings. A request log can establish which bytes the client attempted to submit. It cannot establish which acoustic evidence reached the recognizer after every remote processing stage.

For a small offline corpus, a simple immutable manifest file can be sufficient. You do not need a new orchestration service to preserve a few source identities and output contracts. Use the existing evaluation runner, keep its data model small, and make the assertions fail loudly when required fields or expected outputs are missing.

Version the validation policy too. If one run permits a final partial frame and another rejects it, the successful populations differ even with the same converter and source set. A policy change deserves a distinct condition so later readers can reconstruct why a fixture was included or excluded.

Review the paired result without hiding coverage

Begin a result review with the offered fixture population. State which source identities were eligible, which transformations completed, which endpoint requests were attempted, and which outcomes were available for scoring. Each stage can remove evidence for a different reason. Reporting only the final transcript count conceals those distinctions.

For a synthetic illustration, suppose a local test plan contains two fixture identities and one condition fails validation for one identity. This is an accounting example, not a measured recognition result. The condition has one eligible request and one explicit validation failure; it does not have two successful requests with one conveniently omitted transcript.

When comparing transcript scores, keep the matched subset identifiable. If both conditions produce a transcript for a fixture, that pair supports a direct transcript comparison under the declared label version. A fixture with a timeout in one condition still matters to reliability reporting even when it cannot contribute to a paired transcript difference.

Define critical-field normalization narrowly. Trimming allowed surrounding whitespace may be reasonable for one field, while deleting all punctuation or converting arbitrary words to digits can conceal a material error in another. Preserve the original recognized value under its privacy boundary and record the exact normalization policy used to derive a scored field.

Use field-specific criteria for dates and identifiers. An ambiguous spoken date can require clarification even if a transcript resembles the reference text. A recognized identifier with the wrong leading zero can be unusable despite a low aggregate edit count. The evaluation should reflect the action the application is allowed to take from that value.

Keep correction behavior in the task protocol. If the application reads back a value and the caller corrects it, the initial transcript outcome and the eventual confirmed field outcome are both useful. They answer different questions about recognition and recovery. Avoid counting a successful correction as proof that the original recognizer output was correct.

Review errors by source condition without inventing causal explanations. A missing final syllable could arise from segmentation, packet damage, an upstream recording defect, or model behavior. Use retained format and boundary evidence to narrow the possibilities. An explanation becomes stronger when a targeted fixture reproduces the suspected failure under controlled inputs.

Record the deployment decision separately from the raw result. You may accept a conversion path because it meets a required endpoint contract and the task criteria, even when another condition has a slightly different transcript score. The decision should identify the operational constraints, missing evidence, and conditions that require reevaluation.

Schedule reevaluation when the actual contract changes. A new capture device, codec mapping, converter version, endpoint model, or language policy can invalidate the previous comparison. Cosmetic changes to a report do not. Tie the rerun trigger to a material input or scoring change so the evaluation remains useful rather than becoming an unmaintained ritual.


Frequently asked questions

Can I turn 8 kHz audio into true wideband speech?

A rate converter can produce a valid higher-rate representation, but it cannot independently observe frequencies removed before capture. Evaluate any recognition change as behavior of the selected model and input path. Do not describe a denser sample grid as recovered source information.

Should every ASR request be resampled to 16 kHz?

Read the exact endpoint contract first. Some interfaces accept a suitable native rate, while others require a particular representation. A universal conversion rule can add avoidable work or hide a mislabeled source. Preserve the actual source declaration and validate the output you send.

Is an 8 kHz RTP clock always narrowband audio?

No. RFC 3551 specifies the G.722 exception: its audio sampling rate is 16 kHz while its RTP clock is 8 kHz. Keep codec mapping and decoded sampling rate separate. A bare RTP clock integer is insufficient to classify captured bandwidth.

Why does changing only the WAV header alter playback?

The header tells a reader how quickly to interpret the existing samples. If the sample count remains unchanged while the rate doubles, the declared duration halves. That operation changes interpretation rather than performing a real rate conversion. Compare source and output duration under a trusted source contract.

Does a successful upload prove the format is correct?

It proves only that the interface accepted that request at its own boundary. The bytes can still be mislabeled, badly decoded, clipped, or unsuitable for the task. Inspect local structure and preserve endpoint dispositions separately from recognition and task outcomes.

Can the checker identify raw PCMU bytes automatically?

No. It intentionally validates a declared raw PCM16 contract and does not infer codecs from arbitrary byte content. Resolve the container or negotiated payload mapping first. A byte sequence with even length can still represent the wrong format.

Why keep the source checksum?

It binds a derived artifact to a specific source byte sequence and exposes accidental source replacement. It does not establish consent, truthfulness of metadata, or acoustic quality. Keep those records separately and version the transformation and labels as well as the source.

Does correct duration prove good conversion quality?

No. Duration correctness detects a useful class of accounting mistakes, but wrong-law decoding, filtering defects, and amplitude clipping can retain duration. Add independent format fixtures and consented speech evaluation. Treat each check as evidence for a named property rather than a universal quality certificate.

Can synthetic tones replace a speech corpus?

Tones help inspect conversion, clipping, aliasing, and boundary behavior under controlled inputs. They do not represent names, accents, conversational noise, or task corrections. Use appropriately consented speech for recognition evaluation, with separate development and held-out material.

Why compare paired utterances?

Pairing controls the underlying utterance while the declared transformation changes. Unrelated corpora can differ in speakers, labels, tasks, and devices at the same time. Pairing reduces that ambiguity, although it still requires careful versioning and honest treatment of missing outcomes.

What should happen to a failed conversion?

Retain its fixture identity and explicit failure disposition. Do not remove it from the offered population just because there is no transcript. You may report a successful-transcript subset, but its coverage and exclusions must accompany any score derived from it.

Should I normalize volume before recognition?

Treat normalization as a separate transformation with its own version and evaluation condition. It can change clipping and noise relationships, so combining it silently with resampling obscures attribution. Prefer a controlled comparison that records actual output peaks and the supported input contract.

How should stereo input be handled?

Choose a channel policy based on the source and endpoint requirements. Selecting one channel, duplicating channels, and mixing them have different consequences. The small checker rejects stereo rather than guessing. A broader adapter needs explicit channel fixtures and a documented policy.

Why use rational duration calculations?

The synthetic checker compares sample-count fractions exactly and avoids rounding a mismatch away with floating-point formatting. Real converter delay or rounding policies may need a justified tolerance. Such a tolerance should be explicit, versioned, and tested at its boundary.

Does lower word error rate establish task success?

No. A transcript metric and a workflow outcome have different denominators and acceptance rules. A critical identifier can remain wrong even when aggregate transcription improves. Evaluate confirmed field values and completed authorized tasks separately from transcript quality.

Can I mix model versions in one result table?

Only if the table explicitly reports that mixed condition and supports the intended question. For a controlled conversion comparison, keep endpoint and model configuration stable or stratify the outcomes. Otherwise the apparent conversion effect can include an unrelated model change.

What if the earliest capture boundary is unavailable?

Validate the representation you can observe and state which upstream stages are unknown. You can compare downstream behavior of that representation. You cannot confidently attribute a difference to a specific microphone, filter, or carrier stage without evidence from that boundary.

Is audioop needed for these checks?

No. The example uses wave, struct, fractions, and immutable dataclasses. Python removed audioop in 3.13 after earlier deprecation. A new guide should avoid making its core validation depend on that removed module or silently restricting readers to an obsolete runtime.

What belongs in a deployment rollback condition?

Name the source contract, transform version, endpoint setting, and task criterion that trigger rollback. Include structural rejection rates and missing outcomes where relevant. Restore a coherent configuration pair so the previous decoder and endpoint declarations remain compatible.

What is the first useful experiment?

Take one consented source path, verify its actual format, and rebuild one derived condition from an immutable source. Run the structural fixtures before sending paired requests. Expand the corpus only after source identity, output accounting, and outcome recording are repeatable.

Validate one source path first

Start with a source you can describe honestly. Establish its encoding, decoded rate, channels, frame count, and provenance. Then validate the exact representation required by the selected endpoint, keeping the original and transformed artifacts separate.

Use the local checker to catch empty input, partial frames, unsupported contracts, truncated WAV data, and duration mismatches. Add your real converter as a separately versioned adapter. Its output needs its own fixtures and cannot inherit quality claims from the accounting example.

Finally, run a paired consented speech evaluation with explicit transcript, critical-field, and task outcomes. Preserve failures and missing pairs. The useful release decision is a repeatable input contract that meets the application criteria, with clear evidence about what was observed and what remains unknown.