flacenc-rs
This crate provides some basic modules for building application customized FLAC
(Free Lossless Audio Codec) encoder in rust programs. If you are interested in a
stand-alone FLAC encoder (rather than a library for building it), check out the
CLI for this module located in flacenc-bin.
See the auto-generated report for the characteristics of the encoder compared to FLAC reference implementation.
Usage
Add the following line to your Cargo.toml:
= "0.3.0"
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:
= { = "0.3.0", = ["simd-nightly"] }
Examples
See also the source code of flacenc-bin sub-crate as an example implementation
of FLAC encoder.
The simplest way to implement FLAC encoder given the recorded samples in
&[i32] is as follows:
use BitRepr;
let samples: & = &; // replace this with real samples.
let = ;
let config = default;
let source = from_samples;
let flac_stream = encode_with_fixed_block_size.expect;
// `Stream` imlpements `BitRepr` so you can obtain the encoded stream via
// `ByteSink` struct that implements `BitSink`.
let mut sink = new;
flac_stream.write;
// Then, e.g. you can write it to a file.
write;
// or you can write only a specific frame.
let mut sink = new;
flac_stream.frame.unwrap.write;
samples here is an interleaved sequence, e.g. in the case with stereo inputs,
it is a sequence like [left_0, right_0, left_1, right_1, ...] where
{left|right}_N denotes the N-th sample from the left or right channel. 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.
Customizing Encoder Behaviors
NOTE: Currently, flacenc is in its initial development stage
(major version zero).
The current API provides several ways to control the encoding process. The possible customization can be categorized into three groups:
- Encode behavior customization by configuring
config::Encoder, - Input enhancement by implementing
source::Sourcetrait, - Add custom post-processing via structs in
componentsubmodule.
Feature Flags
flacenc has a few Cargo features that changes the internal behaviors and APIs.
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.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-featuers = false.paradds dependency tocrossbeam-channelcrate.
In an example encoder flacenc-bin, all the features except for simd-nightly
are enabled by default. Further, simd-nightly is used in
the benchmarking script.
Contributing
See CONTRIBUTING.md for details.
License
Apache 2.0; see LICENSE.md for details.
Disclaimer
This project is not an official Google project. It is not supported by Google and Google specifically disclaims all warranties as to its quality, merchantability, or fitness for a particular purpose.
This encoder is still unstable and sometimes the encoded file may contain distortion, i.e. the encoder is sometimes not "lossless". You can check whether you encountered an encoder bug by running the reference decoder. The FLAC format contains MD5 digest of the input signal, and the reference decoder checks if the digest of the decoded signal matches with the stored one.