arduino-audio-tools
CodecG7xx.h
1 #pragma once
2 #include "AudioTools/AudioCodecs/AudioCodecsBase.h"
3 
4 extern "C"{
5  #include "g72x.h"
6 }
7 
8 
9 namespace audio_tools {
10 
17 enum G7xxCODEC_e {g723_24, g721, g723_40, others};
18 
27 class G7xxDecoder : public AudioDecoder {
28  public:
29  G7xxDecoder(G7xxCODEC_e codec) {
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 
128 class 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 
235 class G721Decoder : public G7xxDecoder {
236  public:
237  G721Decoder() : G7xxDecoder(g721) {};
238 };
246 class G721Encoder : public G7xxEncoder {
247  public:
248  G721Encoder() : G7xxEncoder(g721) {};
249 };
257 class G723_24Decoder : public G7xxDecoder {
258  public:
259  G723_24Decoder() : G7xxDecoder(g723_24) {};
260 };
268 class G723_24Encoder : public G7xxEncoder {
269  public:
270  G723_24Encoder() : G7xxEncoder(g723_24) {};
271 };
279 class G723_40Decoder : public G7xxDecoder {
280  public:
281  G723_40Decoder() : G7xxDecoder(g723_40) {};
282 };
290 class G723_40Encoder : public G7xxEncoder {
291  public:
292  G723_40Encoder() : G7xxEncoder(g723_40) {};
293 };
294 
303 class 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 
337 class 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
Docoding of encoded audio into PCM data.
Definition: AudioCodecsBase.h:16
virtual void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition: AudioCodecsBase.h:26
Encoding of PCM data.
Definition: AudioCodecsBase.h:84
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition: AudioCodecsBase.h:93
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
const char * mime() override
Provides the mime type of the encoded result.
Definition: CodecG7xx.h:172
virtual void setAudioInfo(AudioInfo info)
Defines the sample rate, number of channels and bits per sample.
Definition: CodecG7xx.h:174
Definition: NoArduino.h:58
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:868
G7xxCODEC_e
Supported codecs by G7xxDecoder and G7xxEncoder.
Definition: CodecG7xx.h:17
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:52
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