mirror of
https://github.com/iluvcapra/bwavfile.git
synced 2026-01-02 18:00:44 +00:00
Comments and documentation
This commit is contained in:
@@ -7,7 +7,10 @@ use byteorder::ReadBytesExt;
|
|||||||
use super::chunks::WaveFmt;
|
use super::chunks::WaveFmt;
|
||||||
use super::errors::Error;
|
use super::errors::Error;
|
||||||
|
|
||||||
/// Read samples from a `WaveFileReader`
|
/// Read audio frames
|
||||||
|
///
|
||||||
|
/// The inner reader is interpreted as a raw audio data
|
||||||
|
/// bitstream having a format specified by `format`.
|
||||||
///
|
///
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AudioFrameReader<R: Read + Seek> {
|
pub struct AudioFrameReader<R: Read + Seek> {
|
||||||
@@ -18,6 +21,13 @@ pub struct AudioFrameReader<R: Read + Seek> {
|
|||||||
impl<R: Read + Seek> AudioFrameReader<R> {
|
impl<R: Read + Seek> AudioFrameReader<R> {
|
||||||
|
|
||||||
/// Create a new `AudioFrameReader`
|
/// Create a new `AudioFrameReader`
|
||||||
|
///
|
||||||
|
/// ### Panics
|
||||||
|
///
|
||||||
|
/// This method does a few sanity checks on the provided format
|
||||||
|
/// parameter to confirm the `block_alignment` law is fulfilled
|
||||||
|
/// and the format tag is readable by this implementation (only
|
||||||
|
/// format 0x01 is supported at this time.)
|
||||||
pub fn new(inner: R, format: WaveFmt) -> Self {
|
pub fn new(inner: R, format: WaveFmt) -> Self {
|
||||||
assert!(format.block_alignment * 8 == format.bits_per_sample * format.channel_count,
|
assert!(format.block_alignment * 8 == format.bits_per_sample * format.channel_count,
|
||||||
"Unable to read audio frames from packed formats: block alignment is {}, should be {}",
|
"Unable to read audio frames from packed formats: block alignment is {}, should be {}",
|
||||||
@@ -28,6 +38,8 @@ impl<R: Read + Seek> AudioFrameReader<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Locate the read position to a different frame
|
/// Locate the read position to a different frame
|
||||||
|
///
|
||||||
|
/// Seeks within the audio stream.
|
||||||
pub fn locate(&mut self, to :u64) -> Result<u64,Error> {
|
pub fn locate(&mut self, to :u64) -> Result<u64,Error> {
|
||||||
let position = to * self.format.block_alignment as u64;
|
let position = to * self.format.block_alignment as u64;
|
||||||
let seek_result = self.inner.seek(Start(position))?;
|
let seek_result = self.inner.seek(Start(position))?;
|
||||||
@@ -46,6 +58,11 @@ impl<R: Read + Seek> AudioFrameReader<R> {
|
|||||||
///
|
///
|
||||||
/// A single frame is read from the audio stream and the read location
|
/// A single frame is read from the audio stream and the read location
|
||||||
/// is advanced one frame.
|
/// is advanced one frame.
|
||||||
|
///
|
||||||
|
/// ### Panics
|
||||||
|
///
|
||||||
|
/// The `buffer` must have a number of elements equal to the number of
|
||||||
|
/// channels and this method will panic if this is not the case.
|
||||||
pub fn read_integer_frame(&mut self, buffer:&mut [i32]) -> Result<u64,Error> {
|
pub fn read_integer_frame(&mut self, buffer:&mut [i32]) -> Result<u64,Error> {
|
||||||
assert!(buffer.len() as u16 == self.format.channel_count,
|
assert!(buffer.len() as u16 == self.format.channel_count,
|
||||||
"read_integer_frame was called with a mis-sized buffer, expected {}, was {}",
|
"read_integer_frame was called with a mis-sized buffer, expected {}, was {}",
|
||||||
|
|||||||
43
src/lib.rs
43
src/lib.rs
@@ -1,12 +1,49 @@
|
|||||||
//
|
|
||||||
/*!
|
/*!
|
||||||
# bwavfile
|
# bwavfile
|
||||||
|
|
||||||
Rust Wave File Reader/Writer with Broadcast-WAV, MBWF and RF64 Support
|
Rust Wave File Reader/Writer with Broadcast-WAV, MBWF and RF64 Support
|
||||||
|
|
||||||
(Note: This crate is still in an alpha or pre-alpha stage of development. Reading of
|
__(Note: This crate is still in an alpha or pre-alpha stage of development. Reading of
|
||||||
files works however the interfaces may change significantly. Stay up-to-date on the
|
files works however the interfaces may change significantly. Stay up-to-date on the
|
||||||
status of this project at [Github][github].)
|
status of this project at [Github][github].)__
|
||||||
|
|
||||||
|
## Objectives and Roadmap
|
||||||
|
|
||||||
|
This package aims to support read and writing any kind of WAV file you are likely
|
||||||
|
to encounter in a professional audio, motion picture production, broadcast, or music
|
||||||
|
production.
|
||||||
|
|
||||||
|
Apps we test against:
|
||||||
|
- Avid Pro Tools
|
||||||
|
- FFMpeg
|
||||||
|
- Audacity
|
||||||
|
|
||||||
|
Wave features we want to support with maximum reliability and ease of use:
|
||||||
|
|
||||||
|
- Large file size, RF64 support
|
||||||
|
- Multichannel audio formats
|
||||||
|
- Embedded metadata
|
||||||
|
|
||||||
|
In addition to reading the audio, we want to support all of the different
|
||||||
|
metadata planes you are liable to need to use.
|
||||||
|
|
||||||
|
- Broadcast-WAV metadata (including the SMPTE UMID and EBU v2 extensions)
|
||||||
|
- iXML Production recorder metadata
|
||||||
|
- ADM XML (with associated `chna` mappings)
|
||||||
|
- Dolby metadata block
|
||||||
|
|
||||||
|
Things that are _not_ necessarily in the scope of this package:
|
||||||
|
|
||||||
|
- Broad codec support. There are a little more than one-hundred
|
||||||
|
[registered wave codecs][rfc3261], but because this library is targeting
|
||||||
|
professional formats being created today, we only plan on supporting
|
||||||
|
two of them: tag 0x0001 (Integer Linear PCM) and tag 0x0003 (IEEE Float
|
||||||
|
Linear PCM).
|
||||||
|
- Music library metadata. There are several packages that can read ID3
|
||||||
|
metadata and it's not particuarly common in wave files in any case. INFO
|
||||||
|
metadata is more common though in professional applications it tends not
|
||||||
|
to be used by many applications.
|
||||||
|
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ use super::wavereader::{WaveReader};
|
|||||||
|
|
||||||
use std::io::{Read,Seek};
|
use std::io::{Read,Seek};
|
||||||
|
|
||||||
|
|
||||||
impl<R:Read + Seek> WaveReader<R> {
|
impl<R:Read + Seek> WaveReader<R> {
|
||||||
/**
|
/**
|
||||||
* Returns without `Err` if the source meets the minimum standard of
|
* Validate file is readable.
|
||||||
|
*
|
||||||
|
* `Ok(())` if the source meets the minimum standard of
|
||||||
* readability by a permissive client:
|
* readability by a permissive client:
|
||||||
* 1. `fmt` chunk and `data` chunk are present
|
* - `fmt` chunk and `data` chunk are present
|
||||||
* 1. `fmt` chunk appears before `data` chunk
|
* - `fmt` chunk appears before `data` chunk
|
||||||
*/
|
*/
|
||||||
pub fn validate_readable(&mut self) -> Result<(), ParserError> {
|
pub fn validate_readable(&mut self) -> Result<(), ParserError> {
|
||||||
let (fmt_pos, _) = self.get_chunk_extent_at_index(FMT__SIG, 0)?;
|
let (fmt_pos, _) = self.get_chunk_extent_at_index(FMT__SIG, 0)?;
|
||||||
@@ -24,9 +27,9 @@ impl<R:Read + Seek> WaveReader<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate minimal WAVE file
|
* Validate minimal WAVE file.
|
||||||
*
|
*
|
||||||
* Returns without `Err` the source is `validate_readable` AND
|
* `Ok(())` if the source is `validate_readable()` AND
|
||||||
*
|
*
|
||||||
* - Contains _only_ a `fmt` chunk and `data` chunk, with no other chunks present
|
* - Contains _only_ a `fmt` chunk and `data` chunk, with no other chunks present
|
||||||
* - is not an RF64/BW64
|
* - is not an RF64/BW64
|
||||||
@@ -34,6 +37,8 @@ impl<R:Read + Seek> WaveReader<R> {
|
|||||||
* Some clients require a WAVE file to only contain format and data without any other
|
* 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.
|
* metadata and this function is provided to validate this condition.
|
||||||
*
|
*
|
||||||
|
* ### Examples
|
||||||
|
*
|
||||||
* ```
|
* ```
|
||||||
* # use bwavfile::WaveReader;
|
* # use bwavfile::WaveReader;
|
||||||
*
|
*
|
||||||
@@ -64,9 +69,11 @@ impl<R:Read + Seek> WaveReader<R> {
|
|||||||
/**
|
/**
|
||||||
* Validate Broadcast-WAVE file format
|
* Validate Broadcast-WAVE file format
|
||||||
*
|
*
|
||||||
* Returns without `Err` if `validate_readable()` and file contains a
|
* Returns `Ok(())` if `validate_readable()` and file contains a
|
||||||
* Broadcast-WAV metadata record (a `bext` chunk).
|
* Broadcast-WAV metadata record (a `bext` chunk).
|
||||||
*
|
*
|
||||||
|
* ### Examples
|
||||||
|
*
|
||||||
* ```
|
* ```
|
||||||
* # use bwavfile::WaveReader;
|
* # use bwavfile::WaveReader;
|
||||||
*
|
*
|
||||||
@@ -87,9 +94,9 @@ impl<R:Read + Seek> WaveReader<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify data is aligned to a block boundary
|
* Verify data is aligned to a block boundary.
|
||||||
*
|
*
|
||||||
* Returns without `Err` if `validate_readable()` and the start of the
|
* Returns `Ok(())` if `validate_readable()` and the start of the
|
||||||
* `data` chunk's content begins at 0x4000.
|
* `data` chunk's content begins at 0x4000.
|
||||||
*/
|
*/
|
||||||
pub fn validate_data_chunk_alignment(&mut self) -> Result<() , ParserError> {
|
pub fn validate_data_chunk_alignment(&mut self) -> Result<() , ParserError> {
|
||||||
@@ -103,10 +110,12 @@ impl<R:Read + Seek> WaveReader<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns without `Err` if:
|
* Verify audio data can be appended immediately to this file.
|
||||||
|
*
|
||||||
|
* Returns `Ok(())` if:
|
||||||
* - `validate_readable()`
|
* - `validate_readable()`
|
||||||
* - there is a `JUNK` or `FLLR` immediately at the beginning of the chunk
|
* - there is a `JUNK` or `FLLR` immediately at the beginning of the chunk
|
||||||
* list adequately large enough to be overwritten by a `ds64` (96 bytes)
|
* list adequately large enough to be overwritten by a `ds64` (92 bytes)
|
||||||
* - `data` is the final chunk
|
* - `data` is the final chunk
|
||||||
*/
|
*/
|
||||||
pub fn validate_prepared_for_append(&mut self) -> Result<(), ParserError> {
|
pub fn validate_prepared_for_append(&mut self) -> Result<(), ParserError> {
|
||||||
|
|||||||
Reference in New Issue
Block a user