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
- Peter Kabal, McGill University
- Multimedia Programming Interface and Data Specifications 1.0 (August 1991), IBM Corporation and Microsoft Corporation
Implementation of Broadcast Wave Files
- EBU Tech 3285 (May 2011), “Specification of the Broadcast Wave Format (BWF)”
- Supplement 1 (July 1997): MPEG Audio
- EBU Rec 68: Signal modulation and format constraints
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”
- Presently in force, adopted by the EBU in EBU Tech 3306v2 (June 2018).
- 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>>
impl WaveReader<BufReader<File>>
source§impl WaveReader<File>
impl WaveReader<File>
sourcepub fn open_unbuffered<P: AsRef<Path>>(path: P) -> Result<Self, ParserError>
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>
impl<R: Read + Seek> WaveReader<R>
sourcepub fn new(inner: R) -> Result<Self, ParserError>
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)
}
sourcepub fn into_inner(self) -> R
pub fn into_inner(self) -> R
Unwrap the inner reader.
sourcepub fn audio_frame_reader(self) -> Result<AudioFrameReader<R>, ParserError>
pub fn audio_frame_reader(self) -> Result<AudioFrameReader<R>, ParserError>
Create an AudioFrameReader
for reading each audio frame and consume the WaveReader
.
sourcepub fn frame_length(&mut self) -> Result<u64, ParserError>
pub fn frame_length(&mut self) -> Result<u64, ParserError>
The count of audio frames in the file.
sourcepub fn format(&mut self) -> Result<WaveFmt, ParserError>
pub fn format(&mut self) -> Result<WaveFmt, ParserError>
Sample and frame format of this wave file.
sourcepub fn broadcast_extension(&mut self) -> Result<Option<Bext>, ParserError>
pub fn broadcast_extension(&mut self) -> Result<Option<Bext>, ParserError>
The Broadcast-WAV metadata record for this file, if present.
sourcepub fn channels(&mut self) -> Result<Vec<ChannelDescriptor>, ParserError>
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);
sourcepub fn cue_points(&mut self) -> Result<Vec<Cue>, ParserError>
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")));
sourcepub fn read_ixml(&mut self, buffer: &mut Vec<u8>) -> Result<usize, ParserError>
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.
sourcepub fn read_axml(&mut self, buffer: &mut Vec<u8>) -> Result<usize, ParserError>
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
sourcepub fn validate_readable(&mut self) -> Result<(), ParserError>
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 anddata
chunk are presentfmt
chunk appears beforedata
chunk
sourcepub fn validate_minimal(&mut self) -> Result<(), ParserError>
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 anddata
chunk, with no other chunks present fmt
chunk is exactly 16 bytes long and begins exactly at file offset 12data
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!");
sourcepub fn validate_broadcast_wave(&mut self) -> Result<(), ParserError>
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");
sourcepub fn validate_data_chunk_alignment(&mut self) -> Result<(), ParserError>
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.
sourcepub fn validate_prepared_for_append(&mut self) -> Result<(), ParserError>
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
orFLLR
immediately at the beginning of the chunk list adequately large enough to be overwritten by ads64
(92 bytes) data
is the final chunk