Struct bwavfile::WaveReader

source ·
pub struct WaveReader<R: Read + Seek> {
    pub inner: R,
}
Expand description

Wave, Broadcast-WAV and RF64/BW64 parser/reader.

use bwavfile::WaveReader;
let mut r = WaveReader::open("tests/media/ff_silence.wav").unwrap();

let format = r.format().unwrap();
assert_eq!(format.sample_rate, 44100);
assert_eq!(format.channel_count, 1);

let mut frame_reader = r.audio_frame_reader().unwrap();
let mut buffer = format.create_frame_buffer::<i32>(1);

let read = frame_reader.read_frames(&mut buffer).unwrap();

assert_eq!(buffer, [0i32]);
assert_eq!(read, 1);

Resources

Implementation of Wave Files

Implementation of Broadcast Wave Files

Implementation of 64-bit Wave Files

  • ITU-R 2088 (October 2019), “Long-form file format for the international exchange of audio programme materials with metadata”
  • EBU Tech 3306v1 (July 2009), “MBWF / RF64: An extended File Format for Audio”
    • No longer in force, however long-established.

Fields§

§inner: R

Implementations§

source§

impl WaveReader<BufReader<File>>

source

pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, ParserError>

source§

impl WaveReader<File>

source

pub fn open_unbuffered<P: AsRef<Path>>(path: P) -> Result<Self, ParserError>

Open a file for reading with unbuffered IO.

A convenience that opens path and calls Self::new()

source§

impl<R: Read + Seek> WaveReader<R>

source

pub fn new(inner: R) -> Result<Self, ParserError>

Wrap a Read struct in a new WaveReader.

This is the primary entry point into the WaveReader interface. The stream passed as inner must be at the beginning of the header of the WAVE data. For a .wav file, this means it must be at the start of the file.

This function does a minimal validation on the provided stream and will return an Err(errors::Error) immediately if there is a structural inconsistency that makes the stream unreadable or if it’s missing essential components that make interpreting the audio data impossible.

use std::fs::File;
use std::io::{Error,ErrorKind};
use bwavfile::{WaveReader, Error as WavError};

let f = File::open("tests/media/error.wav").unwrap();

let reader = WaveReader::new(f);

match reader {
     Ok(_) => panic!("error.wav should not be openable"),
     Err( WavError::IOError( e ) ) => {
         assert_eq!(e.kind(), ErrorKind::UnexpectedEof)
     }
     Err(e) => panic!("Unexpected error was returned {:?}", e)
}
source

pub fn into_inner(self) -> R

Unwrap the inner reader.

source

pub fn audio_frame_reader(self) -> Result<AudioFrameReader<R>, ParserError>

Create an AudioFrameReader for reading each audio frame and consume the WaveReader.

source

pub fn frame_length(&mut self) -> Result<u64, ParserError>

The count of audio frames in the file.

source

pub fn format(&mut self) -> Result<WaveFmt, ParserError>

Sample and frame format of this wave file.

source

pub fn broadcast_extension(&mut self) -> Result<Option<Bext>, ParserError>

The Broadcast-WAV metadata record for this file, if present.

source

pub fn channels(&mut self) -> Result<Vec<ChannelDescriptor>, ParserError>

Describe the channels in this file

Returns a vector of channel descriptors, one for each channel

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);
source

pub fn cue_points(&mut self) -> Result<Vec<Cue>, ParserError>

Read cue points.

use bwavfile::WaveReader;
use bwavfile::Cue;

let mut f = WaveReader::open("tests/media/izotope_test.wav").unwrap();
let cue_points = f.cue_points().unwrap();

assert_eq!(cue_points.len(), 3);
assert_eq!(cue_points[0].frame, 12532);
assert_eq!(cue_points[0].length, None);
assert_eq!(cue_points[0].label, Some(String::from("Marker 1")));
assert_eq!(cue_points[0].note, Some(String::from("Marker 1 Comment")));

assert_eq!(cue_points[1].frame, 20997);
assert_eq!(cue_points[1].length, None);
assert_eq!(cue_points[1].label, Some(String::from("Marker 2")));
assert_eq!(cue_points[1].note, Some(String::from("Marker 2 Comment")));

