- Zig 99.7%
- Ruby 0.3%
|
|
||
|---|---|---|
| src | added canSeek function to Decoder | |
| tests @aa7b0c6cf3 | added tests suite, made passing all subset and faulty | |
| tools | added the script used to generate the initial test boilerplate | |
| .gitignore | updated build scripts, README, and CHANGELOG, set common import | |
| .gitmodules | added tests suite, made passing all subset and faulty | |
| build.zig | updated build scripts, README, and CHANGELOG, set common import | |
| build.zig.zon | updated build scripts, README, and CHANGELOG, set common import | |
| CHANGELOG.md | added canSeek function to Decoder | |
| LICENSE | added LICENSE and first draft of README | |
| README.md | updated links in example to new location | |
flac
A native FLAC decoding library written from scratch in Zig.
This project provides a clean, dependency-free decoding engine designed for seamless integration into audio players, game engines, and mixing pipelines. It eliminates wrappers around legacy C binaries, offering an easy-to-use API built natively for modern Zig I/O paradigms.
Features
- 100% Native Zig: Zero dependencies on
libFLAC,dr_flac, or any other external C source code. Easy to cross-compile out of the box with no third-party dependencies. - Zero Allocation During Decoding: While initialization requires an allocator to set up necessary internal decoding structures, the hot-path decoding loop is completely allocation-free.
- Flexible Sample Conversion: Seamlessly decodes and transforms the underlying stream directly into whatever target sample bit depth or format your application requires, including
i16,i24,i32,f32andf64. - SIMD Accelerated: Utilizes hardware vector extensions where available for high-throughput channel interleaving and audio math.
- Robust I/O Abstraction: Built on top of the Zig 0.16
std.Io.Readerinfrastructure. Natively supports unseekable media (like live network streams) while gracefully supporting hardware/OS-level seeking when a positioning function is supplied. - Fully Spec Compliant: Adheres to the FLAC RFC 9639 specification, defaulting to the FLAC Subset profile, which can be disabled during initialization to support non-standard data.
- No AI/LLM Code: 100% of the code is both inspired and written by a human.
Installation & Integration
Add flac to your project's build.zig.zon:
.{.name="my_project",.version="0.1.0",.dependencies=.{.flac=.{.url="https://codeberg.org/audiophile/flac/archive/v1.0.0.tar.gz",// .hash = "...",},},}Expose the module in your build.zig:
conststd=@import("std");pubfnbuild(b:*std.Build)void{consttarget=b.standardTargetOptions(.{});constoptimize=b.standardOptimizeOption(.{});constflac_dep=b.dependency("flac",.{.target=target,.optimize=optimize,});constexe=b.addExecutable(.{.name="my_audio_app",.root_source_file=b.path("src/main.zig"),.target=target,.optimize=optimize,});exe.root_module.addImport("flac",flac_dep.module("flac"));b.installArtifact(exe);}Quick Start
conststd=@import("std");constflac=@import("flac");pubfnmain(init:std.process.Init)!void{// An arena allocator is fine here too, the decoder performs no// re-allocations or freeing during its lifetime.constallocator=init.gpa;constio=init.io;constcwd=std.Io.Dir.cwd();varfile=trycwd.openFile(io,"filename.flac",.{});// You will definitely need a buffer, bit-streams are single byte reads at a timevarfile_buffer:[8192]u8=undefined;varreader=file.reader(io,&file_buffer);// Initialize the decodervardecoder=tryflac.Decoder.init(allocator,&reader.interface,.{.seek_impl=.file,.skip_metadata=true,});// Decoder does no allocations after initial setup,// and does not maintain a reference to it.deferdecoder.deinit(allocator);varsample_buffer:[4096]i16=undefined;while(true){// The return value is a sub-slice into the given buffer// containing the interleaved samples in requested bit depth,// which may differ from the source, conversion is automatic.constsamples=trydecoder.read(i16,&sample_buffer);// Only returns 0 samples upon a valid EOF condition or if// input buffer is less than the channel count.if(samples.len==0)break;// Do whatever you need with the raw samples// The number of samples returned may differ from the input buffer// length so that only full multi-channel samples (frame) are given.}}Testing & Conformance
This library is fully validated against the ietf-wg-cellar/flac-test-files test suite, ensuring strict adherence to the FLAC format specification. It passes all conformance vectors, including complex variable-length framing architectures and stream-synchronized files lacking standard initialization headers.
Perhaps even more importantly, it passes all "faulty" tests with appropriate error handling. This guards against malformed or even malicious FLAC data when decoding from untrusted sources.
To run the test suite locally, first clone the repository with the --recursive flag:
git clone --recursive https://codeberg.org/audiophile/flac.git
cd flac
Alternatively using SSH:
git clone --recursive ssh://git@codeberg.org/audiophile/flac.git
cd flac
If you have already cloned the repository without the submodule, initialize it using:
git submodule update --init --recursive
To run the test suite locally once the test files are present:
zig build test
License
This project is licensed under the MIT License.
The test files utilized in the test suite are sourced from the IETF WG Cellar repository and are dedicated to the public domain under Creative Commons Zero v1.0 Universal (CC0 1.0).