Files
craft-libs/crates/audio/examples/encode.rs
T
alehelandClaude Opus 5.5 550732201c craft-audio: FLAC encoder
FilmCraft's FLAC encoder behind `flac-encode`, kept over SoundCraft's:
linear prediction, stereo decorrelation and the STREAMINFO MD5 give
0.1-37% smaller files on 12 test signals, and the output is bit-exact
through `flac` and ffmpeg. It is 3-5x slower than SoundCraft's, still
about 56x real time.

`lossless-encode` is now `pcm-encode` plus `flac-encode`, and
`EncodeFormat::Flac` writes it through `encode` and `FileEncoder`.
With only one of the two features, the other's formats are refused as
`Unsupported`.

The tests that use FLAC files as decode fixtures (truncation,
corruption, metadata bounds, zero-frame files, container preflight)
come with it, as do the FLAC oracle tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 10:35:44 +01:00

32 lines
1.5 KiB
Rust

//! Write a tone as WAV and FLAC, whole and streamed.
//!
//! `cargo run -p craft-audio --example encode --features lossless-encode -- out`
use craft_audio::{AudioBuffer, BitDepth, ChannelLayout, EncodeFormat, EncodeOptions, FileEncoder, encode};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let dir = std::path::PathBuf::from(std::env::args().nth(1).unwrap_or_else(|| ".".into()));
std::fs::create_dir_all(&dir)?;
let rate = 48_000;
let tone: Vec<f32> = (0..rate).map(|i| (i as f32 * 440.0 * std::f32::consts::TAU / rate as f32).sin() * 0.5).collect();
let stereo = AudioBuffer { sample_rate: rate as u32, channels: vec![tone.clone(), tone.clone()] };
// A whole buffer at once.
let wav = encode(&stereo, &EncodeOptions::new(EncodeFormat::Wav).with_bit_depth(BitDepth::Int24).with_dither(true))?;
std::fs::write(dir.join("tone.wav"), wav)?;
// A 5.1 file whose layout a channel count alone cannot name (side surrounds).
let surround = AudioBuffer { sample_rate: rate as u32, channels: vec![tone.clone(); 6] };
let wav = encode(&surround, &EncodeOptions::default().with_layout(ChannelLayout::SURROUND_5_1_SIDE))?;
std::fs::write(dir.join("tone-5.1.wav"), wav)?;
// Streamed: the same bytes, block by block into a file.
let opts = EncodeOptions::new(EncodeFormat::Flac);
let mut enc = FileEncoder::new(std::fs::File::create(dir.join("tone.flac"))?, &opts, rate as u32, 2)?;
for chunk in tone.chunks(4096) {
enc.write(&[chunk, chunk], chunk.len())?;
}
enc.finish()?;
Ok(())
}