assert_eq!(cue_points[2].frame, 26711);
assert_eq!(cue_points[2].length, Some(6465));
assert_eq!(cue_points[2].label, Some(String::from("Timed Region")));
assert_eq!(cue_points[2].note, Some(String::from("Region Comment")));
source

pub fn read_ixml(&mut self, buffer: &mut Vec<u8>) -> Result<usize, ParserError>

Read iXML data.

The iXML data will be appended to buffer. If there are no iXML metadata present in the file, Ok(0) will be returned.

source

pub fn read_axml(&mut self, buffer: &mut Vec<u8>) -> Result<usize, ParserError>

Read AXML data.

The axml data will be appended to buffer. By convention this will generally be ADM metadata.

If there are no axml metadata present in the file, Ok(0) will be returned

source

pub fn validate_readable(&mut self) -> Result<(), ParserError>

Validate file is readable.

Ok(()) if the source meets the minimum standard of readability by a permissive client:

  • fmt chunk and data chunk are present
  • fmt chunk appears before data chunk
source

pub fn validate_minimal(&mut self) -> Result<(), ParserError>

Validate minimal WAVE file.

Ok(()) if the source is validate_readable() AND

  • Contains only a fmt chunk and data chunk, with no other chunks present
  • fmt chunk is exactly 16 bytes long and begins exactly at file offset 12
  • data content begins exactly at file offset 36
  • is not an RF64/BW64

Some clients require a WAVE file to only contain format and data without any other metadata and this function is provided to validate this condition.

Examples

let mut w = WaveReader::open("tests/media/ff_minimal.wav").unwrap();
w.validate_minimal().expect("Minimal wav did not validate not minimal!");

let mut x = WaveReader::open("tests/media/pt_24bit_51.wav").unwrap();
x.validate_minimal().expect_err("Complex WAV validated minimal!");
source

pub fn validate_broadcast_wave(&mut self) -> Result<(), ParserError>

Validate Broadcast-WAVE file format

Returns Ok(()) if validate_readable() and file contains a Broadcast-WAV metadata record (a bext chunk).

Examples

let mut w = WaveReader::open("tests/media/ff_bwav_stereo.wav").unwrap();
w.validate_broadcast_wave().expect("BWAVE file did not validate BWAVE");

let mut x = WaveReader::open("tests/media/pt_24bit.wav").unwrap();
x.validate_broadcast_wave().expect("BWAVE file did not validate BWAVE");

let mut y = WaveReader::open("tests/media/audacity_16bit.wav").unwrap();
y.validate_broadcast_wave().expect_err("Plain WAV file DID validate BWAVE");
source

pub fn validate_data_chunk_alignment(&mut self) -> Result<(), ParserError>

Verify data is aligned to a block boundary.

Returns Ok(()) if validate_readable() and the start of the data chunk’s content begins at 0x4000.

source

pub fn validate_prepared_for_append(&mut self) -> Result<(), ParserError>

Verify audio data can be appended immediately to this file.

Returns Ok(()) if:

  • validate_readable()
  • there is a JUNK or FLLR immediately at the beginning of the chunk list adequately large enough to be overwritten by a ds64 (92 bytes)
  • data is the final chunk

Trait Implementations§

source§

impl<R: Debug + Read + Seek> Debug for WaveReader<R>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<R> RefUnwindSafe for WaveReader<R>where R: RefUnwindSafe,

§

impl<R> Send for WaveReader<R>where R: Send,

§

impl<R> Sync for WaveReader<R>where R: Sync,

§

impl<R> Unpin for WaveReader<R>where R: Unpin,

§

impl<R> UnwindSafe for WaveReader<R>where R: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<S> FromSample<S> for S

source§

fn from_sample_(s: S) -> S

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> ToSample<U> for Twhere U: FromSample<T>,

source§

fn to_sample_(self) -> U

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<S, T> Duplex<S> for Twhere T: FromSample<S> + ToSample<S>,