arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
CodecG7xx.h
1#pragma once
2#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
3
4extern "C"{
5 #include "g72x.h"
6}
7
8
9namespace audio_tools {
10
17enum G7xxCODEC_e {g723_24, g721, g723_40, others};
18
27class G7xxDecoder : public AudioDecoder {
28 public:
30 info.channels = 1;
31 info.sample_rate = 8000;
32 info.bits_per_sample = 16;
33
34 switch(codec){
35 case g723_24:
36 dec_routine = g723_24_decoder;
37 dec_bits = 3;
38 break;
39
40 case g721:
41 dec_routine = g721_decoder;
42 dec_bits = 4;
43 break;
44
45 case g723_40:
46 dec_routine = g723_40_decoder;
47 dec_bits = 5;
48 break;
49 }
50 }
51
52 void setAudioInfo(AudioInfo info) override {
53 bool ok = true;
54 if (info.channels!=1){
55 LOGE("channels must be 1 instead of %d", info.channels);
56 ok = false;
57 }
58 if (info.sample_rate!=8000){
59 LOGE("sample_rate must be 8000 instead of %d", info.sample_rate);
60 ok = false;
61 }
62 if (info.bits_per_sample!=16){
63 LOGE("bits_per_sample must be 16 instead of %d", info.bits_per_sample);
64 ok = false;
65 }
66 if (ok) AudioDecoder::setAudioInfo(info);
67 }
68
69 bool begin() override {
70 TRACEI();
71 in_buffer = 0;
72 in_bits = 0;
73 out_size = sizeof(int16_t);
74 g72x_init_state(&state);
75
76 is_active = true;
77 return true;
78 }
79
80 void end() override {
81 TRACEI();
82 is_active = false;
83 }
84
85 void setOutput(Print &out_stream) override { p_print = &out_stream; }
86
87 operator bool() { return is_active; }
88
89 size_t write(const uint8_t *data, size_t len) override {
90 LOGD("write: %d", len);
91 if (!is_active) {
92 LOGE("inactive");
93 return 0;
94 }
95
96 uint8_t *p_byte = (uint8_t *)data;
97 for (int j = 0; j < len; j++) {
98 sample = (*dec_routine)(p_byte[j], AUDIO_ENCODING_LINEAR, &state);
99 p_print->write((uint8_t*)&sample, out_size);
100 }
101
102 return len;
103 }
104
105 protected:
106 Print *p_print = nullptr;
107 int input_pos = 0;
108 bool is_active = false;
109 int16_t sample;
110 unsigned char code;
111 int n;
112 struct g72x_state state;
113 int out_size;
114 int (*dec_routine)(int code, int out_coding, struct g72x_state* state_ptr);
115 int dec_bits;
116 unsigned int in_buffer = 0;
117 int in_bits = 0;
118
119};
120
128class G7xxEncoder : public AudioEncoder {
129 public:
130 G7xxEncoder(G7xxCODEC_e codec) {
131 info.channels = 1;
132 info.sample_rate = 8000;
133 info.bits_per_sample = 16;
134
135 switch(codec){
136
137 case g721:
138 enc_routine = g721_encoder;
139 enc_bits = 4;
140 p_mime = "audio/g721";
141 break;
142
143 case g723_24:
144 enc_routine = g723_24_encoder;
145 enc_bits = 3;
146 p_mime = "audio/g723_24";
147 break;
148
149 case g723_40:
150 enc_routine = g723_40_encoder;
151 enc_bits = 5;
152 p_mime = "audio/g723_40";
153 break;
154 }
155 }
156
157 bool begin() override {
158 TRACEI();
159 g72x_init_state(&state);
160 out_buffer = 0;
161 out_bits = 0;
162
163 is_active = true;
164 return true;
165 }
166
167 void end() override {
168 TRACEI();
169 is_active = false;
170 }
171
172 const char *mime() override { return p_mime; }
173
174 virtual void setAudioInfo(AudioInfo info) {
175 bool ok = true;
176 if (info.channels!=1){
177 LOGE("channels must be 1 instead of %d", info.channels);
178 ok = false;
179 }
180 if (info.sample_rate!=8000){
181 LOGE("sample_rate must be 8000 instead of %d", info.sample_rate);
182 ok = false;
183 }
184 if (info.bits_per_sample!=16){
185 LOGE("bits_per_sample must be 16 instead of %d", info.bits_per_sample);
186 ok = false;
187 }
188 if (ok) AudioEncoder::setAudioInfo(info);
189 }
190
191 void setOutput(Print &out_stream) override { p_print = &out_stream; }
192
193 operator bool() { return is_active; }
194
195 size_t write(const uint8_t *data, size_t len) override {
196 LOGD("write: %d", len);
197 if (!is_active) {
198 LOGE("inactive");
199 return 0;
200 }
201 // encode bytes
202 int16_t *p_16 = (int16_t *)data;
203 int samples = len / sizeof(int16_t);
204 for (int j = 0; j < samples; j++) {
205 code = (*enc_routine)(p_16[j], AUDIO_ENCODING_LINEAR, &state);
206 p_print->write(&code, 1);
207 }
208
209 return len;
210 }
211
212 protected:
213 Print *p_print = nullptr;
214 bool is_active = false;
215 const char *p_mime = nullptr;
216 int resid;
217 struct g72x_state state;
218 unsigned char sample_char;
219 int16_t sample_int16;
220 unsigned char code;
221 int (*enc_routine)(int sample, int in_coding, struct g72x_state* state_ptr);
222 int enc_bits;
223 unsigned int out_buffer = 0;
224 int out_bits = 0;
225
226};
227
235class G721Decoder : public G7xxDecoder {
236 public:
237 G721Decoder() : G7xxDecoder(g721) {};
238};
246class G721Encoder : public G7xxEncoder {
247 public:
248 G721Encoder() : G7xxEncoder(g721) {};
249};
258 public:
259 G723_24Decoder() : G7xxDecoder(g723_24) {};
260};
269 public:
270 G723_24Encoder() : G7xxEncoder(g723_24) {};
271};
280 public:
281 G723_40Decoder() : G7xxDecoder(g723_40) {};
282};
291 public:
292 G723_40Encoder() : G7xxEncoder(g723_40) {};
293};
294
303class G711Encoder : public G7xxEncoder {
304 public:
305 G711Encoder(uint8_t(*enc)(int)) : G7xxEncoder(others) {
306 this->enc = enc;
307 assert(this->enc!=nullptr);
308 };
309 size_t write(const uint8_t *data, size_t len) override {
310 LOGD("write: %d", len);
311 if (!is_active) {
312 LOGE("inactive");
313 return 0;
314 }
315 // encode bytes
316 int samples = len/2;
317 int16_t *p_16 = (int16_t *)data;
318 uint8_t buffer[samples];
319 for (int j = 0; j < samples; j++) {
320 buffer[j] = enc(p_16[j]);
321 }
322 p_print->write(buffer,samples);
323 return len;
324 }
325 protected:
326 uint8_t(*enc)(int)=nullptr;
327};
328
337class G711Decoder : public G7xxDecoder {
338 public:
339 G711Decoder(int (*dec)(uint8_t a_val)) : G7xxDecoder(others) {
340 this->dec = dec;
341 assert(this->dec!=nullptr);
342 };
343
344 size_t write(const uint8_t *data, size_t len) override {
345 LOGD("write: %d", len);
346 if (!is_active) {
347 LOGE("inactive");
348 return 0;
349 }
350 // decode bytes
351 uint8_t *p_8 = (uint8_t *)data;
352 for (int j = 0; j < len; j++) {
353 int16_t result = dec(p_8[j]);
354 p_print->write((uint8_t*)&result,sizeof(int16_t));
355 }
356 return len;
357 }
358 protected:
359 int (*dec)(uint8_t a_val)=nullptr;
360};
361
362
371 public:
372 G711_ALAWEncoder() : G711Encoder(linear2alaw) {};
373};
374
383 public:
384 G711_ALAWDecoder() : G711Decoder(alaw2linear) {};
385};
386
395 public:
396 G711_ULAWEncoder() : G711Encoder(linear2ulaw) {};
397};
398
407 public:
408 G711_ULAWDecoder() : G711Decoder(ulaw2linear) {};
409};
410
411} // namespace audio_tools
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition AudioCodecsBase.h:28
Encoding of PCM data.
Definition AudioCodecsBase.h:90
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition AudioCodecsBase.h:99
64 kbit/s g711 ALOW Decoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:382
64 kbit/s g711 ALOW Encoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:370
64 kbit/s g711 ULOW Decoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:406
64 kbit/s g711 ULOW Encoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:394
64 kbit/s g711 ULOW Decoder based on https://github.com/pschatzmann/arduino-libg7xx Supported decoder...
Definition CodecG7xx.h:337
64 kbit/s g711 ULOW Encoder based on https://github.com/pschatzmann/arduino-libg7xx Supported encoder...
Definition CodecG7xx.h:303
32Kbps G721 Decoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:235
32Kbps G721 Encoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:246
24Kbps G723 Decoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:257
24Kbps G723 Encoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:268
40Kbps G723 Decoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:279
40Kbps G723 Encoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:290
g723_24, g721, g723_40 Decoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:27
void setOutput(Print &out_stream) override
Defines where the decoded result is written to.
Definition CodecG7xx.h:85
void setAudioInfo(AudioInfo info) override
for most decoders this is not needed
Definition CodecG7xx.h:52
g723_24, g721, g723_40 Encoder based on https://github.com/pschatzmann/arduino-libg7xx
Definition CodecG7xx.h:128
virtual void setAudioInfo(AudioInfo info)
Defines the sample rate, number of channels and bits per sample.
Definition CodecG7xx.h:174
const char * mime() override
Provides the mime type of the encoded result.
Definition CodecG7xx.h:172
Definition NoArduino.h:62
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
G7xxCODEC_e
Supported codecs by G7xxDecoder and G7xxEncoder.
Definition CodecG7xx.h:17
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:53
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:59