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 asoundfile-style numpy array (default), or withdecode=Falsethe bytes of a standalone FLAC file;download_flac— the same window semantics, written to a local.flacpath (the counterpart of legacysoundhub_utilsio.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_samplefrom 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 anyStorageBackend; - the four legacy entry points collapse to
read_flac/download_flac, with the window optional and the fetch strategy overridable viause_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 |
required |
Returns:
| Type | Description |
|---|---|
FlacHeader
|
The parsed |
Raises:
| Type | Description |
|---|---|
OndioError
|
If |
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 |
required |
start_sec
|
float | None
|
Window start in seconds; |
None
|
end_sec
|
float | None
|
Window end in seconds; |
None
|
decode
|
bool
|
If |
True
|
use_range
|
bool | None
|
Fetch strategy. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, int] | bytes
|
With |
tuple[ndarray, int] | bytes
|
|
tuple[ndarray, int] | bytes
|
like libsndfile/ |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the window is empty, negative, starts past EOF, or holds no samples. |
OndioError
|
If any of these is true:
|
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 |
required |
out_path
|
str | PathLike[str]
|
Local |
required |
start_sec
|
float | None
|
Window start in seconds; |
None
|
end_sec
|
float | None
|
Window end in seconds; |
None
|
use_range
|
bool | None
|
As in |
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:
|