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
read
and 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
ndarray
crate. Enable thendarray
feature to enable ndarray support. - Support for the
pyo3
crate. Enable thepyo3
feature to enable pyo3 support. This is mostly for PyWavers. - Supports logging through the
log
crate. Enable thelogging
feature 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
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.
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
Chunk
trait 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.