Expand description
§Wavers
WaveRs is a fast and lightweight library for reading and writing wav
files.
Currently, it supports reading and writing of i16
, i32
, f32
, and f64
audio samples.
Experimental support for i24
audio samples is also available. The i24
type supports conversion to and from the other sample types.
The i24
type supports Add, Sub, Mul, Div, Rem, Neg, BitXor, BitOr, BitAnd, Shl, Shr, Not, and their assignment counterparts.
Feedback and bugs welcome!
§Highlights
- Fast and lightweight
- Simple API, read a wav file with
read
and write a wav file withwrite
- Easy and efficient conversion between different types of audio samples.
- Support for the Extensible format.
- Increasing support for different chunks in the wav file.
- Support for the
ndarray
crate. - Support for iteration over the frames and channels of the wav file.
§Crate Status
- This crate is currently in development. Changes to the core API will either not happen or they will be kept to a minimum. Any planned additions to the API will be built on top of the existing API.
- Documentation is currently in progress, it is mostly complete but will be updated as necessary.
- The API is tested, but there can always be more tests.
- The crate has been benchmarked, but there can always be more benchmarks.
- Some examples of planned features:
- Investigate the performance of the
write
function. - Any suggestions or requests are welcome.
- Investigate the performance of the
§Examples
The following examples show how to read and write a wav file, as well as retrieving information from the header.
§Reading
use wavers::{Wav, read};
use std::path::Path;
fn main() {
let fp = "path/to/wav.wav";
// creates a Wav file struct, does not read the audio data. Just the header information.
let wav: Wav<i16> = Wav::from_path(fp).unwrap();
// or to read the audio data directly
let (samples, sample_rate): (Samples<i16>, i32) = read::<i16, _>(fp).unwrap();
// samples can be derefed to a slice of samples
let samples: &[i16] = &samples;
}
§Conversion
use wavers::{Wav, read, ConvertTo};
use std::path::Path;
fn main() {
// Two ways of converted a wav file
let fp: "./path/to/i16_encoded_wav.wav";
let wav: Wav<f32> = Wav::from_path(fp).unwrap();
// conversion happens automatically when you read
let samples: &[f32] = &wav.read().unwrap();
// or read and then call the convert function on the samples.
let (samples, sample_rate): (Samples<i16>, i32) = read::<i16, _>(fp).unwrap();
let samples: &[f32] = &samples.convert();
}
§Writing
use wavers::Wav;
use std::path::Path;
fn main() {
let fp: &Path = &Path::new("path/to/wav.wav");
let out_fp: &Path = &Path::new("out/path/to/wav.wav");
// two main ways, read and write as the type when reading
let wav: Wav<i16> = Wav::from_path(fp).unwrap();
wav.write(out_fp).unwrap();
// or read, convert, and write
let (samples, sample_rate): (Samples<i16>,i32) = read::<i16, _>(fp).unwrap();
let sample_rate = wav.sample_rate();
let n_channels = wav.n_channels();
let samples: &[f32] = &samples.convert();
write(out_fp, samples, sample_rate, n_channels).unwrap();
}
§Iteration
WaveRs
provides two primary methods of iteration: Frame-wise and Channel-wise. These can be performed using the Wav::frames
and Wav::channels
functions respectively. Both methods return an iterator over the samples in the wav file. The frames
method returns an iterator over the frames of the wav file, where a frame is a single sample from each channel. The channels
method returns an iterator over the channels of the wav file, where a channel is all the samples for a single channel.
use wavers::Wav;
fn main() {
let wav = Wav::from_path("path/to/two_channel.wav").unwrap();
for frame in wav.frames() {
assert_eq!(frame.len(), 2, "The frame should have two samples since the wav file has two channels");
// do something with the frame
}
for channel in wav.channels() {
// do something with the channel
assert_eq!(channel.len(), wav.n_samples() / wav.n_channels(), "The channel should have the same number of samples as the wav file divided by the number of channels");
}
}
§Wav Utilities
use wavers::wav_spec;
fn main() {
let fp = "path/to/wav.wav";
let wav: Wav<i16> = Wav::from_path(fp).unwrap();
let wav_spec = wav.wav_spec(); // returns the duration and the header
println!("{:?}", wav_spec);
}
Check out wav_inspect for a simnple command line tool to inspect the headers of wav files.
§Features
The following section describes the features available in the WaveRs crate.
§Ndarray
The ndarray
feature is used to provide functions that allow wav files to be read as ndarray
2-D arrays (samples x channels). There are two functions provided, into_ndarray
and as_ndarray
. into_ndarray
consumes the samples and as_ndarray
creates a Array2
from the samples.
use wavers::{read, Wav, AsNdarray, IntoNdarray, Samples};
use ndarray::{Array2, CowArray2};
fn main() {
let fp = "path/to/wav.wav";
let wav: Wav<i16> = Wav::from_path(fp).unwrap();
// does not consume the wav file struct
let (i16_array, sample_rate): (Array2<i16>, i32) = wav.as_ndarray().unwrap();
// consumes the wav file struct
let (i16_array, sample_rate): (Array2<i16>, i32) = wav.into_ndarray().unwrap();
// convert the array to samples.
let samples: Samples<i16> = Samples::from(i16_array);
}
§Benchmarks
To check out the benchmarks head on over to the benchmarks wiki page on the WaveRs GitHub.
Benchmarks were conducted on the reading and writing functionality of WaveRs and compared to the hound
crate.
Structs§
- The fact chunk of a wav file. Contains a single field,
num_samples
. This field is the number of samples in the wav file per channel. - The format chunk of a wav file. This chunk contains information about the format of the audio data. This chunk must be present in a wav file.
- A List Chunk - a chunk that contains a list of other chunks. Each chunk in the list is identified by a 4 byte ID, followed by a 4 byte size, and then the data.
- Wrapper struct around a boxed slice of samples. Wrapping allows the extension of the struct to include more functionality.
- Struct representing a wav file. The struct contains a boxed reader and the header information of the wav file.
- A struct representing the header of a wav file. It stores the offset and size of each chunk in the header, the format information and the current size of the file in bytes.
- An experimental 24-bit unsigned integer type.
Enums§
- An enum representing some of the format codes in the wav file format.
- Enum representing the encoding of a wav file.
- Error types for Wavers
Constants§
- The data chunk ID “data”
- The fact chunk ID “fact”
- The fact chunk ID “fact”
- The RIFF chunk ID “RIFF”
- The WAVE chunk ID “WAVE”
Traits§
- Trait used to indicate that a type is an audio sample and can be treated as such.
- Trait for converting between audio sample types in a slice The type
T
must implement theAudioSample
trait - Trait for converting between audio sample types The type
T
must implement theAudioSample
trait - Trait representing a type that can be used to read and seek.
Functions§
- Converts a tuple of format codes and bits per sample to a WavType.
- Reads a wav file and returns the samples and the sample rate.
- Returns the sample rate, number of channels, duration and encoding of a wav file. Convenmience function which opens the wav file and reads the header.
- Converts a WavType to a tuple of format codes and bits per sample.
- Writes wav samples to disk.
Type Aliases§
- Result type for Wavers