1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! A pure-Rust FLAC decoder and encoder with no unsafe code and no C
//! dependency.
//!
//! FLAC (Free Lossless Audio Codec) stores audio so that decoding returns the
//! exact original samples, bit for bit. This crate reads a FLAC byte stream
//! into its raw integer samples and writes raw samples back into a valid FLAC
//! stream, without any lossy intermediate.
//!
//! It exists for steganography, watermarking, forensic analysis, and any audio
//! work that needs the decoded sample plane with a guarantee that a decode
//! followed by an encode preserves the data exactly.
//!
//! # Quick start
//!
//! ```no_run
//! use flac_io::{decode, encode};
//!
//! let bytes = std::fs::read("song.flac").unwrap();
//! let audio = decode(&bytes).unwrap();
//! println!("{} Hz, {} ch, {} bit", audio.sample_rate, audio.channels, audio.bits_per_sample);
//!
//! let out = encode(&audio).unwrap();
//! std::fs::write("song_reencoded.flac", out).unwrap();
//! ```
//!
//! # Sample layout
//!
//! [`FlacAudio::samples`] holds one inner vector per channel, each the same
//! length (the number of samples per channel). Samples are signed integers in
//! the stream's native bit depth, sign-extended into `i32`. For stereo, index
//! 0 is the left channel and index 1 is the right.
pub use FlacError;
pub use StreamInfo;
/// Decoded FLAC audio: the stream parameters plus the samples, one vector per
/// channel.
/// Read just the stream metadata (sample rate, channels, bit depth, total
/// samples, MD5) without decoding any audio.
///
/// The container is detected automatically: both native FLAC and Ogg-wrapped
/// FLAC are accepted. Only the metadata is read, so this stays cheap even for a
/// large file. Use it when you need the format of a stream but not its samples.
///
/// # Errors
///
/// Returns [`FlacError`] if the input is not FLAC, is truncated, its STREAMINFO
/// block is corrupt, or it declares a channel count or bit depth this crate
/// cannot decode (so `info` and [`decode`] agree on which streams are valid).
/// Decode a FLAC byte stream into its samples and parameters.
///
/// The container is detected automatically: both native FLAC (the `.flac` form,
/// starting with `fLaC`) and Ogg-wrapped FLAC (the `.oga` form, starting with
/// `OggS`) are accepted.
///
/// Decoding is bounded: a crafted stream cannot make this function allocate
/// without limit. The total number of decoded samples (summed across channels)
/// is capped near one billion, which holds the output buffer under about four
/// gibibytes; a stream that needs more returns [`FlacError::LimitExceeded`]
/// rather than risking the process.
///
/// # Errors
///
/// Returns [`FlacError`] if the input is not FLAC, is truncated, is corrupt, a
/// stored CRC does not match, it uses a feature this crate does not implement,
/// or it exceeds the decode size cap.
/// Encode samples into a valid native FLAC byte stream (the `.flac` form).
///
/// # Errors
///
/// Returns [`FlacError::InvalidInput`] if the channel vectors disagree in
/// length, the bit depth or channel count is out of range, or there are no
/// samples.
/// Encode samples into a FLAC stream wrapped in the Ogg container (the `.oga`
/// form).
///
/// The audio is encoded identically to [`encode`]; only the container differs.
/// Reading is symmetric: [`decode`] auto-detects either container, so there is
/// no separate Ogg decode function.
///
/// # Errors
///
/// Returns [`FlacError::InvalidInput`] under the same conditions as [`encode`].