****** SLAC ****** |
---|
Simple Lossless Audio Compressor |
Copyright (c) 2019 - 2022 David Bryant. |
All Rights Reserved. |
Distributed under the BSD Software License (see license.txt) |
Since I developed and named this codec I have been made aware of a proprietary audio compression algorithm from Texas Instruments for its CC85xx line of chips (and perhaps others) also called SLAC (Slightly Lossy Audio Codec). There is no relation between the two codecs (mine is completely original and neither lossy nor proprietary). I apologize for any confusion.
A very simple lossless audio compressor. Designed to achieve about the same compression as flac -0 or shorten with the absolute minimum amount of complexity (in fact, the entire library for both encoding and decoding is a single C file of less than 500 lines). Being so simple, it's also pretty quick, even in pure C without multithreading. Possible uses:
- Learning how lossless audio compressors work, or the starting point for your own lossless codec experiments.
- Easily incorporating lossless audio compression into other apps, perhaps even including translation into another language.
- Implementing lossless audio compression on limited resource systems, or even hardware.
It's important to note that this is NOT a new lossless audio compression file format! There is a simple command-line front end for demo purposes that works with WAV files, but the resulting SLAC files are simply a concatenation of the generated blocks and provide no metadata storage, no error detection, and no seeking capability. The format COULD be used inside of another container format like Matroska, but I'm not sure that would have any value.
To build the demo app:
$ make
or
$ make SHARED=Y
or
$ gcc -Wall -O2 src/*.c -o slac
slac [-options] infile.wav outfile.slac
slac -d [-options] infile.slac outfile.wav
Specify -
for filename, but not WAV output
-d = decode operation (default = encode))
-bn = override block samples (default = 1024)
-h = display this help message
-j0 = encode stereo files as L/R
-j1 = encode stereo files as M/S (default)
-j2 = encode stereo files using best (slow)
-q = quiet mode (display errors only)
-r = raw output (no WAV header written)
-v = verbose (display lots of info)
-y = overwrite outfile if it exists
The compression algorithm uses only standard techniques:
-
The audio data samples are divided into blocks. By default these are 1024 samples but can be essentially any size (there are trade-offs) and this step is actually done by the client of the library.
-
For stereo data, a check is made for identical channels (dual-mono), otherwise the data is optionally converted to mid-side (which on average compresses better), or simply left as left-right.
-
The data is scanned for redundant LSB zeros, and if these are found in all samples a right-shift is performed to reduce the sample magnitude. The size of the shift is stored in the output bitstream so that the samples can be left-shifted at decode.
-
The decorrelation method is simply pure deltas (i.e. each sample is replaced with the difference between it and the previous sample). This is repeated in passes and the resulting magnitude checked until the optimum number of passes is determined. This value (from -1 to 6) is stored with the audio and used on decode to re-correlate the audio samples. Note that the -1 value is for cases where the samples are negatively correlated (rare in music but possible in test cases).
-
The signed samples are converted to a nonnegative integer representation (with the sign in the LSB) and these are encoded with standard Rice codes. The optimum Golomb-Rice parameter k is determined by trial from just the sum of the values to be encoded. The first few un-decorrelated samples are encoded with their own Rice parameter because they often have wildly different magnitudes than the majority of the samples. Also, a check is made for all the samples being zero, in which case nothing is encoded.