arduino-audio-tools
Loading...
Searching...
No Matches
CodecG729.h
Go to the documentation of this file.
1
10#pragma once
11
12#include <bcg729.h> // https://github.com/pschatzmann/codec-bcg729
13
15
16namespace audio_tools {
17
18// G.729 frame sizes
19static constexpr size_t G729_SAMPLES_PER_FRAME = 80; // 10 ms @ 8 kHz
20static constexpr size_t G729_PCM_SIZE =
21 G729_SAMPLES_PER_FRAME * 2; // 160 bytes PCM16
22static constexpr size_t G729_ENC_SIZE = 10; // 10 bytes speech frame
23static constexpr size_t G729_SID_SIZE = 2; // 2 bytes SID frame
24static AudioInfo audioInfoG729{8000, 1, 16};
25
48class G729Decoder : public AudioDecoder {
49 public:
51
52 void setAudioInfo(AudioInfo info) override {
53 // Check if requested format is valid
54 if (info != audioInfoG729) {
55 LOGE(
56 "G.729 encoder input is fixed to 8000 Hz, mono, 16-bit PCM "
57 "(requested: %d Hz, %d ch, %d bit)",
59 }
60 // update when changed to trigger notifications, even though the actual format is fixed
62 }
63
64 bool begin() override {
65 TRACEI();
66 end();
67
70
72 if (decoder_ctx == nullptr) {
73 LOGE("initBcg729DecoderChannel");
74 return false;
75 }
76
77 input_pos = 0;
78 is_active = true;
80 return true;
81 }
82
83 void end() override {
84 TRACEI();
85 if (decoder_ctx != nullptr) {
87 decoder_ctx = nullptr;
88 }
89 input_pos = 0;
90 is_active = false;
91 }
92
94
95 operator bool() override { return is_active; }
96
97 size_t write(const uint8_t* data, size_t len) override {
98 LOGD("write: %d", static_cast<int>(len));
99
100 if (!is_active) {
101 LOGE("inactive");
102 return 0;
103 }
104 if (p_print == nullptr) {
105 LOGE("output not set");
106 return 0;
107 }
108
109 // Fast path: if the caller supplies a complete framed payload and the
110 // accumulator is empty, decode directly so SID (2-byte) and speech
111 // (10-byte) frame boundaries are preserved.
112 if (input_pos == 0 && (len == G729_ENC_SIZE || len == G729_SID_SIZE)) {
113 decodeFrame(data, len);
114 return len;
115 }
116
117 // Stream mode: accumulate bytes into 10-byte speech frames.
118 for (size_t j = 0; j < len; ++j) {
119 processByte(data[j]);
120 }
121
122 return len;
123 }
124
125 protected:
126 Print* p_print = nullptr;
130 size_t input_pos = 0;
131 bool is_active = false;
132
133 void processByte(uint8_t byte) {
135
136 if (input_pos >= G729_ENC_SIZE) {
138 input_pos = 0;
139 }
140 }
141
142 void decodeFrame(const uint8_t* data, size_t frame_len) {
144 LOGW("unsupported G729 frame size: %d", static_cast<int>(frame_len));
145 return;
146 }
147
149
150 bcg729Decoder(decoder_ctx, const_cast<uint8_t*>(data),
151 static_cast<uint8_t>(frame_len),
152 0, // frameErasureFlag
153 sid_frame, // SIDFrameFlag
154 0, // rfc3389PayloadFlag
155 reinterpret_cast<int16_t*>(result_buffer.data()));
156
158 }
159};
160
186class G729Encoder : public AudioEncoder {
187 public:
192
193 void setVADEnabled(bool enabled) { vad_enabled = enabled; }
194
195 void setAudioInfo(AudioInfo info) override {
196 // Check if requested format is valid
197 if (info != audioInfoG729) {
198 LOGE(
199 "G.729 encoder input is fixed to 8000 Hz, mono, 16-bit PCM "
200 "(requested: %d Hz, %d ch, %d bit)",
202 }
203 // update when changed to trigger notifications, even though the actual format is fixed
205 }
206
207 bool begin() override {
208 TRACEI();
209 end();
210
212 if (encoder_ctx == nullptr) {
213 LOGE("initBcg729EncoderChannel");
214 return false;
215 }
216
219 buffer_pos = 0;
220 is_active = true;
221 return true;
222 }
223
224 void end() override {
225 TRACEI();
226 if (encoder_ctx != nullptr) {
228 encoder_ctx = nullptr;
229 }
230 buffer_pos = 0;
231 is_active = false;
232 }
233
234 const char* mime() override { return "audio/g729"; }
235
237
238 operator bool() override { return is_active; }
239
240 size_t write(const uint8_t* data, size_t len) override {
241 LOGD("write: %d", static_cast<int>(len));
242
243 if (!is_active) {
244 LOGE("inactive");
245 return 0;
246 }
247 if (p_print == nullptr) {
248 LOGE("output not set");
249 return 0;
250 }
251
252 for (size_t j = 0; j < len; ++j) {
253 processByte(data[j]);
254 }
255 return len;
256 }
257
258 protected:
259 Print* p_print = nullptr;
263 size_t buffer_pos = 0;
264 bool vad_enabled = false;
265 bool is_active = false;
266
267 void processByte(uint8_t byte) {
269
270 if (buffer_pos >= G729_PCM_SIZE) {
272
274 reinterpret_cast<const int16_t*>(input_buffer.data()),
276
277 if (result_len > result_buffer.size()) {
278 LOGE("Encoder: result buffer too small: %d -> %d",
279 static_cast<int>(result_buffer.size()),
280 static_cast<int>(result_len));
281 } else if (result_len > 0) {
283 }
284
285 buffer_pos = 0;
286 }
287 }
288};
289
290} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
AudioInfo info
Definition AudioCodecsBase.h:76
void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition AudioCodecsBase.h:28
Encoding of PCM data.
Definition AudioCodecsBase.h:97
AudioInfo info
Definition AudioCodecsBase.h:116
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition AudioCodecsBase.h:106
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:178
G.729 decoder using the bcg729 library.
Definition CodecG729.h:48
void setOutput(Print &out_stream) override
Defines where the decoded result is written to.
Definition CodecG729.h:93
bool is_active
Definition CodecG729.h:131
Vector< uint8_t > result_buffer
Definition CodecG729.h:129
G729Decoder()
Definition CodecG729.h:50
void end() override
Definition CodecG729.h:83
size_t write(const uint8_t *data, size_t len) override
Definition CodecG729.h:97
void decodeFrame(const uint8_t *data, size_t frame_len)
Definition CodecG729.h:142
void processByte(uint8_t byte)
Definition CodecG729.h:133
bool begin() override
Definition CodecG729.h:64
Print * p_print
Definition CodecG729.h:126
void setAudioInfo(AudioInfo info) override
for most decoders this is not needed
Definition CodecG729.h:52
size_t input_pos
Definition CodecG729.h:130
Vector< uint8_t > input_buffer
Definition CodecG729.h:128
bcg729DecoderChannelContextStruct * decoder_ctx
Definition CodecG729.h:127
G.729 encoder using the bcg729 library.
Definition CodecG729.h:186
void setOutput(Print &out_stream) override
Default output assignment (encoders may override to store Print reference)
Definition CodecG729.h:236
bool vad_enabled
Definition CodecG729.h:264
bool is_active
Definition CodecG729.h:265
bcg729EncoderChannelContextStruct * encoder_ctx
Definition CodecG729.h:260
Vector< uint8_t > result_buffer
Definition CodecG729.h:262
void end() override
Definition CodecG729.h:224
void setVADEnabled(bool enabled)
Definition CodecG729.h:193
size_t write(const uint8_t *data, size_t len) override
Definition CodecG729.h:240
G729Encoder(bool is_vad_enabled=false)
Definition CodecG729.h:188
void processByte(uint8_t byte)
Definition CodecG729.h:267
const char * mime() override
Provides the mime type of the encoded result.
Definition CodecG729.h:234
bool begin() override
Definition CodecG729.h:207
Print * p_print
Definition CodecG729.h:259
void setAudioInfo(AudioInfo info) override
Defines the sample rate, number of channels and bits per sample.
Definition CodecG729.h:195
size_t buffer_pos
Definition CodecG729.h:263
Vector< uint8_t > input_buffer
Definition CodecG729.h:261
Definition NoArduino.h:62
virtual size_t write(const uint8_t *data, size_t len)
Definition NoArduino.h:126
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(int newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
static constexpr size_t G729_PCM_SIZE
Definition CodecG729.h:20
static AudioInfo audioInfoG729
Definition CodecG729.h:24
static constexpr size_t G729_ENC_SIZE
Definition CodecG729.h:22
static constexpr size_t G729_SID_SIZE
Definition CodecG729.h:23
static constexpr size_t G729_SAMPLES_PER_FRAME
Definition CodecG729.h:19
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:55
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:57
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61