flac_codec/decode.rs
1// Copyright 2025 Brian Langenberger
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! For decoding FLAC files to PCM samples
10
11use crate::Error;
12use crate::audio::Frame;
13use crate::metadata::{BlockList, ChannelMask, SeekTable};
14use bitstream_io::{BitRead, SignedBitCount};
15use std::collections::VecDeque;
16use std::fs::File;
17use std::io::BufReader;
18use std::num::NonZero;
19use std::path::Path;
20
21pub use crate::metadata::Metadata;
22
23trait SignedInteger:
24 bitstream_io::SignedInteger + Into<i64> + std::ops::AddAssign + std::ops::Neg<Output = Self>
25{
26 fn from_i64(i: i64) -> Self;
27
28 fn from_u32(u: u32) -> Self;
29}
30
31impl SignedInteger for i32 {
32 #[inline(always)]
33 fn from_i64(i: i64) -> i32 {
34 i as i32
35 }
36
37 #[inline(always)]
38 fn from_u32(u: u32) -> i32 {
39 u as i32
40 }
41}
42
43impl SignedInteger for i64 {
44 #[inline(always)]
45 fn from_i64(i: i64) -> i64 {
46 i
47 }
48
49 #[inline(always)]
50 fn from_u32(u: u32) -> i64 {
51 u as i64
52 }
53}
54
55/// A FLAC reader which outputs PCM samples as bytes
56///
57/// # Example
58///
59/// ```
60/// use flac_codec::{
61/// byteorder::LittleEndian,
62/// encode::{FlacByteWriter, Options},
63/// decode::{FlacByteReader, Metadata},
64/// };
65/// use std::io::{Cursor, Read, Seek, Write};
66///
67/// let mut flac = Cursor::new(vec![]); // a FLAC file in memory
68///
69/// let mut writer = FlacByteWriter::endian(
70/// &mut flac, // our wrapped writer
71/// LittleEndian, // .wav-style byte order
72/// Options::default(), // default encoding options
73/// 44100, // sample rate
74/// 16, // bits-per-sample
75/// 1, // channel count
76/// Some(2000), // total bytes
77/// ).unwrap();
78///
79/// // write 1000 samples as 16-bit, signed, little-endian bytes (2000 bytes total)
80/// let written_bytes = (0..1000).map(i16::to_le_bytes).flatten().collect::<Vec<u8>>();
81/// assert!(writer.write_all(&written_bytes).is_ok());
82///
83/// // finalize writing file
84/// assert!(writer.finalize().is_ok());
85///
86/// flac.rewind().unwrap();
87///
88/// // open reader around written FLAC file
89/// let mut reader = FlacByteReader::endian(flac, LittleEndian).unwrap();
90///
91/// // read 2000 bytes
92/// let mut read_bytes = vec![];
93/// assert!(reader.read_to_end(&mut read_bytes).is_ok());
94///
95/// // ensure MD5 sum of signed, little-endian samples matches hash in file
96/// let mut md5 = md5::Context::new();
97/// md5.consume(&read_bytes);
98/// assert_eq!(&md5.compute().0, reader.md5().unwrap());
99///
100/// // ensure input and output matches
101/// assert_eq!(read_bytes, written_bytes);
102/// ```
103#[derive(Clone)]
104pub struct FlacByteReader<R, E> {
105 // the wrapped decoder
106 decoder: Decoder<R>,
107 // decoded byte buffer
108 buf: VecDeque<u8>,
109 // the endianness of the bytes in our byte buffer
110 endianness: std::marker::PhantomData<E>,
111 // offset start of frames, if known
112 frames_start: Option<u64>,
113}
114
115impl<R: std::io::Read, E: crate::byteorder::Endianness> FlacByteReader<R, E> {
116 /// Opens new FLAC reader which wraps the given reader
117 ///
118 /// The reader must be positioned at the start of the
119 /// FLAC stream. If the file has non-FLAC data
120 /// at the beginning (such as ID3v2 tags), one
121 /// should skip such data before initializing a `FlacByteReader`.
122 #[inline]
123 pub fn new(mut reader: R) -> Result<Self, Error> {
124 let blocklist = BlockList::read(reader.by_ref())?;
125
126 Ok(Self {
127 decoder: Decoder::new(reader, blocklist),
128 buf: VecDeque::default(),
129 endianness: std::marker::PhantomData,
130 frames_start: None,
131 })
132 }
133
134 /// Opens new FLAC reader in the given endianness
135 ///
136 /// The reader must be positioned at the start of the
137 /// FLAC stream. If the file has non-FLAC data
138 /// at the beginning (such as ID3v2 tags), one
139 /// should skip such data before initializing a `FlacByteReader`.
140 #[inline]
141 pub fn endian(reader: R, _endian: E) -> Result<Self, Error> {
142 Self::new(reader)
143 }
144
145 /// Returns FLAC metadata blocks
146 #[inline]
147 pub fn metadata(&self) -> &BlockList {
148 self.decoder.metadata()
149 }
150}
151
152impl<R: std::io::Read + std::io::Seek, E: crate::byteorder::Endianness> FlacByteReader<R, E> {
153 /// Opens a new seekable FLAC reader which wraps the given reader
154 ///
155 /// If a stream is both readable and seekable,
156 /// it's vital to use this method to open it if one
157 /// also wishes to seek within the FLAC stream.
158 /// Otherwise, an I/O error will result when attempting to seek.
159 ///
160 /// [`FlacByteReader::open`] calls this method to ensure
161 /// all `File`-based streams are also seekable.
162 ///
163 /// The reader must be positioned at the start of the
164 /// FLAC stream. If the file has non-FLAC data
165 /// at the beginning (such as ID3v2 tags), one
166 /// should skip such data before initializing a `FlacByteReader`.
167 ///
168 /// # Example
169 ///
170 /// ```
171 /// use flac_codec::{
172 /// byteorder::LittleEndian,
173 /// encode::{FlacByteWriter, Options},
174 /// decode::FlacByteReader,
175 /// };
176 /// use std::io::{Cursor, Read, Seek, SeekFrom, Write};
177 ///
178 /// let mut flac = Cursor::new(vec![]); // a FLAC file in memory
179 ///
180 /// let mut writer = FlacByteWriter::endian(
181 /// &mut flac, // our wrapped writer
182 /// LittleEndian, // .wav-style byte order
183 /// Options::default(), // default encoding options
184 /// 44100, // sample rate
185 /// 16, // bits-per-sample
186 /// 1, // channel count
187 /// Some(2000), // total bytes
188 /// ).unwrap();
189 ///
190 /// // write 1000 samples as 16-bit, signed, little-endian bytes (2000 bytes total)
191 /// let written_bytes = (0..1000).map(i16::to_le_bytes).flatten().collect::<Vec<u8>>();
192 /// assert!(writer.write_all(&written_bytes).is_ok());
193 ///
194 /// // finalize writing file
195 /// assert!(writer.finalize().is_ok());
196 ///
197 /// flac.rewind().unwrap();
198 ///
199 /// // open reader around written FLAC file
200 /// let mut reader: FlacByteReader<_, LittleEndian> =
201 /// FlacByteReader::new_seekable(flac).unwrap();
202 ///
203 /// // read 2000 bytes
204 /// let mut read_bytes_1 = vec![];
205 /// assert!(reader.read_to_end(&mut read_bytes_1).is_ok());
206 ///
207 /// // ensure input and output matches
208 /// assert_eq!(read_bytes_1, written_bytes);
209 ///
210 /// // rewind reader to halfway through file
211 /// assert!(reader.seek(SeekFrom::Start(1000)).is_ok());
212 ///
213 /// // read 1000 bytes
214 /// let mut read_bytes_2 = vec![];
215 /// assert!(reader.read_to_end(&mut read_bytes_2).is_ok());
216 ///
217 /// // ensure output matches back half of input
218 /// assert_eq!(read_bytes_2.len(), 1000);
219 /// assert!(written_bytes.ends_with(&read_bytes_2));
220 /// ```
221 pub fn new_seekable(mut reader: R) -> Result<Self, Error> {
222 let blocklist = BlockList::read(reader.by_ref())?;
223 let frames_start = reader.stream_position()?;
224
225 Ok(Self {
226 decoder: Decoder::new(reader, blocklist),
227 buf: VecDeque::default(),
228 endianness: std::marker::PhantomData,
229 frames_start: Some(frames_start),
230 })
231 }
232}
233
234impl<R: std::io::Read, E: crate::byteorder::Endianness> Metadata for FlacByteReader<R, E> {
235 #[inline]
236 fn channel_count(&self) -> u8 {
237 self.decoder.channel_count().get()
238 }
239
240 #[inline]
241 fn channel_mask(&self) -> ChannelMask {
242 self.decoder.channel_mask()
243 }
244
245 #[inline]
246 fn sample_rate(&self) -> u32 {
247 self.decoder.sample_rate()
248 }
249
250 #[inline]
251 fn bits_per_sample(&self) -> u32 {
252 self.decoder.bits_per_sample()
253 }
254
255 #[inline]
256 fn total_samples(&self) -> Option<u64> {
257 self.decoder.total_samples().map(|s| s.get())
258 }
259
260 #[inline]
261 fn md5(&self) -> Option<&[u8; 16]> {
262 self.decoder.md5()
263 }
264}
265
266impl<E: crate::byteorder::Endianness> FlacByteReader<BufReader<File>, E> {
267 /// Opens FLAC file from the given path
268 #[inline]
269 pub fn open<P: AsRef<Path>>(path: P, _endianness: E) -> Result<Self, Error> {
270 FlacByteReader::new_seekable(BufReader::new(File::open(path.as_ref())?))
271 }
272}
273
274impl<R: std::io::Read, E: crate::byteorder::Endianness> std::io::Read for FlacByteReader<R, E> {
275 /// Reads samples to the given buffer as bytes in our stream's endianness
276 ///
277 /// Returned samples are interleaved by channel, like:
278 /// [left₀ , right₀ , left₁ , right₁ , left₂ , right₂ , …]
279 ///
280 /// This is the same format used by common PCM container
281 /// formats like WAVE and AIFF
282 ///
283 /// # Errors
284 ///
285 /// Returns any error that occurs when reading the stream,
286 /// converted to an I/O error.
287 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
288 if self.buf.is_empty() {
289 match self.decoder.read_frame()? {
290 Some(frame) => {
291 self.buf.resize(frame.bytes_len(), 0);
292 frame.to_buf::<E>(self.buf.make_contiguous());
293 self.buf.read(buf)
294 }
295 None => Ok(0),
296 }
297 } else {
298 self.buf.read(buf)
299 }
300 }
301}
302
303impl<R: std::io::Read, E: crate::byteorder::Endianness> std::io::BufRead for FlacByteReader<R, E> {
304 /// Reads samples to the given buffer as bytes in our stream's endianness
305 ///
306 /// Returned samples are interleaved by channel, like:
307 /// [left₀ , right₀ , left₁ , right₁ , left₂ , right₂ , …]
308 ///
309 /// # Errors
310 ///
311 /// Returns any error that occurs when reading the stream,
312 /// converted to an I/O error.
313 fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
314 if self.buf.is_empty() {
315 match self.decoder.read_frame()? {
316 Some(frame) => {
317 self.buf.resize(frame.bytes_len(), 0);
318 frame.to_buf::<E>(self.buf.make_contiguous());
319 self.buf.fill_buf()
320 }
321 None => Ok(&[]),
322 }
323 } else {
324 self.buf.fill_buf()
325 }
326 }
327
328 fn consume(&mut self, amt: usize) {
329 self.buf.consume(amt)
330 }
331}
332
333/// A FLAC reader which outputs PCM samples as signed integers
334///
335/// # Example
336///
337/// ```
338/// use flac_codec::{
339/// encode::{FlacSampleWriter, Options},
340/// decode::FlacSampleReader,
341/// };
342/// use std::io::{Cursor, Seek};
343///
344/// let mut flac = Cursor::new(vec![]); // a FLAC file in memory
345///
346/// let mut writer = FlacSampleWriter::new(
347/// &mut flac, // our wrapped writer
348/// Options::default(), // default encoding options
349/// 44100, // sample rate
350/// 16, // bits-per-sample
351/// 1, // channel count
352/// Some(1000), // total samples
353/// ).unwrap();
354///
355/// // write 1000 samples
356/// let written_samples = (0..1000).collect::<Vec<i32>>();
357/// assert!(writer.write(&written_samples).is_ok());
358///
359/// // finalize writing file
360/// assert!(writer.finalize().is_ok());
361///
362/// flac.rewind().unwrap();
363///
364/// // open reader around written FLAC file
365/// let mut reader = FlacSampleReader::new(flac).unwrap();
366///
367/// // read 1000 samples
368/// let mut read_samples = vec![0; 1000];
369/// assert!(matches!(reader.read(&mut read_samples), Ok(1000)));
370///
371/// // ensure they match
372/// assert_eq!(read_samples, written_samples);
373/// ```
374#[derive(Clone)]
375pub struct FlacSampleReader<R> {
376 // the wrapped decoder
377 decoder: Decoder<R>,
378 // decoded sample buffer
379 buf: VecDeque<i32>,
380 // start of FLAC frames
381 frames_start: Option<u64>,
382}
383
384impl<R: std::io::Read> FlacSampleReader<R> {
385 /// Opens new FLAC reader which wraps the given reader
386 ///
387 /// The reader must be positioned at the start of the
388 /// FLAC stream. If the file has non-FLAC data
389 /// at the beginning (such as ID3v2 tags), one
390 /// should skip such data before initializing a `FlacByteReader`.
391 #[inline]
392 pub fn new(mut reader: R) -> Result<Self, Error> {
393 let blocklist = BlockList::read(reader.by_ref())?;
394
395 Ok(Self {
396 decoder: Decoder::new(reader, blocklist),
397 buf: VecDeque::default(),
398 frames_start: None,
399 })
400 }
401
402 /// Returns FLAC metadata blocks
403 #[inline]
404 pub fn metadata(&self) -> &BlockList {
405 self.decoder.metadata()
406 }
407
408 /// Attempts to fill the buffer with samples and returns quantity read
409 ///
410 /// Returned samples are interleaved by channel, like:
411 /// [left₀ , right₀ , left₁ , right₁ , left₂ , right₂ , …]
412 ///
413 /// # Errors
414 ///
415 /// Returns error if some error occurs reading FLAC file
416 #[inline]
417 pub fn read(&mut self, samples: &mut [i32]) -> Result<usize, Error> {
418 if self.buf.is_empty() {
419 match self.decoder.read_frame()? {
420 Some(frame) => {
421 self.buf.extend(frame.iter());
422 }
423 None => return Ok(0),
424 }
425 }
426
427 let to_consume = samples.len().min(self.buf.len());
428 for (i, o) in samples.iter_mut().zip(self.buf.drain(0..to_consume)) {
429 *i = o;
430 }
431 Ok(to_consume)
432 }
433
434 /// Reads all samples from source FLAC, placing them in `buf`
435 ///
436 /// If successful, returns the total number of samples read
437 pub fn read_to_end(&mut self, buf: &mut Vec<i32>) -> Result<usize, Error> {
438 let mut amt_read = 0;
439 loop {
440 match self.fill_buf()? {
441 [] => break Ok(amt_read),
442 decoded => {
443 let decoded_len = decoded.len();
444 buf.extend_from_slice(decoded);
445 amt_read += decoded_len;
446 self.consume(decoded_len);
447 }
448 }
449 }
450 }
451
452 /// Returns complete buffer of all read samples
453 ///
454 /// Analogous to [`std::io::BufRead::fill_buf`], this should
455 /// be paired with [`FlacSampleReader::consume`] to
456 /// consume samples in the filled buffer once used.
457 ///
458 /// Returned samples are interleaved by channel, like:
459 /// [left₀ , right₀ , left₁ , right₁ , left₂ , right₂ , …]
460 ///
461 /// # Errors
462 ///
463 /// Returns error if some error occurs reading FLAC file
464 /// to fill buffer.
465 #[inline]
466 pub fn fill_buf(&mut self) -> Result<&[i32], Error> {
467 if self.buf.is_empty() {
468 match self.decoder.read_frame()? {
469 Some(frame) => {
470 self.buf.extend(frame.iter());
471 }
472 None => return Ok(&[]),
473 }
474 }
475
476 Ok(self.buf.make_contiguous())
477 }
478
479 /// Informs the reader that `amt` samples have been consumed.
480 ///
481 /// Analagous to [`std::io::BufRead::consume`], which marks
482 /// samples as having been read.
483 ///
484 /// May panic if attempting to consume more bytes
485 /// than are available in the buffer.
486 #[inline]
487 pub fn consume(&mut self, amt: usize) {
488 self.buf.drain(0..amt);
489 }
490}
491
492impl<R: std::io::Read + std::io::Seek> FlacSampleReader<R> {
493 /// Opens a new seekable FLAC reader which wraps the given reader
494 ///
495 /// If a stream is both readable and seekable,
496 /// it's vital to use this method to open it if one
497 /// also wishes to seek within the FLAC stream.
498 /// Otherwise, an I/O error will result when attempting to seek.
499 ///
500 /// [`FlacSampleReader::open`] calls this method to ensure
501 /// all `File`-based streams are also seekable.
502 ///
503 /// The reader must be positioned at the start of the
504 /// FLAC stream. If the file has non-FLAC data
505 /// at the beginning (such as ID3v2 tags), one
506 /// should skip such data before initializing a `FlacSampleReader`.
507 ///
508 /// # Example
509 ///
510 /// ```
511 /// use flac_codec::{
512 /// encode::{FlacSampleWriter, Options},
513 /// decode::FlacSampleReader,
514 /// };
515 /// use std::io::{Cursor, Seek};
516 ///
517 /// let mut flac = Cursor::new(vec![]); // a FLAC file in memory
518 ///
519 /// let mut writer = FlacSampleWriter::new(
520 /// &mut flac, // our wrapped writer
521 /// Options::default(), // default encoding options
522 /// 44100, // sample rate
523 /// 16, // bits-per-sample
524 /// 1, // channel count
525 /// Some(1000), // total samples
526 /// ).unwrap();
527 ///
528 /// // write 1000 samples
529 /// let written_samples = (0..1000).collect::<Vec<i32>>();
530 /// assert!(writer.write(&written_samples).is_ok());
531 ///
532 /// // finalize writing file
533 /// assert!(writer.finalize().is_ok());
534 ///
535 /// flac.rewind().unwrap();
536 ///
537 /// // open reader around written FLAC file
538 /// let mut reader = FlacSampleReader::new_seekable(flac).unwrap();
539 ///
540 /// // read 1000 samples
541 /// let mut read_samples_1 = vec![0; 1000];
542 /// assert!(matches!(reader.read(&mut read_samples_1), Ok(1000)));
543 ///
544 /// // ensure they match
545 /// assert_eq!(read_samples_1, written_samples);
546 ///
547 /// // rewind reader to halfway through file
548 /// assert!(reader.seek(500).is_ok());
549 ///
550 /// // read 500 samples
551 /// let mut read_samples_2 = vec![0; 500];
552 /// assert!(matches!(reader.read(&mut read_samples_2), Ok(500)));
553 ///
554 /// // ensure output matches back half of input
555 /// assert_eq!(read_samples_2.len(), 500);
556 /// assert!(written_samples.ends_with(&read_samples_2));
557 /// ```
558 pub fn new_seekable(mut reader: R) -> Result<Self, Error> {
559 let blocklist = BlockList::read(reader.by_ref())?;
560 let frames_start = reader.stream_position()?;
561
562 Ok(Self {
563 decoder: Decoder::new(reader, blocklist),
564 buf: VecDeque::default(),
565 frames_start: Some(frames_start),
566 })
567 }
568}
569
570impl FlacSampleReader<BufReader<File>> {
571 /// Opens FLAC file from the given path
572 #[inline]
573 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
574 FlacSampleReader::new_seekable(BufReader::new(File::open(path.as_ref())?))
575 }
576}
577
578impl<R: std::io::Read> Metadata for FlacSampleReader<R> {
579 #[inline]
580 fn channel_count(&self) -> u8 {
581 self.decoder.channel_count().get()
582 }
583
584 #[inline]
585 fn channel_mask(&self) -> ChannelMask {
586 self.decoder.channel_mask()
587 }
588
589 #[inline]
590 fn sample_rate(&self) -> u32 {
591 self.decoder.sample_rate()
592 }
593
594 #[inline]
595 fn bits_per_sample(&self) -> u32 {
596 self.decoder.bits_per_sample()
597 }
598
599 #[inline]
600 fn total_samples(&self) -> Option<u64> {
601 self.decoder.total_samples().map(|s| s.get())
602 }
603
604 #[inline]
605 fn md5(&self) -> Option<&[u8; 16]> {
606 self.decoder.md5()
607 }
608}
609
610impl<R: std::io::Read> IntoIterator for FlacSampleReader<R> {
611 type IntoIter = FlacSampleIterator<R>;
612 type Item = Result<i32, Error>;
613
614 fn into_iter(self) -> FlacSampleIterator<R> {
615 FlacSampleIterator { reader: self }
616 }
617}
618
619/// A FLAC reader which iterates over decoded samples as signed integers
620///
621/// # Example
622///
623/// ```
624/// use flac_codec::{
625/// encode::{FlacSampleWriter, Options},
626/// decode::FlacSampleReader,
627/// };
628/// use std::io::{Cursor, Seek};
629///
630/// let mut flac = Cursor::new(vec![]); // a FLAC file in memory
631///
632/// let mut writer = FlacSampleWriter::new(
633/// &mut flac, // our wrapped writer
634/// Options::default(), // default encoding options
635/// 44100, // sample rate
636/// 16, // bits-per-sample
637/// 1, // channel count
638/// Some(10), // total samples
639/// ).unwrap();
640///
641/// // write 10 samples
642/// let written_samples = (0..10).collect::<Vec<i32>>();
643/// assert!(writer.write(&written_samples).is_ok());
644///
645/// // finalize writing file
646/// assert!(writer.finalize().is_ok());
647///
648/// flac.rewind().unwrap();
649///
650/// // open reader around written FLAC file
651/// let reader = FlacSampleReader::new(flac).unwrap();
652///
653/// // convert reader to iterator
654/// let mut iter = reader.into_iter();
655///
656/// // read all its samples
657/// let read_samples = iter.collect::<Result<Vec<_>, _>>().unwrap();
658///
659/// // ensure they match
660/// assert_eq!(read_samples, written_samples);
661/// assert_eq!(read_samples, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
662/// ```
663#[derive(Clone)]
664pub struct FlacSampleIterator<R> {
665 reader: FlacSampleReader<R>,
666}
667
668impl<R: std::io::Read> Metadata for FlacSampleIterator<R> {
669 fn channel_count(&self) -> u8 {
670 self.reader.channel_count()
671 }
672
673 fn sample_rate(&self) -> u32 {
674 self.reader.sample_rate()
675 }
676
677 fn bits_per_sample(&self) -> u32 {
678 self.reader.bits_per_sample()
679 }
680
681 fn total_samples(&self) -> Option<u64> {
682 self.reader.total_samples()
683 }
684
685 fn md5(&self) -> Option<&[u8; 16]> {
686 self.reader.md5()
687 }
688}
689
690impl<R: std::io::Read> Iterator for FlacSampleIterator<R> {
691 type Item = Result<i32, Error>;
692
693 #[inline]
694 fn next(&mut self) -> Option<Result<i32, Error>> {
695 match self.reader.buf.pop_front() {
696 Some(sample) => Some(Ok(sample)),
697 None => match self.reader.decoder.read_frame() {
698 Ok(Some(frame)) => {
699 self.reader.buf.extend(frame.iter());
700 self.reader.buf.pop_front().map(Ok)
701 }
702 Err(e) => Some(Err(e)),
703 Ok(None) => None,
704 },
705 }
706 }
707}
708
709impl<R: std::io::Read + std::io::Seek, E: crate::byteorder::Endianness> std::io::Seek
710 for FlacByteReader<R, E>
711{
712 fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
713 use std::cmp::Ordering;
714
715 let Self { decoder, buf, .. } = self;
716
717 let streaminfo = decoder.blocks.streaminfo();
718
719 let bytes_per_pcm_frame: u64 = (u32::from(streaminfo.bits_per_sample).div_ceil(8)
720 * u32::from(streaminfo.channels.get()))
721 .into();
722
723 // the desired absolute position in the stream, in bytes
724 let desired_pos: u64 = match pos {
725 std::io::SeekFrom::Start(pos) => pos,
726 std::io::SeekFrom::Current(pos) => {
727 // current position in bytes is current position in samples
728 // converted to bytes *minus* the un-consumed space in the buffer
729 // since the sample position is running ahead of the byte position
730 let original_pos: u64 =
731 (decoder.current_sample * bytes_per_pcm_frame) - (buf.len() as u64);
732
733 match pos.cmp(&0) {
734 Ordering::Less => {
735 original_pos
736 .checked_sub(pos.unsigned_abs())
737 .ok_or(std::io::Error::new(
738 std::io::ErrorKind::InvalidInput,
739 "cannot seek below byte 0",
740 ))?
741 }
742 Ordering::Equal => return Ok(original_pos),
743 Ordering::Greater => {
744 original_pos
745 .checked_add(pos.unsigned_abs())
746 .ok_or(std::io::Error::new(
747 std::io::ErrorKind::InvalidInput,
748 "seek offset too large",
749 ))?
750 }
751 }
752 }
753 std::io::SeekFrom::End(pos) => {
754 // if the total samples is unknown in streaminfo,
755 // we have no way to know where the file's end is
756 // (this is a very unusual case)
757 let max_pos: u64 = decoder.total_samples().map(|s| s.get()).ok_or_else(|| {
758 std::io::Error::new(std::io::ErrorKind::NotSeekable, "total samples not known")
759 })?;
760
761 match pos.cmp(&0) {
762 Ordering::Less => max_pos.checked_sub(pos.unsigned_abs()).ok_or_else(|| {
763 std::io::Error::new(
764 std::io::ErrorKind::InvalidInput,
765 "cannot seek below byte 0",
766 )
767 })?,
768 Ordering::Equal => max_pos,
769 Ordering::Greater => {
770 return Err(std::io::Error::new(
771 std::io::ErrorKind::InvalidInput,
772 "cannot seek beyond end of file",
773 ));
774 }
775 }
776 }
777 };
778
779 // perform seek in stream to the desired sample
780 // (this will usually be some position prior to the desired sample)
781 let mut new_pos = decoder.seek(
782 self.frames_start
783 .ok_or(std::io::Error::from(std::io::ErrorKind::NotSeekable))?,
784 desired_pos / bytes_per_pcm_frame,
785 )? * bytes_per_pcm_frame;
786
787 // seeking invalidates current buffer
788 buf.clear();
789
790 // skip bytes to reach desired sample
791 while new_pos < desired_pos {
792 use std::io::BufRead;
793
794 let buf = self.fill_buf()?;
795
796 if !buf.is_empty() {
797 let to_skip = (usize::try_from(desired_pos - new_pos).unwrap()).min(buf.len());
798 self.consume(to_skip);
799 new_pos += to_skip as u64;
800 } else {
801 // attempting to seek beyond the end of the FLAC file
802 return Err(std::io::Error::new(
803 std::io::ErrorKind::UnexpectedEof,
804 "stream exhausted before sample reached",
805 ));
806 }
807 }
808
809 Ok(desired_pos)
810 }
811}
812
813impl<R: std::io::Read + std::io::Seek> FlacSampleReader<R> {
814 /// Seeks to the given channel-independent sample
815 ///
816 /// The sample is relative to the beginning of the stream
817 pub fn seek(&mut self, sample: u64) -> Result<(), Error> {
818 let channels: u8 = self.channel_count();
819
820 // actual position, in channel-independent samples
821 let mut pos = self.decoder.seek(
822 self.frames_start
823 .ok_or(std::io::Error::from(std::io::ErrorKind::NotSeekable))?,
824 sample,
825 )?;
826
827 // seeking invalidates the current buffer
828 self.buf.clear();
829
830 // needed channel-independent samples
831 while sample > pos {
832 let buf = self.fill_buf()?;
833
834 // size of buf in channel-independent samples
835 match buf.len() / usize::from(channels) {
836 0 => {
837 // read beyond end of stream
838 return Err(Error::InvalidSeek);
839 }
840 buf_samples => {
841 // amount of channel-independent samples to consume
842 let to_consume = buf_samples.min((sample - pos).try_into().unwrap());
843
844 // mark samples in buffer as consumed
845 self.consume(to_consume * usize::from(channels));
846
847 // advance current actual position
848 pos += to_consume as u64;
849 }
850 }
851 }
852
853 Ok(())
854 }
855}
856
857/// A FLAC reader which outputs non-interleaved channels
858///
859/// # Example
860/// ```
861/// use flac_codec::{
862/// encode::{FlacChannelWriter, Options},
863/// decode::FlacChannelReader,
864/// };
865/// use std::io::{Cursor, Seek};
866///
867/// let mut flac = Cursor::new(vec![]); // a FLAC file in memory
868///
869/// let mut writer = FlacChannelWriter::new(
870/// &mut flac, // our wrapped writer
871/// Options::default(), // default encoding options
872/// 44100, // sample rate
873/// 16, // bits-per-sample
874/// 2, // channel count
875/// Some(5), // total channel-independent samples
876/// ).unwrap();
877///
878/// // write our samples, divided by channel
879/// let written_samples = vec![
880/// vec![1, 2, 3, 4, 5],
881/// vec![-1, -2, -3, -4, -5],
882/// ];
883/// assert!(writer.write(&written_samples).is_ok());
884///
885/// // finalize writing file
886/// assert!(writer.finalize().is_ok());
887///
888/// flac.rewind().unwrap();
889///
890/// // open reader around written FLAC file
891/// let mut reader = FlacChannelReader::new(flac).unwrap();
892///
893/// // read a buffer's worth of samples
894/// let read_samples = reader.fill_buf().unwrap();
895///
896/// // ensure the channels match
897/// assert_eq!(read_samples.len(), written_samples.len());
898/// assert_eq!(read_samples[0], written_samples[0]);
899/// assert_eq!(read_samples[1], written_samples[1]);
900/// ```
901#[derive(Clone)]
902pub struct FlacChannelReader<R> {
903 // the wrapped decoder
904 decoder: Decoder<R>,
905 // amount of consumed frames across all channels
906 consumed: usize,
907 // start of FLAC frames
908 frames_start: Option<u64>,
909}
910
911impl<R: std::io::Read> FlacChannelReader<R> {
912 /// Opens new FLAC reader which wraps the given reader
913 ///
914 /// The reader must be positioned at the start of the
915 /// FLAC stream. If the file has non-FLAC data
916 /// at the beginning (such as ID3v2 tags), one
917 /// should skip such data before initializing a `FlacByteReader`.
918 #[inline]
919 pub fn new(mut reader: R) -> Result<Self, Error> {
920 let blocklist = BlockList::read(reader.by_ref())?;
921
922 Ok(Self {
923 decoder: Decoder::new(reader, blocklist),
924 consumed: 0,
925 frames_start: None,
926 })
927 }
928
929 /// Returns FLAC metadata blocks
930 #[inline]
931 pub fn metadata(&self) -> &BlockList {
932 self.decoder.metadata()
933 }
934
935 /// Returns complete buffer of all read samples
936 ///
937 /// Analogous to [`std::io::BufRead::fill_buf`], this should
938 /// be paired with [`FlacSampleReader::consume`] to
939 /// consume samples in the filled buffer once used.
940 ///
941 /// Returned samples are returned as a `Vec` of channel slices,
942 /// like: [[left₀ , left₁ , left₂ , …], [right₀ , right₁ , right₂ , …]]
943 ///
944 /// The returned buffer will always contain at least one channel.
945 /// All channel slices will always be the same length.
946 ///
947 /// # Errors
948 ///
949 /// Returns error if some error occurs reading FLAC file
950 /// to fill buffer.
951 #[inline]
952 pub fn fill_buf(&mut self) -> Result<Vec<&[i32]>, Error> {
953 if self.consumed < self.decoder.buf.pcm_frames() {
954 Ok(self
955 .decoder
956 .buf
957 .channels()
958 .map(|c| &c[self.consumed..])
959 .collect())
960 } else {
961 self.consumed = 0;
962 let channels = usize::from(self.decoder.channel_count().get());
963 match self.decoder.read_frame()? {
964 Some(frame) => Ok(frame.channels().collect()),
965 None => Ok(vec![&[]; channels]),
966 }
967 }
968 }
969
970 /// Informs the reader that `amt` channel-indepedent samples
971 /// have been consumed.
972 ///
973 /// Analagous to [`std::io::BufRead::consume`], which marks
974 /// samples as having been read.
975 ///
976 /// May panic if attempting to consume more bytes
977 /// than are available in the buffer.
978 #[inline]
979 pub fn consume(&mut self, amt: usize) {
980 self.consumed += amt;
981 }
982}
983
984impl<R: std::io::Read + std::io::Seek> FlacChannelReader<R> {
985 /// Opens a new seekable FLAC reader which wraps the given reader
986 ///
987 /// If a stream is both readable and seekable,
988 /// it's vital to use this method to open it if one
989 /// also wishes to seek within the FLAC stream.
990 /// Otherwise, an I/O error will result when attempting to seek.
991 ///
992 /// [`FlacChannelReader::open`] calls this method to ensure
993 /// all `File`-based streams are also seekable.
994 ///
995 /// The reader must be positioned at the start of the
996 /// FLAC stream. If the file has non-FLAC data
997 /// at the beginning (such as ID3v2 tags), one
998 /// should skip such data before initializing a `FlacChannelReader`.
999 pub fn new_seekable(mut reader: R) -> Result<Self, Error> {
1000 let blocklist = BlockList::read(reader.by_ref())?;
1001 let frames_start = reader.stream_position()?;
1002
1003 Ok(Self {
1004 decoder: Decoder::new(reader, blocklist),
1005 consumed: 0,
1006 frames_start: Some(frames_start),
1007 })
1008 }
1009}
1010
1011impl FlacChannelReader<BufReader<File>> {
1012 /// Opens FLAC file from the given path
1013 #[inline]
1014 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
1015 FlacChannelReader::new_seekable(BufReader::new(File::open(path.as_ref())?))
1016 }
1017}
1018
1019impl<R: std::io::Read + std::io::Seek> FlacChannelReader<R> {
1020 /// Seeks to the given channel-independent sample
1021 ///
1022 /// The sample is relative to the beginning of the stream
1023 pub fn seek(&mut self, sample: u64) -> Result<(), Error> {
1024 // actual position, in channel-independent samples
1025 let mut pos = self.decoder.seek(
1026 self.frames_start
1027 .ok_or(std::io::Error::from(std::io::ErrorKind::NotSeekable))?,
1028 sample,
1029 )?;
1030
1031 // seeking invalidates the current samples consumed
1032 self.consumed = 0;
1033
1034 // needed channel-independent samples
1035 while sample > pos {
1036 let buf = self.fill_buf()?;
1037
1038 // size of buf in channel-independent samples
1039 match buf[0].len() {
1040 0 => {
1041 // read beyond end of stream
1042 return Err(Error::InvalidSeek);
1043 }
1044 buf_samples => {
1045 // amount of channel-independent samples to consume
1046 let to_consume = buf_samples.min((sample - pos).try_into().unwrap());
1047
1048 // mark samples in buffer as consumed
1049 self.consume(to_consume);
1050
1051 // advance current actual position
1052 pos += to_consume as u64;
1053 }
1054 }
1055 }
1056
1057 Ok(())
1058 }
1059}
1060
1061impl<R: std::io::Read> Metadata for FlacChannelReader<R> {
1062 #[inline]
1063 fn channel_count(&self) -> u8 {
1064 self.decoder.channel_count().get()
1065 }
1066
1067 #[inline]
1068 fn channel_mask(&self) -> ChannelMask {
1069 self.decoder.channel_mask()
1070 }
1071
1072 #[inline]
1073 fn sample_rate(&self) -> u32 {
1074 self.decoder.sample_rate()
1075 }
1076
1077 #[inline]
1078 fn bits_per_sample(&self) -> u32 {
1079 self.decoder.bits_per_sample()
1080 }
1081
1082 #[inline]
1083 fn total_samples(&self) -> Option<u64> {
1084 self.decoder.total_samples().map(|s| s.get())
1085 }
1086
1087 #[inline]
1088 fn md5(&self) -> Option<&[u8; 16]> {
1089 self.decoder.md5()
1090 }
1091}
1092
1093/// A FLAC reader which operates on streamed input
1094///
1095/// Streamed FLAC files are simply a collection of raw
1096/// FLAC frames with no accompanying metadata,
1097/// like might be delivered over a multicast stream.
1098///
1099/// Because this reader needs to scan the stream for
1100/// valid frame sync codes before playback,
1101/// it requires [`std::io::BufRead`] instead of [`std::io::Read`].
1102///
1103/// # Example
1104///
1105/// ```
1106/// use flac_codec::{
1107/// decode::{FlacStreamReader, FrameBuf},
1108/// encode::{FlacStreamWriter, Options},
1109/// };
1110/// use std::io::{Cursor, Seek};
1111/// use std::num::NonZero;
1112/// use bitstream_io::SignedBitCount;
1113///
1114/// let mut flac = Cursor::new(vec![]);
1115///
1116/// let samples = (0..100).collect::<Vec<i32>>();
1117///
1118/// let mut w = FlacStreamWriter::new(&mut flac, Options::default());
1119///
1120/// // write a single FLAC frame with some samples
1121/// w.write(
1122/// 44100, // sample rate
1123/// 1, // channels
1124/// 16, // bits-per-sample
1125/// &samples,
1126/// ).unwrap();
1127///
1128/// flac.rewind().unwrap();
1129///
1130/// let mut r = FlacStreamReader::new(&mut flac);
1131///
1132/// // read a single FLAC frame with some samples
1133/// assert_eq!(
1134/// r.read().unwrap(),
1135/// FrameBuf {
1136/// samples: &samples,
1137/// sample_rate: 44100,
1138/// channels: 1,
1139/// bits_per_sample: 16,
1140/// },
1141/// );
1142/// ```
1143pub struct FlacStreamReader<R> {
1144 // the wrapped reader
1145 reader: R,
1146 // raw decoded frame samples
1147 buf: Frame,
1148 // interlaced frame samples
1149 samples: Vec<i32>,
1150}
1151
1152impl<R: std::io::BufRead> FlacStreamReader<R> {
1153 /// Opens new FLAC stream reader which wraps the given reader
1154 #[inline]
1155 pub fn new(reader: R) -> Self {
1156 Self {
1157 reader,
1158 buf: Frame::default(),
1159 samples: Vec::default(),
1160 }
1161 }
1162
1163 /// Returns the next decoded FLAC frame and its parameters
1164 ///
1165 /// # Errors
1166 ///
1167 /// Returns an I/O error from the stream or if any
1168 /// other error occurs when reading the file.
1169 pub fn read(&mut self) -> Result<FrameBuf<'_>, Error> {
1170 use crate::crc::{Checksum, Crc16, CrcReader};
1171 use crate::stream::FrameHeader;
1172 use bitstream_io::{BigEndian, BitReader};
1173 use std::io::Read;
1174
1175 // Finding the next frame header in a BufRead is
1176 // tougher than it seems because fill_buf might
1177 // slice a frame sync code in half, which needs
1178 // to be accounted for.
1179
1180 let (header, mut crc16_reader) = loop {
1181 // scan for the first byte of the frame sync
1182 self.reader.skip_until(0b11111111)?;
1183
1184 // either gotten the first half of the frame sync,
1185 // or have reached EOF
1186
1187 // check that the next byte is the other half of a frame sync
1188 match self.reader.fill_buf() {
1189 Ok([]) => {
1190 return Err(std::io::Error::new(
1191 std::io::ErrorKind::UnexpectedEof,
1192 "eof looking for frame sync",
1193 )
1194 .into());
1195 }
1196 Ok([byte, ..]) if byte >> 1 == 0b1111100 => {
1197 // got a whole frame sync
1198 // so try to parse a whole frame header
1199 let mut crc_reader: CrcReader<_, Crc16> = CrcReader::new(
1200 std::slice::from_ref(&0b11111111).chain(self.reader.by_ref()),
1201 );
1202
1203 if let Ok(header) = FrameHeader::read_subset(&mut crc_reader) {
1204 break (header, crc_reader);
1205 }
1206 }
1207 Ok(_) => continue,
1208 // didn't get the other half of frame sync,
1209 // so continue without consuming anything
1210 Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
1211 Err(e) => return Err(e.into()),
1212 }
1213 };
1214
1215 read_subframes(
1216 BitReader::endian(crc16_reader.by_ref(), BigEndian),
1217 &header,
1218 &mut self.buf,
1219 )?;
1220
1221 if crc16_reader.into_checksum().valid() {
1222 self.samples.clear();
1223 self.samples.extend(self.buf.iter());
1224
1225 Ok(FrameBuf {
1226 samples: self.samples.as_slice(),
1227 sample_rate: header.sample_rate.into(),
1228 channels: header.channel_assignment.count(),
1229 bits_per_sample: header.bits_per_sample.into(),
1230 })
1231 } else {
1232 Err(Error::Crc16Mismatch)
1233 }
1234 }
1235}
1236
1237/// A buffer of samples read from a [`FlacStreamReader`]
1238///
1239/// In a conventional FLAC reader, the stream's metadata
1240/// is known in advance from the required STREAMINFO metadata block
1241/// and is an error for it to change mid-file.
1242///
1243/// In a streamed reader, that metadata isn't known in advance
1244/// and can change from frame to frame. This buffer contains
1245/// all the metadata fields in the frame for decoding/playback.
1246#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1247pub struct FrameBuf<'s> {
1248 /// Decoded samples
1249 ///
1250 /// Samples are interleaved by channel, like:
1251 /// [left₀ , right₀ , left₁ , right₁ , left₂ , right₂ , …]
1252 pub samples: &'s [i32],
1253
1254 /// The sample rate, in Hz
1255 pub sample_rate: u32,
1256
1257 /// Channel count, from 1 to 8
1258 pub channels: u8,
1259
1260 /// Bits-per-sample, from 4 to 32
1261 pub bits_per_sample: u32,
1262}
1263
1264/// The results of FLAC file verification
1265#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
1266pub enum Verified {
1267 /// FLAC file has MD5 hash and decoded contents match that hash
1268 MD5Match,
1269 /// FLAC file has MD5 hash, but decoded contents do not match
1270 MD5Mismatch,
1271 /// FLAC file has no MD5 hash, but decodes successfully
1272 NoMD5,
1273}
1274
1275/// Verifies FLAC file for correctness
1276pub fn verify<P: AsRef<Path>>(p: P) -> Result<Verified, Error> {
1277 File::open(p.as_ref())
1278 .map_err(Error::Io)
1279 .and_then(|r| verify_reader(BufReader::new(r)))
1280}
1281
1282/// Verifies FLAC stream for correctness
1283///
1284/// The stream must be set to the start of the FLAC data
1285pub fn verify_reader<R: std::io::Read>(r: R) -> Result<Verified, Error> {
1286 use crate::byteorder::LittleEndian;
1287
1288 let mut r = FlacByteReader::endian(r, LittleEndian)?;
1289 match r.md5().cloned() {
1290 Some(flac_md5) => {
1291 let mut output_md5 = md5::Context::new();
1292 std::io::copy(&mut r, &mut output_md5)?;
1293 Ok(if flac_md5 == output_md5.compute().0 {
1294 Verified::MD5Match
1295 } else {
1296 Verified::MD5Mismatch
1297 })
1298 }
1299 None => std::io::copy(&mut r, &mut std::io::sink())
1300 .map(|_| Verified::NoMD5)
1301 .map_err(Error::Io),
1302 }
1303}
1304
1305/// A FLAC decoder
1306#[derive(Clone)]
1307struct Decoder<R> {
1308 reader: R,
1309 // all metadata blocks
1310 blocks: BlockList,
1311 // // the size of everything before the first frame, in bytes
1312 // frames_start: u64,
1313 // the current sample, in channel-independent samples
1314 current_sample: u64,
1315 // raw decoded frame samples
1316 buf: Frame,
1317}
1318
1319impl<R: std::io::Read> Decoder<R> {
1320 /// Builds a new FLAC decoder from the given stream
1321 ///
1322 /// This assumes the stream is positioned at the start
1323 /// of the file.
1324 ///
1325 /// # Errors
1326 ///
1327 /// Returns an error of the initial FLAC metadata
1328 /// is invalid or an I/O error occurs reading
1329 /// the initial metadata.
1330 fn new(reader: R, blocks: BlockList) -> Self {
1331 Self {
1332 reader,
1333 blocks,
1334 current_sample: 0,
1335 buf: Frame::default(),
1336 }
1337 }
1338
1339 /// Returns channel count
1340 ///
1341 /// From 1 to 8
1342 fn channel_count(&self) -> NonZero<u8> {
1343 self.blocks.streaminfo().channels
1344 }
1345
1346 fn channel_mask(&self) -> ChannelMask {
1347 self.blocks.channel_mask()
1348 }
1349
1350 /// Returns sample rate, in Hz
1351 fn sample_rate(&self) -> u32 {
1352 self.blocks.streaminfo().sample_rate
1353 }
1354
1355 /// Returns decoder's bits-per-sample
1356 ///
1357 /// From 1 to 32
1358 fn bits_per_sample(&self) -> u32 {
1359 self.blocks.streaminfo().bits_per_sample.into()
1360 }
1361
1362 /// Returns total number of channel-independent samples, if known
1363 fn total_samples(&self) -> Option<NonZero<u64>> {
1364 self.blocks.streaminfo().total_samples
1365 }
1366
1367 /// Returns MD5 of entire stream, if known
1368 fn md5(&self) -> Option<&[u8; 16]> {
1369 self.blocks.streaminfo().md5.as_ref()
1370 }
1371
1372 /// Returns FLAC metadata
1373 fn metadata(&self) -> &BlockList {
1374 &self.blocks
1375 }
1376
1377 /// Returns decoded frame, if any.
1378 ///
1379 /// # Errors
1380 ///
1381 /// Returns any decoding error from the stream.
1382 fn read_frame(&mut self) -> Result<Option<&Frame>, Error> {
1383 use crate::crc::{Checksum, Crc16, CrcReader};
1384 use crate::stream::FrameHeader;
1385 use bitstream_io::{BigEndian, BitReader};
1386 use std::io::Read;
1387
1388 let mut crc16_reader: CrcReader<_, Crc16> = CrcReader::new(self.reader.by_ref());
1389
1390 let header = match self
1391 .blocks
1392 .streaminfo()
1393 .total_samples
1394 .map(|total| total.get() - self.current_sample)
1395 {
1396 Some(0) => return Ok(None),
1397 Some(remaining) => FrameHeader::read(crc16_reader.by_ref(), self.blocks.streaminfo())
1398 .and_then(|header| {
1399 // only the last block in a stream may contain <= 14 samples
1400 let block_size = u16::from(header.block_size);
1401 (u64::from(block_size) == remaining || block_size > 14)
1402 .then_some(header)
1403 .ok_or(Error::ShortBlock)
1404 })?,
1405 // if total number of remaining samples isn't known,
1406 // treat an EOF error as the end of stream
1407 // (this is an uncommon case)
1408 None => match FrameHeader::read(crc16_reader.by_ref(), self.blocks.streaminfo()) {
1409 Ok(header) => header,
1410 Err(Error::Io(err)) if err.kind() == std::io::ErrorKind::UnexpectedEof => {
1411 return Ok(None);
1412 }
1413 Err(err) => return Err(err),
1414 },
1415 };
1416
1417 read_subframes(
1418 BitReader::endian(crc16_reader.by_ref(), BigEndian),
1419 &header,
1420 &mut self.buf,
1421 )?;
1422
1423 if !crc16_reader.into_checksum().valid() {
1424 return Err(Error::Crc16Mismatch);
1425 }
1426
1427 self.current_sample += u64::from(u16::from(header.block_size));
1428
1429 Ok(Some(&self.buf))
1430 }
1431}
1432
1433impl<R: std::io::Seek> Decoder<R> {
1434 /// Attempts to seek to desired sample number
1435 ///
1436 /// Sample number is indicated in channel-independent samples.
1437 ///
1438 /// Upon success, returns the actual sample number
1439 /// the stream is positioned to, in channel-independent samples,
1440 /// which may be less than the desired sample.
1441 ///
1442 /// # Errors
1443 ///
1444 /// Passes along an I/O error that occurs when seeking
1445 /// within the file.
1446 fn seek(&mut self, frames_start: u64, sample: u64) -> Result<u64, Error> {
1447 use crate::metadata::SeekPoint;
1448 use std::io::SeekFrom;
1449
1450 match self.blocks.get() {
1451 Some(SeekTable { points: seektable }) => {
1452 match seektable
1453 .iter()
1454 .filter(|point| {
1455 point
1456 .sample_offset()
1457 .map(|offset| offset <= sample)
1458 .unwrap_or(false)
1459 })
1460 .next_back()
1461 {
1462 Some(SeekPoint::Defined {
1463 sample_offset,
1464 byte_offset,
1465 ..
1466 }) => {
1467 assert!(*sample_offset <= sample);
1468 self.reader
1469 .seek(SeekFrom::Start(frames_start + byte_offset))?;
1470 self.current_sample = *sample_offset;
1471 Ok(*sample_offset)
1472 }
1473 _ => {
1474 // empty seektable so rewind to start of stream
1475 self.reader.seek(SeekFrom::Start(frames_start))?;
1476 self.current_sample = 0;
1477 Ok(0)
1478 }
1479 }
1480 }
1481 None => {
1482 // no seektable
1483 // all we can do is rewind data to start of stream
1484 self.reader.seek(SeekFrom::Start(frames_start))?;
1485 self.current_sample = 0;
1486 Ok(0)
1487 }
1488 }
1489 }
1490}
1491
1492fn read_subframes<R: BitRead>(
1493 mut reader: R,
1494 header: &crate::stream::FrameHeader,
1495 buf: &mut Frame,
1496) -> Result<(), Error> {
1497 use crate::stream::ChannelAssignment;
1498
1499 match header.channel_assignment {
1500 ChannelAssignment::Independent(total_channels) => {
1501 buf.resized_channels(
1502 header.bits_per_sample.into(),
1503 total_channels.into(),
1504 u16::from(header.block_size).into(),
1505 )
1506 .try_for_each(|channel| {
1507 read_subframe(&mut reader, header.bits_per_sample.into(), channel)
1508 })?;
1509 }
1510 ChannelAssignment::LeftSide => {
1511 let (left, side) = buf.resized_stereo(
1512 header.bits_per_sample.into(),
1513 u16::from(header.block_size).into(),
1514 );
1515
1516 read_subframe(&mut reader, header.bits_per_sample.into(), left)?;
1517
1518 match header.bits_per_sample.checked_add(1) {
1519 Some(side_bps) => {
1520 read_subframe(&mut reader, side_bps, side)?;
1521
1522 left.iter().zip(side.iter_mut()).for_each(|(left, side)| {
1523 *side = *left - *side;
1524 });
1525 }
1526 None => {
1527 // the very rare case of 32-bps streams
1528 // accompanied by side channels
1529 let mut side_i64 = vec![0; side.len()];
1530
1531 read_subframe::<33, R, i64>(
1532 &mut reader,
1533 SignedBitCount::from(header.bits_per_sample)
1534 .checked_add(1)
1535 .expect("excessive bps for substream"),
1536 &mut side_i64,
1537 )?;
1538
1539 left.iter().zip(side_i64).zip(side.iter_mut()).for_each(
1540 |((left, side_i64), side)| {
1541 *side = (*left as i64 - side_i64) as i32;
1542 },
1543 );
1544 }
1545 }
1546 }
1547 ChannelAssignment::SideRight => {
1548 let (side, right) = buf.resized_stereo(
1549 header.bits_per_sample.into(),
1550 u16::from(header.block_size).into(),
1551 );
1552
1553 match header.bits_per_sample.checked_add(1) {
1554 Some(side_bps) => {
1555 read_subframe(&mut reader, side_bps, side)?;
1556 read_subframe(&mut reader, header.bits_per_sample.into(), right)?;
1557
1558 side.iter_mut().zip(right.iter()).for_each(|(side, right)| {
1559 *side += *right;
1560 });
1561 }
1562 None => {
1563 // the very rare case of 32-bps streams
1564 // accompanied by side channels
1565 let mut side_i64 = vec![0; side.len()];
1566
1567 read_subframe::<33, R, i64>(
1568 &mut reader,
1569 SignedBitCount::from(header.bits_per_sample)
1570 .checked_add(1)
1571 .expect("excessive bps for substream"),
1572 &mut side_i64,
1573 )?;
1574 read_subframe(&mut reader, header.bits_per_sample.into(), right)?;
1575
1576 side.iter_mut().zip(side_i64).zip(right.iter()).for_each(
1577 |((side, side_64), right)| {
1578 *side = (side_64 + *right as i64) as i32;
1579 },
1580 );
1581 }
1582 }
1583 }
1584 ChannelAssignment::MidSide => {
1585 let (mid, side) = buf.resized_stereo(
1586 header.bits_per_sample.into(),
1587 u16::from(header.block_size).into(),
1588 );
1589
1590 read_subframe(&mut reader, header.bits_per_sample.into(), mid)?;
1591
1592 match header.bits_per_sample.checked_add(1) {
1593 Some(side_bps) => {
1594 read_subframe(&mut reader, side_bps, side)?;
1595
1596 mid.iter_mut().zip(side.iter_mut()).for_each(|(mid, side)| {
1597 let sum = *mid * 2 + side.abs() % 2;
1598 *mid = (sum + *side) >> 1;
1599 *side = (sum - *side) >> 1;
1600 });
1601 }
1602 None => {
1603 // the very rare case of 32-bps streams
1604 // accompanied by side channels
1605 let mut side_i64 = vec![0; side.len()];
1606
1607 read_subframe::<33, R, i64>(
1608 &mut reader,
1609 SignedBitCount::from(header.bits_per_sample)
1610 .checked_add(1)
1611 .expect("excessive bps for substream"),
1612 &mut side_i64,
1613 )?;
1614
1615 mid.iter_mut().zip(side.iter_mut()).zip(side_i64).for_each(
1616 |((mid, side), side_i64)| {
1617 let sum = *mid as i64 * 2 + (side_i64.abs() % 2);
1618 *mid = ((sum + side_i64) >> 1) as i32;
1619 *side = ((sum - side_i64) >> 1) as i32;
1620 },
1621 );
1622 }
1623 }
1624 }
1625 }
1626
1627 reader.byte_align();
1628 reader.skip(16)?; // CRC-16 checksum
1629
1630 Ok(())
1631}
1632
1633fn read_subframe<const MAX: u32, R: BitRead, I: SignedInteger>(
1634 reader: &mut R,
1635 bits_per_sample: SignedBitCount<MAX>,
1636 channel: &mut [I],
1637) -> Result<(), Error> {
1638 use crate::stream::{SubframeHeader, SubframeHeaderType};
1639
1640 let header = reader.parse::<SubframeHeader>()?;
1641
1642 let effective_bps = bits_per_sample
1643 .checked_sub::<MAX>(header.wasted_bps)
1644 .ok_or(Error::ExcessiveWastedBits)?;
1645
1646 match header.type_ {
1647 SubframeHeaderType::Constant => {
1648 channel.fill(reader.read_signed_counted(effective_bps)?);
1649 }
1650 SubframeHeaderType::Verbatim => {
1651 channel.iter_mut().try_for_each(|i| {
1652 *i = reader.read_signed_counted(effective_bps)?;
1653 Ok::<(), Error>(())
1654 })?;
1655 }
1656 SubframeHeaderType::Fixed { order } => {
1657 read_fixed_subframe(
1658 reader,
1659 effective_bps,
1660 SubframeHeaderType::FIXED_COEFFS[order as usize],
1661 channel,
1662 )?;
1663 }
1664 SubframeHeaderType::Lpc { order } => {
1665 read_lpc_subframe(reader, effective_bps, order, channel)?;
1666 }
1667 }
1668
1669 if header.wasted_bps > 0 {
1670 channel.iter_mut().for_each(|i| *i <<= header.wasted_bps);
1671 }
1672
1673 Ok(())
1674}
1675
1676fn read_fixed_subframe<const MAX: u32, R: BitRead, I: SignedInteger>(
1677 reader: &mut R,
1678 bits_per_sample: SignedBitCount<MAX>,
1679 coefficients: &[i64],
1680 channel: &mut [I],
1681) -> Result<(), Error> {
1682 let (warm_up, residuals) = channel
1683 .split_at_mut_checked(coefficients.len())
1684 .ok_or(Error::InvalidFixedOrder)?;
1685
1686 warm_up.iter_mut().try_for_each(|s| {
1687 *s = reader.read_signed_counted(bits_per_sample)?;
1688 Ok::<_, std::io::Error>(())
1689 })?;
1690
1691 read_residuals(reader, coefficients.len(), residuals)?;
1692 predict(coefficients, 0, channel);
1693 Ok(())
1694}
1695
1696fn read_lpc_subframe<const MAX: u32, R: BitRead, I: SignedInteger>(
1697 reader: &mut R,
1698 bits_per_sample: SignedBitCount<MAX>,
1699 predictor_order: NonZero<u8>,
1700 channel: &mut [I],
1701) -> Result<(), Error> {
1702 let mut coefficients: [i64; 32] = [0; 32];
1703
1704 let (warm_up, residuals) = channel
1705 .split_at_mut_checked(predictor_order.get().into())
1706 .ok_or(Error::InvalidLpcOrder)?;
1707
1708 warm_up.iter_mut().try_for_each(|s| {
1709 *s = reader.read_signed_counted(bits_per_sample)?;
1710 Ok::<_, std::io::Error>(())
1711 })?;
1712
1713 let qlp_precision: SignedBitCount<15> = reader
1714 .read_count::<0b1111>()?
1715 .checked_add(1)
1716 .and_then(|c| c.signed_count())
1717 .ok_or(Error::InvalidQlpPrecision)?;
1718
1719 let qlp_shift: u32 = reader
1720 .read::<5, i32>()?
1721 .try_into()
1722 .map_err(|_| Error::NegativeLpcShift)?;
1723
1724 let coefficients = &mut coefficients[0..predictor_order.get().into()];
1725
1726 coefficients.iter_mut().try_for_each(|c| {
1727 *c = reader.read_signed_counted(qlp_precision)?;
1728 Ok::<_, std::io::Error>(())
1729 })?;
1730
1731 read_residuals(reader, coefficients.len(), residuals)?;
1732 predict(coefficients, qlp_shift, channel);
1733 Ok(())
1734}
1735
1736fn predict<I: SignedInteger>(coefficients: &[i64], qlp_shift: u32, channel: &mut [I]) {
1737 for split in coefficients.len()..channel.len() {
1738 let (predicted, residuals) = channel.split_at_mut(split);
1739
1740 residuals[0] += I::from_i64(
1741 predicted
1742 .iter()
1743 .rev()
1744 .zip(coefficients)
1745 .map(|(x, y)| (*x).into() * y)
1746 .sum::<i64>()
1747 >> qlp_shift,
1748 );
1749 }
1750}
1751
1752#[test]
1753fn verify_prediction() {
1754 let mut coefficients = [-75, 166, 121, -269, -75, -399, 1042];
1755 let mut buffer = [
1756 -796, -547, -285, -32, 199, 443, 670, -2, -23, 14, 6, 3, -4, 12, -2, 10,
1757 ];
1758 coefficients.reverse();
1759 predict(&coefficients, 9, &mut buffer);
1760 assert_eq!(
1761 &buffer,
1762 &[
1763 -796, -547, -285, -32, 199, 443, 670, 875, 1046, 1208, 1343, 1454, 1541, 1616, 1663,
1764 1701
1765 ]
1766 );
1767
1768 let mut coefficients = [119, -255, 555, -836, 879, -1199, 1757];
1769 let mut buffer = [-21363, -21951, -22649, -24364, -27297, -26870, -30017, 3157];
1770 coefficients.reverse();
1771 predict(&coefficients, 10, &mut buffer);
1772 assert_eq!(
1773 &buffer,
1774 &[
1775 -21363, -21951, -22649, -24364, -27297, -26870, -30017, -29718
1776 ]
1777 );
1778
1779 let mut coefficients = [
1780 709, -2589, 4600, -4612, 1350, 4220, -9743, 12671, -12129, 8586, -3775, -645, 3904, -5543,
1781 4373, 182, -6873, 13265, -15417, 11550,
1782 ];
1783 let mut buffer = [
1784 213238, 210830, 234493, 209515, 235139, 201836, 208151, 186277, 157720, 148176, 115037,
1785 104836, 60794, 54523, 412, 17943, -6025, -3713, 8373, 11764, 30094,
1786 ];
1787 coefficients.reverse();
1788 predict(&coefficients, 12, &mut buffer);
1789 assert_eq!(
1790 &buffer,
1791 &[
1792 213238, 210830, 234493, 209515, 235139, 201836, 208151, 186277, 157720, 148176, 115037,
1793 104836, 60794, 54523, 412, 17943, -6025, -3713, 8373, 11764, 33931,
1794 ]
1795 );
1796}
1797
1798fn read_residuals<R: BitRead, I: SignedInteger>(
1799 reader: &mut R,
1800 predictor_order: usize,
1801 residuals: &mut [I],
1802) -> Result<(), Error> {
1803 fn read_block<const RICE_MAX: u32, R: BitRead, I: SignedInteger>(
1804 reader: &mut R,
1805 predictor_order: usize,
1806 mut residuals: &mut [I],
1807 ) -> Result<(), Error> {
1808 use crate::stream::ResidualPartitionHeader;
1809
1810 let block_size = predictor_order + residuals.len();
1811 let partition_order = reader.read::<4, u32>()?;
1812 let partition_count = 1 << partition_order;
1813
1814 for p in 0..partition_count {
1815 let (partition, next) = residuals
1816 .split_at_mut_checked(
1817 (block_size / partition_count)
1818 .checked_sub(if p == 0 { predictor_order } else { 0 })
1819 .ok_or(Error::InvalidPartitionOrder)?,
1820 )
1821 .ok_or(Error::InvalidPartitionOrder)?;
1822
1823 match reader.parse()? {
1824 ResidualPartitionHeader::Standard { rice } => {
1825 partition.iter_mut().try_for_each(|s| {
1826 let msb = reader.read_unary::<1>()?;
1827 let lsb = reader.read_counted::<RICE_MAX, u32>(rice)?;
1828 let unsigned = (msb << u32::from(rice)) | lsb;
1829 *s = if (unsigned & 1) == 1 {
1830 -(I::from_u32(unsigned >> 1)) - I::ONE
1831 } else {
1832 I::from_u32(unsigned >> 1)
1833 };
1834 Ok::<(), std::io::Error>(())
1835 })?;
1836 }
1837 ResidualPartitionHeader::Escaped { escape_size } => {
1838 partition.iter_mut().try_for_each(|s| {
1839 *s = reader.read_signed_counted(escape_size)?;
1840 Ok::<(), std::io::Error>(())
1841 })?;
1842 }
1843 ResidualPartitionHeader::Constant => {
1844 partition.fill(I::ZERO);
1845 }
1846 }
1847
1848 residuals = next;
1849 }
1850
1851 Ok(())
1852 }
1853
1854 match reader.read::<2, u8>()? {
1855 0 => read_block::<0b1111, R, I>(reader, predictor_order, residuals),
1856 1 => read_block::<0b11111, R, I>(reader, predictor_order, residuals),
1857 _ => Err(Error::InvalidCodingMethod),
1858 }
1859}