Skip to content

Commit 2ff4632

Browse files
committed
updated docs for clarity
1 parent b7fe963 commit 2ff4632

File tree

3 files changed

+63
-51
lines changed

3 files changed

+63
-51
lines changed

README.md

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,26 @@
22

33
# Companders (a fixed point audio compression library)
44

5-
(c) 2001-2017 M. A. Chatterjee < deftio [at] deftio [dot] com >
5+
(c) 2001-2019 M. A. Chatterjee
66

7-
This document is a brief overview of the simple audio compression library for microcontrollers using A-Law (a type of compander). This uses fixed-radix (integer only) math with
7+
This document is a brief overview of this simple audio compression library for microcontrollers using A-Law (a type of compander). This uses fixed-radix (integer only) math with
88
a small introductory disucssion and use of associated DC-offset correction with an IIR fixed-radix filter.
99

1010
## Welcome..
1111

1212
The accompanying companders.c contains a small set of functions written in C using only integer math for companding operations. I developed this several years ago for use in several embedded interized math projects and this small, slightly cleaned up version is made available for the public here. It worked very well on M*CORE, 80x86 and ARM processors for small embedded systems.
1313

14-
update: 2016 -- minor edits to this read (changed to markdown format). updated license information (still free but uses OSI approved text now!)
14+
Usage:
1515

16-
17-
usage:
18-
```
16+
```C
1917
#include "companders.h" //no other dependancies or libaries are required.
2018

21-
#compile and link companders.c
19+
// .. in code then
20+
int myCompandedValue = DIO_LinearToALaw(123); // convert the integer to is A-Law equivalent companded value
2221

22+
int unCompandedValue = DIO_ALawToLinear(myCompandedValue); // convert back to linear range. (with appropriate loss)
2323
```
2424

25-
## License
26-
See attached LICENSE.txt file (OSI approved BSD)
27-
28-
Copyright (c) 2001-2016, M. A. Chatterjee < deftio at deftio dot com >
29-
All rights reserved.
30-
31-
Redistribution and use in source and binary forms, with or without
32-
modification, are permitted provided that the following conditions are met:
33-
34-
* Redistributions of source code must retain the above copyright notice, this
35-
list of conditions and the following disclaimer.
36-
37-
* Redistributions in binary form must reproduce the above copyright notice,
38-
this list of conditions and the following disclaimer in the documentation
39-
and/or other materials provided with the distribution.
40-
41-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
42-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
45-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
47-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
48-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51-
52-
## Versions
53-
* 1.0.1 3 Sep 2012 -- original release
54-
* 1.0.2 15 Jul 2016 -- updated README.md to markdown format. updated license to be OSI compliant. no code changes. some minor doc updates. Thanks to John R Strohm giving me the nudge to update the docs here.
5525

5626

5727
## About companding...
@@ -61,6 +31,8 @@ Companding is a special type of lossy compression in which linear format samples
6131
Theory of how companding works:
6232
Suppose that we have a signed 16 bit linear sample in 2's complement math. The range of this sample can vary from -32768 to + 32767 in integer steps. Now lets put the constraint that we only have 8 bits with which to represent the data not the full 16 bits of the original linear number. A simple way to preserve high order information would be to linearly truncate off the lower 8 bits giving us a signed number from -128 to +127. We could make a mental note to keep track of the fact that we lost the lower 8 bits and so when use this representation we multiply by 8 bits (or 256) to preserve the input range.
6333
so:
34+
35+
```C
6436
-128 * 256 = -32768
6537
-127 * 256 = -32512
6638
...
@@ -71,7 +43,8 @@ so:
7143
...
7244
126 * 256 = 32256
7345
127 * 256 = 32512
74-
46+
```
47+
7548
Notice that the steps between these linearly rounded off samples are quite large. This truncated 8 bit representation would be very good at representing a linear quantity system such as linear displacement transducer which moves through its whole range as part of normal operation (like a door). but terrible at logarithmic phenomonen such as audio. Audio information tends to be grouped around zero with occaisonaly peaks of loudness. So with linear quantization soft audio would be lost due to the large quanitization steps at low volumes. To address this companders were developed for use in landline telephony for compressing audio data logarithmically instead of linearly. Hence we use more bits for audio samples near zero and less with audio samples near the integer max extremes.
7649

7750
A-Law and it cousin mu-Law are companders. Rather than represent samples in linear steps the more bits are allocated to samples near zero while larger magnitude (positive or negative) samples are represented with proportionately larger interval sizes.
@@ -109,8 +82,10 @@ uC_ADC_Pin<-----------C---- audio_input_source
10982
R
11083
|
11184
GND
85+
11286
```
11387

88+
11489
However cheap resistors have tolerances 5 to 10%, so the setpoint voltage could easily be anywhere from 1.4 to 1.8V. To address this software should read the ADC before audio is coming in and determine the actual DC bias voltage set by the real world resistors. Then when audio is coming in this value is subtracted from the ADC input to give a signed number which is fed to the LinearToAlaw encoder.
11590

