SEA - Simple Embedded Audio Codec
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/
Key Features
- 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
SEA file specification
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.
File header
Metadata
- 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
Example metadata
author=John Doe
title=My Song
Chunk
- 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:
0 = chunk_residual - 1
1 = chunk_residual
2 = chunk_residual + 1
3 = chunk_residual + 2
Future plans
- Seeking Support: Add seeking functionality to the Rust implementation.
- CLI Tool: Develop a command-line tool for easy audio conversion.
- Optimization and Benchmarking: Optimize the implementation and benchmark against other codecs.
- C Encoder: Implement an encoder in C for broader compatibility.
License
MIT License
Copyright (c) 2025 Dani Biró