diff --git a/src/fmt.rs b/src/fmt.rs index 2c812c6..772adef 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -23,16 +23,16 @@ pub struct ADMAudioID { /// Describes a single channel in a WAV file. pub struct ChannelDescriptor { /// Index, the offset of this channel's samples in one frame. - index: u16, + pub index: u16, /// Channel assignment /// /// This is either implied (in the case of mono or stereo wave files) or /// explicitly given in `WaveFormatExtentended` for files with more tracks. - speaker: ChannelMask, + pub speaker: ChannelMask, /// ADM audioTrackUIDs - adm_track_audio_ids: Vec, + pub adm_track_audio_ids: Vec, } diff --git a/src/lib.rs b/src/lib.rs index 2514914..19fbc8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,6 +121,6 @@ mod wavewriter; pub use errors::Error; pub use wavereader::{WaveReader}; pub use bext::Bext; -pub use fmt::{WaveFmt, WaveFmtExtended, ChannelDescriptor}; +pub use fmt::{WaveFmt, WaveFmtExtended, ChannelDescriptor, ChannelMask}; pub use common_format::CommonFormat; pub use audio_frame_reader::AudioFrameReader; \ No newline at end of file diff --git a/src/wavereader.rs b/src/wavereader.rs index 49e77e0..90298ac 100644 --- a/src/wavereader.rs +++ b/src/wavereader.rs @@ -5,7 +5,7 @@ use super::parser::Parser; use super::fourcc::{FourCC, FMT__SIG,DATA_SIG, BEXT_SIG, JUNK_SIG, FLLR_SIG}; use super::errors::Error as ParserError; use super::raw_chunk_reader::RawChunkReader; -use super::fmt::WaveFmt; +use super::fmt::{WaveFmt, ChannelDescriptor, ChannelMask}; use super::bext::Bext; use super::audio_frame_reader::AudioFrameReader; use super::chunks::ReadBWaveChunks; @@ -132,6 +132,37 @@ impl WaveReader { self.chunk_reader(BEXT_SIG, 0)?.read_bext() } + /// Describe the channels in this file + /// + /// Returns a vector of channel descriptors, one for each channel + /// + /// ```rust + /// # use bwavfile::WaveReader; + /// # use bwavfile::ChannelMask; + /// let mut f = WaveReader::open("tests/media/pt_24bit_51.wav").unwrap(); + /// + /// let chans = f.channels().unwrap(); + /// assert_eq!(chans[0].index, 0); + /// assert_eq!(chans[0].speaker, ChannelMask::FrontLeft); + /// assert_eq!(chans[3].index, 3); + /// assert_eq!(chans[3].speaker, ChannelMask::LowFrequency); + /// assert_eq!(chans[4].speaker, ChannelMask::BackLeft); + /// ``` + pub fn channels(&mut self) -> Result, ParserError> { + + let format = self.format()?; + let channel_masks : Vec = match (format.channel_count, format.extended_format) { + (1,_) => vec![ChannelMask::FrontCenter], + (2,_) => vec![ChannelMask::FrontLeft, ChannelMask::FrontRight], + (n,Some(x)) => ChannelMask::channels(x.channel_mask, n), + (n,_) => vec![ChannelMask::DirectOut; n as usize] + }; + + Ok( (0..format.channel_count).zip(channel_masks) + .map(|(i,m)| ChannelDescriptor { index: i, speaker:m, adm_track_audio_ids: vec![] } ) + .collect() ) + } + /** * Validate file is readable. *