11691
If it not easily possible to turn off the analog / audio source then the long term DC average can be inferred by using one of the IIR functions included here with a long window length (perhaps 2000 samples if sampling at 8 KHz or about 1/4 second). These IIR functions are cheap to run in realtime even with reasonably high sample rates as they take little memory and are simple integer-math IIRs.
@@ -121,21 +96,22 @@ The (Infinite Impulse Reponse) IIR functions included here use fixed radix math
12196

12297
To calculate how many bits of fractional part while preventing overflow use the following formulas:
12398

124-
```
125-
Nb = number of bits in use = ceiling(log2(highest_number_represented))
99+
```C
100+
Nb = number_of_bits_in_use = ceiling(log2(highest_number_represented))
126101

127102
radix = 32-Nb(sample_resolution)-Nb(WindowLength)-2
128103

129-
for example if you have a ADC generating counts from 0 to 1023 then the Nb(ADC-range) =
130-
Nb = ceiling(log2(1023)) = 10 bits
104+
//for example if you have a ADC generating counts from 0 to 1023 then the Nb(ADC-range) =
105+
Nb = ceiling(log2(1023)) = 10 // bits
131106

132-
If you use a DC average window length of 2000
133-
Nb = ceiling(log2(2000)) = 11 bits
107+
//If you use a DC average window length of 2000
108+
Nb = ceiling(log2(2000)) = 11 // bits
134109

135-
so the max radix that should be specified is:
136-
radix = 32 - 10 - 11 - 2 = 32 - 23 = 9 bits
110+
//so the max radix that should be specified is:
111+
radix = 32 - 10 - 11 - 2 = 32 - 23 = 9 // bits
137112

138113
```
114+
139115
with 9 bits in the radix fractional precision of 512 units per integer (e.g 1/512) is possible. The "2" in for formula comes from reserving bits for the sign bit and the additional operation in averager.
140116

141117

@@ -149,13 +125,14 @@ Now back to an embedded microcontroller example. Let's say it has an ADC which
149125
Our "guess" as to the bias = both resistors are the same = (3.3V/2) =1.65V = (1.65V)/(4095 counts/3.3V)= 2048 counts
150126

151127
Resistor actual set bias "zero point" = 1.55V = (1.55V) *(4095 counts/3.3V)) = 1923 counts
152-
We want this to be "zero" we use for the companded A/D process.
128+
We want this to be "zero" we use for the companded A/D process.
153129

154130
To do this we start our ADC to periodically sample for sometime before we start "recording" audio. We will feed the ADC values in to our IIR average to find the actual zero point. Note that even when we decide not to "record" we still can still run the A/D and IIR averager so its adapting to the real zero point.
155131

156132

157133
## C-like Pseudo code
158-
```
134+
135+
```C
159136
#include "companders.h"
160137

161138
static volatile int32 gIIRavg= 2048; // global static var holds DC average as estimated by the IIR
@@ -198,12 +175,45 @@ main()
198175

199176

200177
}
201-
178+
202179
```
203180
The accompanying compandit.c file is an example program demonstrating the convergence of the averager to a simulated DC offset value (output is in the testout.txt file).
204181

205-
### Some Closing comments..
182+
### Some Closing comments..
183+
206184
Finally, it can be in some systems that we can't turn off the audio input source it may be hard wired to some sensor or mic or perhaps the A/D center bias circuit (the 2 resistors) always is on when the audio is on. In this case running the IIR with a long filter length all the time can remove the bias even when the audio is running. For example in an 8KHz sampling system with an IIR length of 1024 is about 1/8 of a second or a cutoff freq well below 10Hz and costs almost nothing to run.
207185

208186

187+
## Versions
188+
189+
* 1.0.1 3 Sep 2012 -- original release
190+
* 1.0.2 15 Jul 2016 -- updated README.md to markdown format. updated license to be OSI compliant. no code changes. some minor doc updates. Thanks to John R Strohm giving me the nudge to update the docs here.
191+
* 1.0.3 28 Jul 2019 -- updated docs, ver example
192+
209193

194+
## License
195+
See attached LICENSE.txt file (OSI approved BSD 2.0)
196+
197+
Copyright (c) 2001-2019, M. A. Chatterjee < deftio at deftio dot com >
198+
All rights reserved.
199+
200+
Redistribution and use in source and binary forms, with or without
201+
modification, are permitted provided that the following conditions are met:
202+
203+
* Redistributions of source code must retain the above copyright notice, this
204+
list of conditions and the following disclaimer.
205+
206+
* Redistributions in binary form must reproduce the above copyright notice,
207+
this list of conditions and the following disclaimer in the documentation
208+
and/or other materials provided with the distribution.
209+
210+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
211+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
212+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
213+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
214+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
216+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
217+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
218+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
219+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

companders.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ extern "C"
4545
{
4646
#endif
4747

48+
#define DIO_COMPANDERS_VER (0x000010003) //00 01 00 03 in hex
49+
4850
//"DIO" prefixes are to assist in prevent name collisions if global namespace is used.
4951

5052
//typedefs ... change for platform dependant register size

makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ compandit: $(OBJ)
1414
gcc -o $@ $^ $(CFLAGS) -lm
1515

1616
clean :
17-
rm *.o
17+
rm *.o -f
1818

0 commit comments

Comments
 (0)