---
title: "Audio input and transcription pipeline"
url: https://recursiveai.org/onespeech/docs/audio-input/
description: "AudioFileSource is a synchronous pull decoder. It accepts seekable encoded streams or paths and returns interleaved float PCM at 16,000 Hz, preserving the…"
version: "1.0.0"
source: https://github.com/recursive-ai-oss/onespeech-csharp/blob/63002de486786163a0a7800a51811e76d511fae6/docs/audio-input.md
---

# Audio input and transcription pipeline

`AudioFileSource` is a synchronous pull decoder. It accepts seekable encoded streams or paths and returns interleaved float PCM at 16,000 Hz, preserving the original channels. Supported formats are those registered by OneAudio: WAV, MP3, FLAC, Ogg Vorbis/Opus, AAC-LC in M4A/3GP/ADTS, and AMR-NB/WB. Decoding and polyphase resampling keep bounded buffers; the whole recording is never loaded. Resampler latency is compensated by OneAudio, and its tail is flushed at EOF.

A removable internal adapter additionally handles RIFF/WAVE A-law (format tag 6) and μ-law (7), including their WAVE_FORMAT_EXTENSIBLE subformats. It expands companded samples to signed linear 16-bit values and divides by 32768. It validates RIFF/chunk extents, channel count, sample rate, byte rate, block alignment, bit depth, extensible GUID and whole-frame data length. Channels are limited to 32 and G.711 rates to 192,000 Hz. Unknown codecs are delegated to OneAudio; `.au` is not supported. G.711 is specified by ITU-T Recommendation G.711 (11/1988), §3. No code from the associated software tools is used.

Unsupported or corrupt encoded input produces `UnsupportedAudioException`; filesystem/access errors and cancellation are not disguised as format errors. Streams opened with `leaveOpen` remain caller-owned. The asynchronous pipeline copies caller-owned encoded input with asynchronous I/O into a delete-on-close temporary file, then decodes it synchronously. This permits arbitrary nonseekable input and codecs needing random access with constant RAM, at the cost of temporary disk space proportional to encoded input size. Cancellation or a failure deletes the spool. No background inference or async-over-sync scheduling is used.

## Chunking

`VadChunker` accepts 16 kHz PCM blocks, and averages channels with equal weight for recognition. The original channels are still available from `AudioFileSource`; the chunker does not perform channel diarization. Input block storage may be reused after advancing enumeration; emitted chunks own their storage.

A recognition chunk defaults to at most 30 seconds. A family can supply its own maximum in the range 1 second through 1 hour. Each bounded analysis horizon includes one second of lookbehind and one second of lookahead. The detector resets for each horizon; this is not a promise of uninterrupted recurrent VAD equivalence across an entire file. Lookbehind preserves short trailing continuations across forced cuts. The last retained speech-region end within the maximum is preferred as the cut; uninterrupted speech is cut at the maximum. Detected regions within a chunk are merged **without deleting internal silence**. Leading/trailing silence outside retained speech is discarded. Onsets, padding and gaps retain their original audio-time coordinates.

PCM memory is bounded by the maximum chunk duration plus the fixed analysis context, independently of file length. Enumeration can discard each chunk after inference. `AudioChunk.Start` is its origin in the file; recognition times are relative to the chunk. Progress reports the consumed audio duration, including skipped silence, not wall time. Cancellation is checked per decoder block, per VAD frame and before each recognition chunk.

## Pipeline

`VadTranscriptionPipeline` borrows a `VoiceActivityDetector` and `SpeechRecognizer`. It offsets every non-null segment/word/turn timestamp by the chunk origin and preserves null timings. It does not synthesize segments or word timings. Text from nonempty chunk results is joined by one space; text within each result is unchanged. The first detected language, or the caller's explicit language, is used for subsequent chunks. Provenance includes the detector, recognizer, and additional contributing models, deduplicated by ID and revision. Without an optional diarizer, speaker assignments supplied by the recognizer are preserved. The additive diarizer hook, two-pass whole-file processing and embedding-memory bounds are described in [diarization](https://recursiveai.org/onespeech/docs/diarization/).

`Transcribe` accumulates a document, so its text and metadata necessarily grow with output size; only PCM processing is constant-memory. `TranscribeStream` yields final segments without accumulating a document. `Speech.Transcribe` and its stream-input async twin forward to this pipeline through an internal explicit recognizer resolver. Until model-loading integration supplies a recognizer, they fail with `FeatureUnavailableException` before opening input. Language detection uses the first detected speech chunk and refuses a non-null language hint rather than ignoring it. A silent recording cannot yield a language and raises `UnsupportedAudioException`.
