Home

Awesome

QOA: Quite OK Audio

The Quite OK Audio Format for Fast, Lossy Compression.

Build Status

A CLI tool for working with audio files following the QOA Format Specification.

demo

Features:

This blog post by the author of QOA is a great introduction to the format and how it works.

Install

The easiest way is a pre-built binary on the Releases page. I tested it works on Linux and Windows 10+.

wget -O /usr/bin/goqoa https://github.com/braheezy/goqoa/releases/latest/download/goqoa-linux
chmod +x /usr/bin/goqoa
wget -O /usr/bin/goqoa https://github.com/braheezy/goqoa/releases/latest/download/goqoa-mac
chmod +x /usr/bin/goqoa
mkdir $HOME\goqoa
iwr "https://github.com/braheezy/goqoa/releases/latest/download/goqoa.exe" -OutFile "$HOME\goqoa\goqoa.exe"
$env:Path += ";$HOME\goqoa"
[System.Environment]::SetEnvironmentVariable("Path", $env:Path, "User")

Otherwise, install prerequisites for your platform:

# Fedora
yum install gcc alsa-lib-devel
# Debian
apt-get install gcc pkg-config libasound2-dev

Then, install directly with Go:

go install github.com/braheezy/goqoa@latest

Or, checkout the project, build it from source, and install:

git clone https://github.com/braheezy/goqoa.git
cd goqoa
make install

qoa Package

The library qoa has been moved to this repository so I could manage the version of the library separate from the goqoa CLI.

Development

You'll need the following:

Then you can make build to get a binary.

make test will run Go unit tests.

make to see all options.

Reference Testing

This is a rewrite of the QOA implementation, not a transpile of or a CGO wrapper to qoa.h. It's a simple enough encoding that the code can be compared side-by-side to ensure the same algorithm has been implemented.

To further examine fidelity, the check_spec.sh script can be used. It does the following:

The check uses cmp to check each byte in each produced file. For an unknown reason, not all files pass this check. The failing files are the exact same size and when played, sound the same. Perhaps it's rounding error differences between Go and C, or bad reference files, or other such noise. It does appear to the same suspect files everytime. Anyway, you have been warned.

The Dockerfile can also be used to compare against the reference. It builds and installs both goqoa and qoaconv and provides an entrypoint script to convert WAV file(s) with both tools, then summarize the results.

docker build . -t qoacompare:latest && docker run --rm -it -v `pwd`:/data  qoacompare /data/test_ultra_new.wav

Fuzz Testing

The qoa package has a fuzz unit test to examine the Encode() and Decode() functions.

fuzz/create_fuzzy_files.py generates valid QOA files with random data.

Benchmarks

To get a sense of this implementation's encoding speed, I run a simple WAV -> QOA conversion. The timing includes WAV decoding time but that's okay.

My host hardware:

$ neofetch
CPU› 13th Gen Intel i5-13600KF (20) @ 5.100GHz
GPU› AMD ATI Radeon RX 6800/6800 XT / 6900 XT
Memory› 7416MiB / 31925MiB

Before I did any optimizations, this was the state of the benchmarks before-benchmark

I did some refactoring to reduce memory allocations in qoa and updated how I was decoding WAV data. This is what it looks like after: after-benchmark

And the quality of the encoded file didn't go down:


Disclaimer

I have never written software that deals with audio files before. I saw a post about QOA on HackerNews and found the name amusing. There were many ports to other languages, but Go was not listed. So here we are!

I developed this with an LLM-based workflow: