1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
//! An MP3 decoder implemented in pure Rust. //! //! Supports MPEG-1, MPEG-2, and MPEG-2.5 Layer III streams. //! Layers I and II are currently unsupported. //! //! # Example //! //! ``` //! let data = std::fs::read("tests/vectors/MonoCBR192.mp3").expect("Could not open file"); //! let (header, samples) = puremp3::read_mp3(&data[..]).expect("Invalid MP3"); //! for (left, right) in samples { //! // Operate on samples here //! } //! ``` mod decoder; mod error; mod huffman; mod requantize; mod stereo; mod synthesis; mod tables; mod types; pub use crate::error::{Error, Mp3Error}; pub use crate::types::{ BitRate, Channels, Emphasis, FrameHeader, MpegLayer, MpegVersion, SampleRate, }; use std::io::Read; /// Convenience method to decode an MP3. /// Returns the first frame header found in the MP3, and an `Iterator` that /// yields MP3 `Sample`s`. /// /// Each `Sample` represents one left and right sample at the sample rate of /// the MP3. Any invalid data is ignored. The iterator will provide `Sample`s /// until there is no more data, or an error occurs. /// /// If you need to handle errors or changes in the format mid-stream, use /// `Mp3Decoder` driectly. pub fn read_mp3<R: Read>( reader: R, ) -> Result<(FrameHeader, impl Iterator<Item = (f32, f32)>), Error> { let mut decoder = Mp3Decoder::new(reader); let mut frame = decoder.next_frame()?; let header = frame.header.clone(); let mut i = 0; let iter = std::iter::from_fn(move || { if i >= frame.num_samples { i = 0; frame = if let Ok(frame) = decoder.next_frame() { frame } else { return None; } } let sample = (frame.samples[0][i], frame.samples[1][i]); i += 1; Some(sample) }); Ok((header, iter)) } /// Decodes MP3 streams. pub struct Mp3Decoder<R: Read> { reader: R, state: crate::types::DecoderState, } impl<R: Read> Mp3Decoder<R> { /// Creates a new `MP3Decoder` from the given reader. pub fn new(reader: R) -> Self { Self { reader, state: crate::types::DecoderState::new(), } } /// Gets a reference to the underlying reader. pub fn get_ref(&self) -> &R { &self.reader } /// Gets a mutable reference to the underlying reader. /// /// It is inadvisable to directly read from the underlying reader. pub fn get_mut(&mut self) -> &mut R { &mut self.reader } /// Unwraps the `Mp3Decoder`, returning the underlying reader. pub fn into_inner(self) -> R { self.reader } /// Returns an `Iterator` that yields MP3 `Frame`s. /// /// Each `Frame` contains header information and the decoded samples. /// Any invalid data is skipped. The iterator will provide `Frame`s until /// there is no more valid MP3 data or an error occurs. /// /// If you wish to inspect any errors, Use `next_frame` instead. pub fn frames(mut self) -> impl Iterator<Item = Frame> { std::iter::from_fn(move || self.next_frame().ok()) } /// Decodes the next MP3 `Frame` in the stream. /// /// Data is read until a valid `Frame` is found. Invalid data is skipped. /// Other errors are returned. pub fn next_frame(&mut self) -> Result<Frame, Error> { let header; loop { match decoder::read_frame_header(&mut self.reader) { Ok(frame_header) => { header = frame_header; break; } Err(Error::Mp3Error(Mp3Error::InvalidData(_))) => (), Err(e) => return Err(e), } } let (num_samples, samples) = decoder::process_frame(&mut self.state, &mut self.reader, &header)?; Ok(Frame { header, samples, num_samples, }) } } /// A frame of MP3 data. /// /// Each frame contains a header describing the format of the data, and the decoded /// samples. An MP3 frame contains either 576 or 1152 samples (depending on the /// format). pub struct Frame { /// The header of this MP3 frame. pub header: FrameHeader, /// The decoded MP3 samples for the left and right channels. /// Each sample is in the range of [-1.0, 1.0]. /// Only the first `num_samples` entries will contain valid data. /// For mono streams, the data will be duplicated to the left and right /// channels. pub samples: [[f32; 1152]; 2], /// The number of samples in the `samples` array. /// This will be either 576 or 1152 samples depending on the /// format of the MP3. pub num_samples: usize, }