SEA is a low-complexity, lossy audio codec designed for embedded devices, inspired by the awesome QOA codec. Like QOA, SEA utilizes the Least Mean Squares Filter (LMS) algorithm, but it introduces variable bitrate (VBR) support and features slightly modified quantization tables. The reference implementation is written in Rust, and a compact ~250-line decoder written in C is also available for demonstration purposes.
You can test SEA in your browser here: https://daninet.github.io/sea-codec/
- Fast, low complexity, time-domain compression. The decoder fits into ~250 lines of C code.
- Ideal for low-power embedded devices, game assets, and live streaming.
- Flat frequency response: No low-pass filtering is applied, preserving the full frequency range.
- Variable bitrate: 1.2 - 8.5 bits per sample
- Constant and variable bitrate (CBR and VBR) modes.
- Fixed frame length: Enables constant-time seeking.
- Multi-channel support: Handles up to 255 channels.
- Metadata storage: Allows embedding additional information.
- MIT License
You can build it with cargo build --example seaconv --release or you can download a pre-built binary from the releases page.
seaconv.exe input.wav encoded.sea --bitrate 3
seaconv.exe encoded.sea decoded.wav
A SEA file consists of a file header followed by a series of chunks. Samples are stored as 16-bit signed integers in interleaved format. All values are stored in little-endian order.
- Format: UTF-8 encoded string
- Structure: Key-value pairs separated by newline characters (\n)
- Key and value are separated by =
- Key is case-insensitive and cannot contain = or \n
- Value is case sensitive and can contain any characters except \n
- Fixed size: Each chunk has a fixed byte size (specified in the file header) and contains a fixed number of frames, enabling constant-time seeking.
- Padding: If a chunk is smaller than the specified size in the file header, it is padded with zeroes.
- Bitpacking: Scale factors, VBR residual lengths, and residuals are stored using bitpacking.
- Interleaved Order: All packed values are stored in interleaved order (e.g., ch0, ch1, ch2, ch0, ch1, ch2, ...).
- Scale Factor Frames: The scale_factor_frames field determines the interval between scale factor values. For example, a value of 20 means one scale factor is applied to 20 samples.
- VBR Residual Lengths: In VBR mode, bitpacked_vbr_residual_lengths stores the difference from the standard residual length defined in the chunk header. The offset is -1:
- Seeking Support: Add seeking functionality to the Rust implementation.
- Optimization and Benchmarking: Optimize the implementation and benchmark against other codecs.
- C Encoder: Implement an encoder in C for broader compatibility.
MIT License
Copyright (c) 2025 Dani Biró