npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@flo-audio/libflo-audio

v0.1.2

Published

The official encoder/decoder for the flo™ audio format

Readme

libflo

A Rust library for encoding and decoding flo™ audio files with WASM support. Available on crates.io! https://crates.io/crates/libflo-audio

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:

[dependencies]
libflo-audio = { version = "0.1.2" }

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 libflo_audio::{Encoder, decode, info};

// Encode audio (lossless)
let samples: Vec<f32> = vec![0.0; 44100]; // 1 second of silence
let encoder = Encoder::new(44100, 2, 16);
let flo_data = encoder.encode(&samples, &[])?;

// Decode audio (auto-detects mode)
let decoded = decode(&flo_data)?;

// Get info
let file_info = info(&flo_data)?;
println!("Duration: {} seconds", file_info.duration_secs);

Rust (Lossy)

use libflo_audio::{LossyEncoder, QualityPreset, decode};

// Encode with quality preset
let quality = QualityPreset::High.as_f32(); // 0.55
let mut encoder = LossyEncoder::new(44100, 2, quality);
let flo_data = encoder.encode_to_flo(&samples, &[])?;

// Encode with bitrate target
let quality = QualityPreset::from_bitrate(192, 44100, 2).as_f32();
let mut encoder = LossyEncoder::new(44100, 2, quality);
let flo_data = encoder.encode_to_flo(&samples, &[])?;

// Decode (auto-detects lossy mode)
let decoded = decode(&flo_data)?;

JavaScript (WASM)

import init, { encode, encode_lossy, decode, info, validate, version } from './libflo_audio.js';

await init();

// Lossless encode
const samples = new Float32Array(44100);
const floData = encode(samples, 44100, 1, 16, null);

// Lossy encode (quality: 0=Low, 1=Medium, 2=High, 3=VeryHigh, 4=Transparent)
const floDataLossy = encode_lossy(samples, 44100, 1, 16, 2, null);

// Decode (auto-detects mode)
const decoded = decode(floData);

// Validate
const isValid = validate(floData);

// Info
const fileInfo = info(floData);
console.log(`Lossy: ${fileInfo.is_lossy}, Ratio: ${fileInfo.compression_ratio}`);

Streaming Decoder (JavaScript)

For real-time playback and progressive loading:

import init, { WasmStreamingDecoder } from './libflo_audio.js';

await init();

// Create streaming decoder
const decoder = new WasmStreamingDecoder();

// Feed data incrementally
decoder.feed(chunk);

// Get file info once header is parsed  
const info = decoder.get_info();

// Decode frame-by-frame
while (true) {
    const samples = decoder.next_frame();
    if (samples === null) break;
    // Play samples...
}

decoder.free();

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

cargo build --release

WASM

cargo build --target wasm32-unknown-unknown --release
# Or with wasm-pack:
wasm-pack build --target web

Testing

cargo test

License

Apache-2.0