diff --git a/crates/audio/README.md b/crates/audio/README.md index 7cfb3471..4202441f 100644 --- a/crates/audio/README.md +++ b/crates/audio/README.md @@ -131,7 +131,11 @@ if let Some(second) = list.get(1) { ``` A track index the file does not have is `Unsupported`. `DecodeOptions::with_max_samples` sets -another size limit. `tracks_of` lists the tracks of a file read from a `ByteSource`; +another size limit. The default is `DEFAULT_MAX_SAMPLES`, 2^30 samples (4 GiB of `f32`), which +`decode` and `decode_with` can fill from a small compressed file because they keep the whole +result. An app that opens files it did not write passes a limit it can hold (for example +`DEFAULT_MAX_SAMPLES / 8`, or its longest supported clip), or streams with `Decoder`, which has no +limit because it keeps nothing. `tracks_of` lists the tracks of a file read from a `ByteSource`; `detect_container` names a file's container from its first bytes. `DECODE_EXTENSIONS` lists the file extensions of the formats `decode` reads, for a file picker's filter. diff --git a/crates/audio/src/read/mod.rs b/crates/audio/src/read/mod.rs index 1966d70f..533e996a 100644 --- a/crates/audio/src/read/mod.rs +++ b/crates/audio/src/read/mod.rs @@ -152,7 +152,12 @@ pub struct DecodeOptions { /// them; `None` is the first. pub track: Option, /// The most samples (frames × channels) [`decode_with`] returns; a longer file is - /// [`AudioError::TooLarge`]. The streaming [`Decoder`] has no limit. + /// [`AudioError::TooLarge`]. The default, [`DEFAULT_MAX_SAMPLES`], is 2^30 samples: 4 GiB of + /// `f32`, about 3 hours of 48 kHz stereo. It is a ceiling for trusted input, not a budget: + /// a small compressed file (silent FLAC, say) can decode to all of it, and [`decode_with`] + /// holds the whole result in memory. A caller that decodes files it does not control sets + /// this to what it can hold, or reads blocks with [`Decoder`], which keeps nothing and has no + /// limit. pub max_samples: u64, } @@ -399,7 +404,9 @@ pub fn decode(bytes: &[u8], ext_hint: Option<&str>) -> Result<(AudioInfo, AudioB decode_with(bytes, ext_hint, &DecodeOptions::default()) } -/// [`decode`] with options: another track, or another size limit. +/// [`decode`] with options: another track, or another size limit. [`decode`] and `decode_with` +/// keep every decoded sample, so for untrusted files pass a limit +/// ([`DecodeOptions::with_max_samples`]) that the host can hold, or stream with [`Decoder`]. /// /// ``` /// # #[cfg(feature = "pcm-encode")] {