Expand description
§Wavers
WaveRs is a fast and lightweight library for reading and writing wav files.
Currently, it supports reading and writing of i16, i24, i32, f32, and f64 audio samples.
Feedback and bugs welcome!
§Highlights
- Fast and lightweight
- Simple API, read a wav file with
readand write a wav file withwrite - Easy and efficient conversion between different types of audio samples (should compile down to simd instructions provided you build with the appropriate SIMD instruction set for your architecture).
- Support for the Extensible format (Happy to try and support anything else that pops up, just ask or open a PR).
- Increasing support for different chunks in the wav file.
- Support for iteration over the frames, channels and overlapping blocks of the wav file.
- Support for the
ndarraycrate. Enable thendarrayfeature to enable ndarray support. - Support for the
pyo3crate. Enable thepyo3feature to enable pyo3 support. This is mostly for PyWavers. - Supports logging through the
logcrate. Enable theloggingfeature to enable logging.
§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
writefunction. - 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.
Re-exports§
pub use crate::conversion::AudioSample;pub use crate::conversion::ConvertSlice;pub use crate::conversion::ConvertTo;pub use crate::chunks::FactChunk;pub use crate::chunks::FmtChunk;pub use crate::chunks::ListChunk;pub use crate::chunks::DATA;pub use crate::chunks::FACT;pub use crate::chunks::LIST;pub use crate::chunks::RIFF;pub use crate::chunks::WAVE;pub use crate::core::wav_spec;pub use crate::core::ReadSeek;pub use crate::core::Samples;pub use crate::core::Wav;pub use crate::error::WaversError;pub use crate::error::WaversResult;pub use crate::header::WavHeader;pub use crate::wav_type::format_info_to_wav_type;pub use crate::wav_type::wav_type_to_format_info;pub use crate::wav_type::FormatCode;pub use crate::wav_type::WavType;
Modules§
- chunks
- This module contains the
Chunktrait and the constants relating to the different chunks in a wav file. - conversion
- core
- error
- Module containing the error types for Wavers
- header
- Module containing functions and structs for working with Wav file headers.
- iter
- Module containing the different type of iterators for the Wav struct.
- wav_
type - Module for the WavType enum and related functions.
Macros§
- log
- A macro for logging messages if the logging feature is enabled.