Skip to main content

Crate audio_file

Crate audio_file 

Source
Expand description

§audio-file

A simple library to read and write audio files on your disk.

The library can read many formats and can write only to wav files.

§Quick Start

Read a file into interleaved f32 (or f64) samples, full scale at ±1.0:

let audio = audio_file::read::<f32>("test_data/test_1ch.wav", audio_file::ReadConfig::default())?;

let samples = &audio.samples_interleaved;
let sample_rate = audio.sample_rate;
let num_channels = audio.num_channels;

Write interleaved samples back out as a wav file:

let samples = [0.0, 1.0, 0.0, 1.0, 0.0, 1.0]; // interleaved
let num_channels = 2;
let sample_rate = 48_000;

audio_file::write(
    "output.wav",
    &samples,
    num_channels,
    sample_rate,
    audio_file::WriteConfig::default(),
)?;

That covers most uses. Everything below is optional.

§Features

With no default features, this crate reads and writes wav through a built-in decoder, with almost no dependencies. Everything else is additive on top of that.

FeatureDefaultWhat it adds
all-codecsyesRead every common codec: MP3, FLAC, AAC, ALAC, Vorbis, and the MP4, Ogg, Matroska, AIFF and CAF containers
resampleyesResample while reading, via rubato
simdyesSymphonia’s SIMD optimizations. Only does something alongside a codec feature
audio-blocksnoRead and write any channel layout, via audio-blocks

Turning a feature off removes the API it brings rather than making it fail at runtime. Without resample, ReadConfig has no sample_rate field at all, so asking for a rate nothing would resample to does not compile.

§Reading

ReadConfig selects what to read. Only the selected frames are stored, though the reader may decode and discard earlier packets for accurate seeking and codec warm-up.

Positions are given as a Position, in frames or in time. start is inclusive and stop is exclusive, so frame 300 to 400 yields 100 frames. Frame 0 is the first playable frame: encoder delay and padding, as used by formats like MP3, are not part of the timeline.

// the first half second
let audio = audio_file::read::<f32>(
    "test_data/test_1ch.wav",
    audio_file::ReadConfig {
        stop: audio_file::Position::Time(Duration::from_secs_f32(0.5)),
        ..Default::default()
    },
)?;

// frame 300 up to frame 400
let audio = audio_file::read::<f32>(
    "test_data/test_1ch.wav",
    audio_file::ReadConfig {
        start: audio_file::Position::Frame(300),
        stop: audio_file::Position::Frame(400),
        ..Default::default()
    },
)?;

Channels are selected the same way, with start_channel and num_channels:

// the first two channels
let audio = audio_file::read::<f32>(
    "test_data/test_4ch.wav",
    audio_file::ReadConfig {
        num_channels: Some(2),
        ..Default::default()
    },
)?;

// channel 2 and 3, skipping the first
let audio = audio_file::read::<f32>(
    "test_data/test_4ch.wav",
    audio_file::ReadConfig {
        start_channel: Some(1),
        num_channels: Some(2),
        ..Default::default()
    },
)?;

With the resample feature, a sample_rate makes the reader hand back audio at that rate whatever the file holds:

let audio = audio_file::read::<f32>(
    "test_data/test_1ch.wav",
    audio_file::ReadConfig {
        sample_rate: Some(22_050),
        ..Default::default()
    },
)?;

A file is either read in full or not at all: a packet the decoder rejects fails the whole read rather than being skipped over or filled in.

§Writing

Output is always wav. WriteConfig picks the sample format:

SampleFormatDescription
Int88-bit integer
Int1616-bit integer (default, for the broadest compatibility)
Int3232-bit integer
Float3232-bit float
audio_file::write(
    "output_float32.wav",
    &samples_interleaved,
    num_channels,
    sample_rate,
    audio_file::WriteConfig {
        sample_format: audio_file::SampleFormat::Float32,
    },
)?;

§Other channel layouts

Interleaved is the only layout read and write speak. With the audio-blocks feature you get read_block and write_block, which work in AudioBlocks and so handle any layout, plus channel-wise access to what was read:

let (block, sample_rate) =
    audio_file::read_block::<f32>("test_data/test_4ch.wav", ReadConfig::default())?;
let left: Vec<f32> = block.channel_iter(0).copied().collect();

let block = Sequential::from_slice(&[0.0, 0.0, 0.0, 1.0, 1.0, 1.0], 2);
audio_file::write_block("output_layout.wav", block, 48_000, WriteConfig::default())?;

§Picking individual codecs

all-codecs is a convenience for “read anything”. To keep the dependency tree small, name only the formats you need instead:

FormatFeature flags
WAV, integer PCM and IEEE floatnone, built in
WAV, A-law, mu-law and ADPCMwav-compressed
FLACflac
MP1, MP2, MP3mp1, mp2, mp3
AAC (raw ADTS)aac
MP4, M4Aisomp4 plus aac or alac
Oggogg plus vorbis or flac
Matroska (MKA, MKV)mkv plus the codec inside: pcm, flac, vorbis, aac, alac
AIFFaiff plus pcm
CAFcaf plus pcm or alac

A container and the codec inside it are separate flags, so a format that can hold several codecs needs one of each. Enabling only the container reads no file at all. A file no decoder in the build can read fails with ReadError::UnsupportedFormat.

Some formats have channel ceilings below what the format itself allows, see the reader module docs.

Re-exports§

pub use reader::Audio;
pub use reader::Position;
pub use reader::ReadConfig;
pub use reader::ReadError;
pub use reader::read;
pub use writer::SampleFormat;
pub use writer::WriteConfig;
pub use writer::WriteError;
pub use writer::write;

Modules§

reader
Reading audio files.
writer

Enums§

ResampleError