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}