SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
audiocompressor.cpp
Go to the documentation of this file.
1 // Copyright (C) 2018 F4EXB //
3 // written by Edouard Griffiths //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #include "audiocompressor.h"
20 
24 
25 
27 {
28  fillLUT2();
29 }
30 
32 {}
33 
35 {
36  for (int i=0; i<8192; i++) {
37  m_lut[i] = (24576/8192)*i;
38  }
39 
40  for (int i=8192; i<2*8192; i++) {
41  m_lut[i] = 24576 + 0.5f*(i-8192);
42  }
43 
44  for (int i=2*8192; i<3*8192; i++) {
45  m_lut[i] = 24576 + 4096 + 0.25f*(i-2*8192);
46  }
47 
48  for (int i=3*8192; i<4*8192; i++) {
49  m_lut[i] = 24576 + 4096 + 2048 + 0.125f*(i-3*8192);
50  }
51 }
52 
54 {
55  for (int i=0; i<4096; i++) {
56  m_lut[i] = (24576/4096)*i;
57  }
58 
59  for (int i=4096; i<2*4096; i++) {
60  m_lut[i] = 24576 + 0.5f*(i-4096);
61  }
62 
63  for (int i=2*4096; i<3*4096; i++) {
64  m_lut[i] = 24576 + 2048 + 0.25f*(i-2*4096);
65  }
66 
67  for (int i=3*4096; i<4*4096; i++) {
68  m_lut[i] = 24576 + 2048 + 1024 + 0.125f*(i-3*4096);
69  }
70 
71  for (int i=4*4096; i<5*4096; i++) {
72  m_lut[i] = 24576 + 2048 + 1024 + 512 + 0.0625f*(i-4*4096);
73  }
74 
75  for (int i=5*4096; i<6*4096; i++) {
76  m_lut[i] = 24576 + 2048 + 1024 + 512 + 256 + 0.03125f*(i-5*4096);
77  }
78 
79  for (int i=6*4096; i<7*4096; i++) {
80  m_lut[i] = 24576 + 2048 + 1024 + 512 + 256 + 128 + 0.015625f*(i-6*4096);
81  }
82 
83  for (int i=7*4096; i<8*4096; i++) {
84  m_lut[i] = 24576 + 2048 + 1024 + 512 + 256 + 128 + 64 + 0.0078125f*(i-7*4096);
85  }
86 }
87 
89 {
90  for (int i=-16384; i<16384; i++) {
91  m_lut[i+16384] = ALaw_Encode(2*i);
92  }
93 }
94 
96 {
97  for (int i=-16384; i<16384; i++) {
98  m_lut[i+16384] = MuLaw_Encode(2*i);
99  }
100 }
101 
103 {
104  int16_t sign = sample < 0 ? -1 : 1;
105  int16_t abs = sample < 0 ? -sample : sample;
106  return sign * m_lut[abs];
107 }
108 
110 {
111  return m_lut[sample/2 + 16384];
112 }
113 
114 /* http://dystopiancode.blogspot.com/2012/02/pcm-law-and-u-law-companding-algorithms.html
115  *
116  * First, the number is verified is its negative. If the number is negative he will be made
117  * positive and the sign variable (by default 0) will contain the value 0x80
118  * (so when it's OR-ed to the coded result it will determine it's sign).
119  *
120  * Since the A-Law algorithm considers numbers in the range 0x000 - 0xFFF
121  * (without considering the sign bit), if a number is bigger than 0xFFF, it will automatically
122  * made equal to 0xFFF in order to avoid further problems.
123  *
124  * The first step in determining the coded value is finding the position of the first bit
125  * who has a 1 value (excluding the sign bit). The search is started from position 11
126  * and is continued until a bit with the value 1 is find or until a position smaller than 5 is met.
127  *
128  * If the position is smaller than 5 (there was no 1 bit found on the positions 11-5),
129  * the least significant byte of the coded number is made equal the the bits 5,4,3,2
130  * of the original number. Otherwise the least significant bit of the coded number is equal
131  * to the first four bits who come after the first 1 bit encountered.
132  *
133  * In the end, the most significant byte of the coded number is computed according to the position
134  * of the first 1 bit (if not such this was found, then the position is considered).
135  *
136  * Also, before returning the result, the even bits of the result will be complemented
137  * (by XOR-ing with 0x55).
138  */
140 {
141  uint16_t mask = 0x800;
142  uint8_t sign = 0;
143  uint8_t position = 11;
144  uint8_t lsb = 0;
145 
146  if (number < 0)
147  {
148  number = -number;
149  sign = 0x80;
150  }
151 
152  if (number > ALAW_MAX) {
153  number = ALAW_MAX;
154  }
155 
156  for (; ((number & mask) != mask && position >= 5); mask >>= 1, position--) {
157  }
158 
159  lsb = (number >> ((position == 4) ? (1) : (position - 4))) & 0x0f;
160 
161  return (sign | ((position - 4) << 4) | lsb) ^ 0x55;
162 }
163 
164 /* http://dystopiancode.blogspot.com/2012/02/pcm-law-and-u-law-companding-algorithms.html
165  *
166  * The µ-Law compression algorithm is very similar to the A-Law compression algorithm.
167  * The main difference is that the µ-Law uses 13 bits instead of 12 bits, so the position
168  * variable will be initialized with 12 instead of 11. In order to make sure that there will be
169  * no number without a 1 bit in the first 12-5 positions, a bias value is added to the number
170  * (in this case 33). So, since there is no special case (numbers who do not have a 1 bit in
171  * the first 12-5 positions), this makes the algorithm less complex by eliminating some condtions.
172  *
173  * Also in the end all bits are complemented, not just the even ones.
174  */
176 {
177  uint16_t mask = 0x1000;
178  uint8_t sign = 0;
179  uint8_t position = 12;
180  uint8_t lsb = 0;
181 
182  if (number < 0)
183  {
184  number = -number;
185  sign = 0x80;
186  }
187 
188  number += MULAW_BIAS;
189 
190  if (number > MULAW_MAX) {
191  number = MULAW_MAX;
192  }
193 
194  for (; ((number & mask) != mask && position >= 5); mask >>= 1, position--) {
195  }
196 
197  lsb = (number >> (position - 4)) & 0x0f;
198 
199  return (~(sign | ((position - 5) << 4) | lsb));
200 }
short int16_t
Definition: rtptypes_win.h:43
int8_t MuLaw_Encode(int16_t number)
static const uint16_t MULAW_MAX
Fixed< IntType, IntBits > abs(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2313
int8_t compress8(int16_t sample)
void fillLUT2()
8 bands (default)
static const uint16_t MULAW_BIAS
unsigned char uint8_t
Definition: rtptypes_win.h:42
int16_t m_lut[32768]
unsigned short uint16_t
Definition: rtptypes_win.h:44
int32_t i
Definition: decimators.h:244
char int8_t
Definition: rtptypes_win.h:41
void fillALaw()
A-law compression to 8 bits.
int8_t ALaw_Encode(int16_t number)
void fillULaw()
u-law compression to 8 bits
int16_t compress(int16_t sample)
static const uint16_t ALAW_MAX
void fillLUT()
4 bands