IT++ Logo
g711.h
Go to the documentation of this file.
1
28#ifndef G711_H
29#define G711_H
30
31#include <itpp/itexports.h>
32#include <utility>
33#include <itpp/base/ittypes.h>
34
64namespace itpp {
65
67
68//forward declarations to make friends visible
69std::pair<int16_t,int16_t> ulaw_range();
70uint8_t ulaw_compress(int16_t s);
71int16_t ulaw_expand(uint8_t s);
72std::pair<int16_t,int16_t> alaw_range();
73uint8_t alaw_compress(int16_t s);
74int16_t alaw_expand(uint8_t s);
75
76
77namespace g711_details {
78 //This makes compression-expansion tables inaccessible in user's code
79 //while compression-expansion functions are still defined inline. Also, it
80 //hides property classes from itpp namespace.
81
82 //Base properties of G.711 codecs
83 class G711_Base_Properties
84 {
85 protected:
87 static ITPP_EXPORT uint8_t compression_table[128];
88 };
89
90 //u-law algorithm properties
91 class MuLaw_Properties : public G711_Base_Properties
92 {
93 //u-law codec input bitwidth
94 static const int input_bitwidth = 14;
95 //offset applied to magnitude of the input sample
96 static const int16_t magnitude_offset = 33;
97 //maximum input value according to G.711
98 static const int16_t input_max = 8158;
99 //minimum input value according to G.711
100 static const int16_t input_min = -8159;
101 //table used in u-law expansion
102 static ITPP_EXPORT int16_t expansion_table[256];
103
104 friend std::pair<int16_t,int16_t> itpp::ulaw_range();
105 friend uint8_t itpp::ulaw_compress(int16_t s);
106 friend int16_t itpp::ulaw_expand(uint8_t s);
107 };
108
109 //a-law algorithm properties
110 class ALaw_Properties : public G711_Base_Properties
111 {
112 //a-law codec input bitwidth
113 static const int input_bitwidth = 13;
114 //maximum input value according to G.711
115 static const int16_t input_max = 4095;
116 //minimum input value according to G.711
117 static const int16_t input_min = -4096;
118 //table used in u-law expansion
119 static ITPP_EXPORT int16_t expansion_table[256];
120
121 friend std::pair<int16_t,int16_t> itpp::alaw_range();
122 friend uint8_t itpp::alaw_compress(int16_t s);
123 friend int16_t itpp::alaw_expand(uint8_t s);
124 };
125}
127
132inline std::pair<int16_t,int16_t> ulaw_range()
133{
134 using namespace g711_details;
135 return std::make_pair(MuLaw_Properties::input_min,MuLaw_Properties::input_max);
136}
137
138
143inline uint8_t ulaw_compress(int16_t s)
144{
145 using namespace g711_details;
146 //Limiting and shifting. Negative samples are 1's complemented to align dynamic
147 //ranges of positive and negative numbers. Compressed negative
148 //and positive values of equal magnitude are distinguished by the sign bit.
149 //As per G.711 spec, resulting magnitude is shifted before compression.
150 uint8_t sign; uint16_t shifted_magnitude;
151 if(s >= 0){
152 if(s > MuLaw_Properties::input_max) s = MuLaw_Properties::input_max;
153 shifted_magnitude = s + MuLaw_Properties::magnitude_offset;
154 sign = 0xff;
155 }
156 else{
157 if(s < MuLaw_Properties::input_min) s = MuLaw_Properties::input_min;
158 shifted_magnitude = (MuLaw_Properties::magnitude_offset - 1) - s;
159 sign = 0x7f;
160 }
161 //use compression table to get the segment number. Segment number corresponds
162 //to the exponent value stored in compressed sample.
163 uint8_t seg_no = MuLaw_Properties::compression_table[shifted_magnitude>>6];
164 //extract 4 MSBs of magnitude, except leading 1, compose it with segment number
165 //and sign, store 1's complement value as compressed sample
166 uint8_t ret = (seg_no << 4) | ((shifted_magnitude >> (seg_no + 1)) & 0x0f);
167 ret ^= sign; //1's complement and add sign
168 return ret;
169}
170
176inline int16_t ulaw_expand(uint8_t s){return g711_details::MuLaw_Properties::expansion_table[s];}
177
182inline std::pair<int16_t,int16_t> alaw_range()
183{
184 using namespace g711_details;
185 return std::make_pair(ALaw_Properties::input_min,ALaw_Properties::input_max);
186}
187
192inline uint8_t alaw_compress(int16_t s)
193{
194 using namespace g711_details;
195 //Limiting. Negative samples are 1's complemented to align dynamic
196 //ranges of positive and negative numbers. Compressed negative
197 //and positive values of equal magnitude are distinguished by the sign bit.
198 uint8_t sign; uint16_t magnitude;
199 if(s >= 0){
200 if(s > ALaw_Properties::input_max) s = ALaw_Properties::input_max;
201 magnitude = s; sign = 0xd5;
202 }
203 else{//1's complement to get magnitude
204 if(s < ALaw_Properties::input_min) s = ALaw_Properties::input_min;
205 magnitude = -1 - s; sign = 0x55;
206 }
207 //use compression table to get the exponent.
208 uint8_t exp_val = ALaw_Properties::compression_table[magnitude>>5];
209 uint8_t ret;
210 if(exp_val > 0) {
211 //extract 4 MSBs of magnitude, except leading 1 and compose it with exponent
212 ret = (exp_val << 4) | ((magnitude >> (exp_val)) & 0x0f);
213 }
214 else{//exp is 0, store 4 MSBs of magnitude
215 ret = (uint8_t)magnitude >> 1;
216 }
217 ret ^= sign; //toggle even bits and add sign
218 return ret;
219}
220
226inline int16_t alaw_expand(uint8_t s){return g711_details::ALaw_Properties::expansion_table[s];}
227
228}
229
230#endif
int16_t alaw_expand(uint8_t s)
G.711 u-Law expansion function. Returns decoded value for previously compressed sample s....
Definition g711.h:226
uint8_t ulaw_compress(int16_t s)
G.711 u-Law compression function. Returns encoded value for sample s.
Definition g711.h:143
int16_t ulaw_expand(uint8_t s)
G.711 u-Law expansion function. Returns decoded value for previously compressed sample s....
Definition g711.h:176
std::pair< int16_t, int16_t > alaw_range()
G.711 a-Law compressor input range. Returns (min,max) input values in std::pair.
Definition g711.h:182
uint8_t alaw_compress(int16_t s)
G.711 a-Law compression function. Returns encoded value for sample s.
Definition g711.h:192
std::pair< int16_t, int16_t > ulaw_range()
G.711 u-Law compressor input range. Returns (min,max) input values in std::pair.
Definition g711.h:132
double sign(double x)
Signum function.
Definition elem_math.h:81
IT++ type definitions.
itpp namespace
Definition itmex.h:37

Generated on Tue Aug 17 2021 10:59:15 for IT++ by Doxygen 1.12.0