Qoa.jai #
QOA is a neat lossy audio format that’s fast and pretty simple. I recommend reading the post introducing the format for details of it’s design and reason for being developed.
Components #
This project consists of a core module Qoa.jai and two example programs: qoaplay and qoaconv.
The Jai module #
While Qoa itself supports up to 255 channels. This module sets a maximum channel count of 8.
The format only supports 16-bit samples, and supports sample rates from 1hz to 16Mhz.
The public API of the module is fairly sparse and now that it’s functional there needs to be a bit more consideration given to everything. In the meantime, here are the main things you’d be using:
Types #
-
Qoa_Status :: enum“OK” or one of several possible errors. -
Qoa_Desc :: structChannel count, sample rate, and samples per-channel. -
Qoa :: structA decoded byte buffer and aQoa_Descto define the format of the bytes.
Functions #
-
qoa_load_data :: (bytes: string) -> Qoa, Qoa_StatusDecode a byte buffer. -
qoa_load_file :: (filename: string) -> Qoa, Qoa_StatusLoad all bytes from a file and decode them withqoa_load_data. -
qoa_free :: (qoa: *Qoa)Free the decoded sample data.qoa, status := qoa_load_file("foo.qoa"); defer qoa_free(*qoa); -
qoa_samples :: (qoa: *Qoa) -> []s16Returns a sample array view into the decoded byte buffer. Samples are decoded inter-leaved when the file is multi-channel. -
qoa_encode_samples :: (qoa_desc: Qoa_Desc, samples: []s16) -> string, Qoa_StatusEncode the providedsamplesusing the format specified inqoa_descand return the resulting byte buffer. The buffer can be written to a file as-is.
Because Qoa is a frame based encoding, you can definitely decode individual frames instead of decoding the entire file at once. Until I’ve given the API more thought, the functions for actually encoding or decoding frames are file scoped.
string in the API but a string in Jai is synonymous with []u8 and I’m following the example of other modules shipped with the compiler. 🤷qoaplay #
qoaplay <path to input file>
Loads a qoa file and plays it using the Jai Sound_Player module.
Since the Sound_Player module doesn’t have direct support for Qoa files, this program serves as an example of how to initialize a Sound_Data struct to playback the decoded Qoa file.
qoaconv #
qoaconv <path to input file.wav> <path to output file.qoa>
Loads a standard uncompressed PCM wav file, encodes it as qoa, and writes the results to the location specified.