This crate provides some basic modules for building application-customized FLAC (Free Lossless Audio Codec) encoder in your rust programs. The API provided by this crate currently supports the following use cases:
- Performing FLAC encoding from custom input sources.
- Inspecting the encoded streams, enabling analysis and serialization of encoder results.
- Decoding a FLAC bitstream (experimental).
Importantly, this encoder is designed for hackability. Its portable and (relatively) clean code makes it easy to modify and adapt to your specific use cases.
If you need a stand-alone FLAC encoder/ decoder, rather than an embeddable
library, try our companion CLI tool, flacenc-bin.
For a detailed comparison of this encoder's characteristics against the FLAC reference implementation, please refer to the auto-generated report.
Add the following line to your Cargo.toml:
flacenc = "0.5.1"This crate is intended to be, and primarily developed with
portable_simd, and the default
configuration above uses "fake" implementation of portable_simd for making it
possible to build within a stable toolchain. If you are okay with using a
nightly toolchain, use this crate with the SIMD features as follows:
flacenc = { version = "0.5.1", features = ["simd-nightly"] }The performance improvement with "simd-nightly" feature can be seen by comparing benchmark report (nightly) and benchmark report (stable).
See also the source code of flacenc-bin sub-crate as an example implementation
of a FLAC encoder.
The simplest way to implement a FLAC encoder given the recorded samples in
&[i32] is as follows:
use flacenc::component::BitRepr;
use flacenc::error::Verify;
let samples: &[i32] = &[0i32; 4096]; // replace this with real samples.
let (channels, bits_per_sample, sample_rate) = (2, 16, 44100);
let config = flacenc::config::Encoder::default().into_verified().expect(
"Config data error."
);
let source = flacenc::source::MemSource::from_samples(
samples, channels, bits_per_sample, sample_rate);
let flac_stream = flacenc::encode_with_fixed_block_size(
&config, source, config.block_size
).expect("Encode failed.");
// `Stream` implements `BitRepr` so you can obtain the encoded stream via
// `ByteSink` struct that implements `BitSink`.
let mut sink = flacenc::bitsink::ByteSink::new();
flac_stream.write(&mut sink);
// Then, e.g. you can write it to a file.
std::fs::write("/dev/null", sink.as_slice());
// or you can write only a specific frame.
let mut sink = flacenc::bitsink::ByteSink::new();
flac_stream.frame(0).unwrap().write(&mut sink);samples here is an interleaved sequence, e.g. in the case of stereo inputs, it
is a sequence like [left[0], right[0], left[1], right[1], ...] where left[t]
and right[t] denote the t-th sample from the left and right channels,
respectively. All samples are assumed to be in the range of
- 2.pow(bits_per_samples - 1) .. 2.pow(bits_per_samples - 1), i.e. if
bits_per_samples == 16, samples[t] must be -32768 <= samples[t] <= 32767.
NOTE: Currently, flacenc is in its initial development stage
(major version zero). Therefore, the API may
change frequently. While in major-version-zero phase, we increment the minor
version ("Y" of the version "x.Y.z") when there's a breaking API change.
The current API provides several ways to control the encoding process. The possible customization can be categorized into three groups:
- Encoder algorithm customization by configuring
config::Encoder, - Input enhancement by implementing
source::Sourcetrait, - Add custom post-processing via structs in
componentsubmodule.
flacenc has a few Cargo features that change the internal behaviors and APIs.
decode: Enables decoder-related features such as bit-stream parsing, and component to signal conversion.flacencemploysnomas a bitstream parser toolkit, and enabling this feature adds dependency to it.experimental: Enables experimental coding algorithms that are typically slower. Due to its experimental nature, there's no documentation on how to activate each algorithm. You may need to exploreflacenc::configmodule or source codes for better understanding.log: (This feature is enabled by default) Enables logging so an application program can handle the log by linking a log-handler crate (such asenv_loggercrate.) Logging is not done in a performance critical part of the code, so the computational cost due to this feature should be negligible.simd-nightly: Activatesportable-simdfeature of a rust nightly toolchain and use real SIMD processing instead of the fake one currently used by default.mimalloc: Enablesmimallocglobal allocator. This can lead a performance improvement inpar-mode.par: (This feature is enabled by default) Enables multi-thread encoding inencode_with_fixed_block_sizefunction ifconfigargument is properly configured (whenparis enabled the default configuration enables multi-thread mode.). If you want to disable multi-thread mode and make the dependency tree smaller, you may do that bydefault-features = false.paradds dependency tocrossbeam-channelcrate.serde: Makes FLAC component datatypes to be serializable/ deserializable. This is convenient for analyzing FLAC streams.
In an example encoder flacenc-bin, all the features except for simd-nightly
are enabled by default. simd-nightly is used in
the benchmarking script.
The core functionality of flacenc (without any feature flags) is developed to
work with the stable Rust version that was the latest as of one year prior to
the date of the latest stable release.
For example, as of October 15, 2025, the latest stable release is 1.90.0, which
was released on September 18, 2025. Therefore, flacenc currently supports the
latest stable compiler available as of Dec 5, 2024, which is 1.83.0.
When changing the MSRV, we increment the minor version number. Since flacenc
is still at ver-0, this corresponds to changing the Z component in X.Y.Z.
To avoid unnecessary version bumps, the MSRV may be set to an older version than
the one derived by the rule above.
The current MSRV is 1.83.0.
See CONTRIBUTING.md for details.
Apache 2.0; see LICENSE for details.