-
Notifications
You must be signed in to change notification settings - Fork 4
/
README
89 lines (72 loc) · 4.54 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
////////////////////////////////////////////////////////////////////////////
// ****** SLAC ****** //
// Simple Lossless Audio Compressor //
// Copyright (c) 2019 - 2022 David Bryant //
// All Rights Reserved. //
// Distributed under the BSD Software License (see license.txt) //
////////////////////////////////////////////////////////////////////////////
Update: 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:
1. Learning how lossless audio compressors work, or the starting point for
your own lossless codec experiments.
2. Easily incorporating lossless audio compression into other apps, perhaps
even including translation into another language.
3. 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:
$ gcc -O2 *.c -o slac
The "help" display from the demo app:
Usage: SLAC [-options] infile.wav outfile.slac
SLAC -d [-options] infile.slac outfile.wav
Pipes: specify '-' for filename, but not WAV output
Options: -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:
1. 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.
2. 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.
3. 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.
4. 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).
5. 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.