Skip to content

ondio.flac

ondio.flac

FLAC header parsing and soundfile-based reads.

Public surface (each mirrored URI-first in the dispatcher):

  • extract_flac_header — parse STREAMINFO fetching only header bytes;
  • read_flac — the whole stream or a [start_sec, end_sec] window, in memory: decoded PCM as a soundfile-style numpy array (default), or with decode=False the bytes of a standalone FLAC file;
  • download_flac — the same window semantics, written to a local .flac path (the counterpart of legacy soundhub_utils io.read_flac(src, dest, ...)).

Calls that need no decoding — read_flac(decode=False) or download_flac with no window — are plain byte copies and preserve the original file bytes exactly. Everything else decodes with soundfile (libsndfile, bundled in its wheel; nothing shells out). Windows are cut by sample index — [round(start_sec * sr), round(end_sec * sr)) — and a windowed FLAC result is a fresh encode: losslessly identical PCM, but not byte-identical to any slice of the source (new frame boundaries, new STREAMINFO, no original tags).

Damaged input raises OndioError. A window that reaches into a corrupt or truncated region raises; it never returns short or substitute audio. A whole-file decode of a truncated or unknown-length stream also raises.

What changed versus soundhub_utils:

  • the STREAMINFO bit arithmetic is fixed — legacy read bits_per_sample from the wrong bits (reporting e.g. 17 for a 16-bit file) and read the channel count from total-samples bits (reporting 1 for nearly any file);
  • backend-agnostic: every function takes (backend, uri) and works on any StorageBackend;
  • the four legacy entry points collapse to read_flac/download_flac, with the window optional and the fetch strategy overridable via use_range;
  • windows are sample-exact; legacy sliced at integer milliseconds.

extract_flac_header

extract_flac_header(backend: StorageBackend, uri: str) -> FlacHeader

Parse STREAMINFO fetching only header bytes.

Metadata block bodies are skipped, not downloaded.

STREAMINFO bytes 10-17 are one packed big-endian 64-bit field:

bits 63-44  sample rate in Hz         (20 bits)
bits 43-41  channels - 1               (3 bits)
bits 40-36  bits-per-sample - 1        (5 bits)
bits 35-0   total samples in stream   (36 bits; 0 = unknown)

(This is the fix over soundhub_utils, which read bits_per_sample from bits 36-32 plus a stray total-samples bit, and channels from bits 35-33 — total-samples bits — instead of 43-41.)

Parameters:

Name Type Description Default
backend StorageBackend

The storage backend to fetch through.

required
uri str

URI of a FLAC file, addressable by backend.

required

Returns:

Type Description
FlacHeader

The parsed FlacHeader.

Raises:

Type Description
OndioError

If uri is not a valid FLAC stream (missing marker, malformed metadata region, or STREAMINFO not first).

read_flac

read_flac(backend: StorageBackend, uri: str, start_sec: float | None = None, end_sec: float | None = None, *, decode: Literal[True] = True, use_range: bool | None = None) -> tuple[np.ndarray, int]
read_flac(backend: StorageBackend, uri: str, start_sec: float | None = None, end_sec: float | None = None, *, decode: Literal[False], use_range: bool | None = None) -> bytes
read_flac(backend: StorageBackend, uri: str, start_sec: float | None = None, end_sec: float | None = None, *, decode: bool = True, use_range: bool | None = None) -> tuple[np.ndarray, int] | bytes

Read a FLAC file — whole, or a [start_sec, end_sec] window — into memory.

Windows are cut by sample index: [round(start_sec * sr), round(end_sec * sr)).

Parameters:

Name Type Description Default
backend StorageBackend

The storage backend to fetch through.

required
uri str

URI of a FLAC file, addressable by backend.

required
start_sec float | None

Window start in seconds; None means from the beginning.

None
end_sec float | None

Window end in seconds; None means to the end of the stream (values past EOF are clamped, like Python slices).

None
decode bool

If True (default), return decoded PCM; if False, return the bytes of a standalone FLAC file — the original bytes exactly when no window is given (a plain read), a fresh lossless encode of the slice otherwise.

True
use_range bool | None

Fetch strategy. None (default) picks per the legacy heuristic: ranged download for files > 50 MB when the window is < 1/3 of the stream, full download otherwise. True/False forces one path. Both are sample-exact.

None

Returns:

Type Description
tuple[ndarray, int] | bytes

With decode=True, (samples, sample_rate) where samples is a

tuple[ndarray, int] | bytes

float32 array of shape (frames, channels) normalized to [-1, 1]

tuple[ndarray, int] | bytes

like libsndfile/soundfile. With decode=False, FLAC bytes.

Raises:

Type Description
ValueError

If the window is empty, negative, starts past EOF, or holds no samples.

OndioError

If any of these is true:

  • uri is not a valid FLAC stream.
  • A window was requested and the stream reports zero duration.
  • The audio to decode is corrupt or truncated.
  • A whole-file read meets a stream of unknown length.
  • decode=False must re-encode a window of a source that is not 8, 16 or 24 bits deep.
Note

The ranged path returns exactly the samples a full download would. A byte estimate chooses what to fetch. The frame numbers in the fetched bytes give the window's position. If the frames do not cover the window, the fetch widens; it fetches each byte at most once, so it never fetches more than the file. For a corrupt or truncated region the ranged path raises OndioError naming use_range=False. It never starts a full download.

download_flac

download_flac(backend: StorageBackend, uri: str, out_path: str | PathLike[str], start_sec: float | None = None, end_sec: float | None = None, *, use_range: bool | None = None) -> None

Write a .flac file containing [start_sec, end_sec] of uri to out_path.

With no window this is a byte-for-byte download of the original file. With one, the window is decoded, cut by sample index, and re-encoded — losslessly identical PCM, but not byte-identical to the source. Window and fetch semantics, and the ranged-path note, are as in read_flac.

(Counterpart of legacy soundhub_utils io.read_flac(src, dest, ...).)

Parameters:

Name Type Description Default
backend StorageBackend

The storage backend to fetch through.

required
uri str

URI of a FLAC file, addressable by backend.

required
out_path str | PathLike[str]

Local .flac destination path; parent directories are created.

required
start_sec float | None

Window start in seconds; None means from the beginning.

None
end_sec float | None

Window end in seconds; None means to the end of the stream.

None
use_range bool | None

As in read_flac.

None

Raises:

Type Description
ValueError

If the window is empty, negative, starts past EOF, or holds no samples.

OndioError

If any of these is true:

  • uri is not a valid FLAC stream.
  • A window was requested and the stream reports zero duration.
  • The window's audio is corrupt or truncated.
  • The source is not 8, 16 or 24 bits deep, so the window cannot be re-encoded.