libflo
A Rust library for encoding and decoding flo™ audio files with WASM support.
Features
- Dual-mode compression: Lossless (ALPC) and lossy (MDCT transform)
- ALPC Compression: Adaptive Linear Predictive Coding (orders 1-12) for lossless
- Transform Coding: MDCT with psychoacoustic model for lossy (~10-30x compression)
- Rice Coding: Efficient residual compression
- CRC32 Integrity: Data chunk verification
- Multi-channel: Mono and stereo support
- Streaming Decoder: Frame-by-frame decoding for real-time playback
- WASM Ready: Full WebAssembly compatibility
- Clean API: Unified interface for CLI, WASM, and library use
Module Structure
src/
├── lib.rs # Main exports and WASM bindings
├── core/ # Core utilities
│ ├── crc32.rs # CRC32 checksums
│ ├── rice.rs # Rice coding for entropy
│ ├── types.rs # Common types (Header, Frame, etc.)
│ └── metadata.rs # Metadata structures (ID3-like)
├── lossless/ # Lossless mode (ALPC)
│ ├── encoder.rs # Lossless encoder
│ ├── decoder.rs # Lossless decoder
│ └── lpc.rs # LPC analysis/synthesis
├── lossy/ # Lossy mode (Transform)
│ ├── encoder.rs # Transform encoder (TransformEncoder)
│ ├── decoder.rs # Transform decoder (TransformDecoder)
│ ├── mdct.rs # MDCT/IMDCT transform
│ └── psychoacoustic.rs # Perceptual model
├── streaming/ # Streaming decoder
│ ├── encoder.rs # Frame-by-frame streaming encoder
│ ├── decoder.rs # Frame-by-frame streaming decoder
├── reader.rs # Binary file parser
└── writer.rs # Binary file writer
Installation
Add to your Cargo.toml:
[]
= { = "path/to/libflo" }
API Reference
Functions
| Function | Description |
|---|---|
encode(samples, sample_rate, channels, bit_depth, metadata) |
Encode audio (lossless) |
encode_lossy(samples, sample_rate, channels, bit_depth, quality, metadata) |
Encode audio (lossy, quality 0-4) |
encode_transform(samples, sample_rate, channels, bit_depth, quality, metadata) |
Encode audio (lossy, quality 0.0-1.0) |
encode_with_bitrate(samples, sample_rate, channels, bit_depth, bitrate_kbps, metadata) |
Encode audio (lossy, target bitrate) |
decode(data) |
Decode flo™ file (auto-detects mode) |
validate(data) |
Verify file integrity (CRC32) |
info(data) |
Get file information |
version() |
Get library version |
Metadata Functions (No Re-encode!)
flo™ stores metadata separately from audio data, enabling instant metadata updates without re-encoding.
| Function | Description |
|---|---|
update_metadata(data, new_metadata) |
Update metadata without re-encoding (WASM) |
update_metadata_bytes(data, new_metadata) |
Update metadata without re-encoding (Rust) |
strip_metadata(data) |
Remove all metadata (WASM) |
strip_metadata_bytes(data) |
Remove all metadata (Rust) |
get_metadata_bytes(data) |
Get raw metadata bytes (WASM) |
get_metadata_bytes_native(data) |
Get raw metadata bytes (Rust) |
has_metadata(data) |
Check if file has metadata (fast header check) |
Streaming Functions
| Function | Description |
|---|---|
WasmStreamingDecoder::new() |
Create new streaming decoder |
feed(data) |
Feed bytes incrementally |
get_info() |
Get file info (sample rate, channels, etc.) |
next_frame() |
Decode next frame (returns samples or null) |
decode_available() |
Decode all buffered data at once |
reset() |
Reset decoder state |
free() |
Release resources |
Structs
| Struct | Description |
|---|---|
Encoder |
Lossless encoder instance |
LossyEncoder |
Transform-based lossy encoder |
Decoder |
Lossless decoder instance |
LossyDecoder |
Transform-based decoder |
QualityPreset |
Quality levels (Low, Medium, High, VeryHigh, Transparent) |
Reader |
Low-level binary parser |
Writer |
Low-level binary writer |
AudioInfo |
File information container |
Quick Start
Rust (Lossless)
use ;
// Encode audio (lossless)
let samples: = vec!; // 1 second of silence
let encoder = new;
let flo_data = encoder.encode?;
// Decode audio (auto-detects mode)
let decoded = decode?;
// Get info
let file_info = info?;
println!;
Rust (Lossy)
use ;
// Encode with quality preset
let quality = High.as_f32; // 0.55
let mut encoder = new;
let flo_data = encoder.encode_to_flo?;
// Encode with bitrate target
let quality = from_bitrate.as_f32;
let mut encoder = new;
let flo_data = encoder.encode_to_flo?;
// Decode (auto-detects lossy mode)
let decoded = decode?;
JavaScript (WASM)
import init from './libflo.js';
await ;
// Lossless encode
const samples = ;
const floData = ;
// Lossy encode (quality: 0=Low, 1=Medium, 2=High, 3=VeryHigh, 4=Transparent)
const floDataLossy = ;
// Decode (auto-detects mode)
const decoded = ;
// Validate
const isValid = ;
// Info
const fileInfo = ;
console.log;
Streaming Decoder (JavaScript)
For real-time playback and progressive loading:
import init from './libflo.js';
await ;
// Create streaming decoder
const decoder = ;
// Feed data incrementally
decoder.;
// Get file info once header is parsed
const info = decoder.;
// Decode frame-by-frame
while
decoder.;
File Format
flo™ follows the specification in flo_audio.ksy:
┌─────────────────────────────────────┐
│ MAGIC "flo™!" (4 bytes) │
├─────────────────────────────────────┤
│ HEADER (66 bytes) │
│ - version, sample_rate, channels │
│ - bit_depth, compression_level │
│ - CRC32, chunk sizes │
├─────────────────────────────────────┤
│ TOC CHUNK │
│ - Frame seek table │
│ - 20 bytes per entry │
├─────────────────────────────────────┤
│ DATA CHUNK │
│ - Compressed audio frames │
│ - 1 second per frame │
├─────────────────────────────────────┤
│ EXTRA CHUNK (reserved) │
├─────────────────────────────────────┤
│ META CHUNK (MessagePack) │
└─────────────────────────────────────┘
Frame Types
| Value | Type | Description |
|---|---|---|
| 0 | Silence | No audio data stored |
| 1-12 | ALPC | Lossless LPC with order N |
| 253 | Transform | MDCT-based lossy encoding |
| 254 | Raw | Uncompressed PCM |
| 255 | Reserved | Future use |
Building
Native
WASM
# Or with wasm-pack:
Testing
License
Apache-2.0