Comments and documentation

This commit is contained in:
Jamie Hardt
2020-11-22 23:32:25 -08:00
parent 0685e7baca
commit dea68662f8
3 changed files with 79 additions and 16 deletions

View File

@@ -7,7 +7,10 @@ use byteorder::ReadBytesExt;
use super::chunks::WaveFmt;
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)]
pub struct AudioFrameReader<R: Read + Seek> {
@@ -18,6 +21,13 @@ pub struct AudioFrameReader<R: Read + Seek> {
impl<R: Read + Seek> AudioFrameReader<R> {
/// 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 {
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 {}",
@@ -28,6 +38,8 @@ impl<R: Read + Seek> AudioFrameReader<R> {
}
/// Locate the read position to a different frame
///
/// Seeks within the audio stream.
pub fn locate(&mut self, to :u64) -> Result<u64,Error> {
let position = to * self.format.block_alignment as u64;
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
/// 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> {
assert!(buffer.len() as u16 == self.format.channel_count,
"read_integer_frame was called with a mis-sized buffer, expected {}, was {}",

View File

@@ -1,12 +1,49 @@
//
/*!
# bwavfile
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
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
@@ -15,9 +52,9 @@ status of this project at [Github][github].)
### Implementation of 64-bit Wave Files
- [ITU-R 2088][itu2088] (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][ebu3306v2] (June 2018).
- Presently in force, adopted by the EBU in [EBU Tech 3306v2][ebu3306v2] (June 2018).
- [EBU Tech 3306v1][ebu3306v1] (July 2009), "MBWF / RF64: An extended File Format for Audio"
- No longer in force, however long-established.
- No longer in force, however long-established.
### Implementation of Wave format `fmt` chunk

View File

@@ -5,12 +5,15 @@ use super::wavereader::{WaveReader};
use std::io::{Read,Seek};
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:
* 1. `fmt` chunk and `data` chunk are present
* 1. `fmt` chunk appears before `data` chunk
* - `fmt` chunk and `data` chunk are present
* - `fmt` chunk appears before `data` chunk
*/
pub fn validate_readable(&mut self) -> Result<(), ParserError> {
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
* - 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
* metadata and this function is provided to validate this condition.
*
* ### Examples
*
* ```
* # use bwavfile::WaveReader;
*
@@ -64,9 +69,11 @@ impl<R:Read + Seek> WaveReader<R> {
/**
* 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).
*
* ### Examples
*
* ```
* # 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.
*/
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()`
* - 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
*/
pub fn validate_prepared_for_append(&mut self) -> Result<(), ParserError> {