arduino-audio-tools
Loading...
Searching...
No Matches
CodecCodec2.h
Go to the documentation of this file.
1
18#pragma once
19
21#include "codec2.h"
22
23
24namespace audio_tools {
25
27int getCodec2Mode(int bits_per_second) {
28 switch (bits_per_second) {
29 case 3200:
30 return CODEC2_MODE_3200;
31 case 2400:
32 return CODEC2_MODE_2400;
33 case 1600:
34 return CODEC2_MODE_1600;
35 case 1400:
36 return CODEC2_MODE_1400;
37 case 1300:
38 return CODEC2_MODE_1300;
39 case 1200:
40 return CODEC2_MODE_1200;
41 case 700:
42 return CODEC2_MODE_700C;
43 case 450:
44 return CODEC2_MODE_450;
45 default:
46 LOGE(
47 "Unsupported sample rate: use 3200, 2400, 1600, 1400, 1300, 1200, "
48 "700 or 450");
49 return -1;
50 }
51}
52
62 public:
63 Codec2Decoder(int bps = 3200) {
64 info.sample_rate = 8000;
65 info.channels = 1;
68 }
69
70 virtual const char *mime() override { return "audio/codec2"; }
71
74 virtual void setBitsPerSecond(int bps) { bits_per_second = bps; }
75
77
78 virtual bool begin() {
79 TRACEI();
80
82 if (mode == -1) {
83 LOGE("invalid bits_per_second")
84 return false;
85 }
86 if (info.channels != 1) {
87 LOGE("Only 1 channel supported")
88 return false;
89 }
90 if (info.bits_per_sample != 16) {
91 LOGE("Only 16 bps are supported")
92 return false;
93 }
94 if (info.sample_rate != 8000) {
95 LOGW("Sample rate should be 8000: %d", info.sample_rate);
96 }
97
98 p_codec2 = codec2_create(mode);
99 if (p_codec2 == nullptr) {
100 LOGE("codec2_create");
101 return false;
102 }
103
106
109
111 LOGI("bytesCompressed:%d", bytesCompressed());
112 LOGI("bytesUncompressed:%d", bytesUncompressed());
113 is_active = true;
114 return true;
115 }
116
118 return p_codec2 != nullptr ? codec2_bytes_per_frame(p_codec2) : 0;
119 }
120
122 return p_codec2 != nullptr
123 ? codec2_samples_per_frame(p_codec2) * sizeof(int16_t)
124 : 0;
125 }
126
127
128 virtual void end() {
129 TRACEI();
130 codec2_destroy(p_codec2);
131 is_active = false;
132 }
133
134 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
135
136 operator bool() { return is_active; }
137
138 size_t write(const uint8_t *data, size_t len) override {
139 LOGD("write: %d", len);
140 if (!is_active) {
141 LOGE("inactive");
142 return 0;
143 }
144
145 uint8_t *p_byte = (uint8_t *)data;
146 for (int j = 0; j < len; j++) {
147 processByte(p_byte[j]);
148 }
149
150 return len;
151 }
152
153 protected:
154 Print *p_print = nullptr;
155 struct CODEC2 *p_codec2;
156 bool is_active = false;
159 int input_pos = 0;
161
163 void processByte(uint8_t byte) {
164 // add byte to buffer
165 input_buffer[input_pos++] = byte;
166
167 // decode if buffer is full
168 if (input_pos >= input_buffer.size()) {
169 codec2_decode(p_codec2, (short*)result_buffer.data(), input_buffer.data());
170 int written = p_print->write((uint8_t *)result_buffer.data(), result_buffer.size());
171 if (written != result_buffer.size()){
172 LOGE("write: %d written: %d", result_buffer.size(), written);
173 } else {
174 LOGD("write: %d written: %d", result_buffer.size(), written);
175 }
176 delay(2);
177 input_pos = 0;
178 }
179 }
180};
181
191 public:
192 Codec2Encoder(int bps = 3200) {
193 info.sample_rate = 8000;
194 info.channels = 1;
196 setBitsPerSecond(bps);
197 }
198
201 virtual void setBitsPerSecond(int bps) { bits_per_second = bps; }
202
204
206 return p_codec2 != nullptr ? codec2_bytes_per_frame(p_codec2) : 0;
207 }
208
210 return p_codec2 != nullptr
211 ? codec2_samples_per_frame(p_codec2) * sizeof(int16_t)
212 : 0;
213 }
214
215 bool begin() {
216 TRACEI();
217
218 int mode = getCodec2Mode(bits_per_second);
219 if (mode == -1) {
220 LOGE("invalid bits_per_second")
221 return false;
222 }
223 if (info.channels != 1) {
224 LOGE("Only 1 channel supported")
225 return false;
226 }
227 if (info.bits_per_sample != 16) {
228 LOGE("Only 16 bps are supported")
229 return false;
230 }
231 if (info.sample_rate != 8000) {
232 LOGW("Sample rate should be 8000: %d", info.sample_rate);
233 }
234
235 p_codec2 = codec2_create(mode);
236 if (p_codec2 == nullptr) {
237 LOGE("codec2_create");
238 return false;
239 }
240
245 LOGI("bytesCompressed:%d", bytesCompressed());
246 LOGI("bytesUncompressed:%d", bytesUncompressed());
247 is_active = true;
248 return true;
249 }
250
251 virtual void end() {
252 TRACEI();
253 codec2_destroy(p_codec2);
254 is_active = false;
255 }
256
257 virtual const char *mime() { return "audio/codec2"; }
258
259 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
260
261 operator bool() { return is_active; }
262
263 size_t write(const uint8_t *in_ptr, size_t in_size) override {
264 LOGD("write: %d", in_size);
265 if (!is_active) {
266 LOGE("inactive");
267 return 0;
268 }
269 // encode bytes
270 uint8_t *p_byte = (uint8_t *)in_ptr;
271 for (int j = 0; j < in_size; j++) {
272 processByte(p_byte[j]);
273 }
274 return in_size;
275 }
276
277 protected:
278 Print *p_print = nullptr;
279 struct CODEC2 *p_codec2 = nullptr;
280 bool is_active = false;
281 int buffer_pos = 0;
285
286 // add byte to decoding buffer and decode if buffer is full
287 void processByte(uint8_t byte) {
288 input_buffer[buffer_pos++] = byte;
289 if (buffer_pos >= input_buffer.size()) {
290 // encode
291 codec2_encode(p_codec2, result_buffer.data(),
292 (short*)input_buffer.data());
293 int written = p_print->write(result_buffer.data(), result_buffer.size());
294 if(written!=result_buffer.size()){
295 LOGE("write: %d written: %d", result_buffer.size(), written);
296 } else {
297 LOGD("write: %d written: %d", result_buffer.size(), written);
298 }
299 buffer_pos = 0;
300 }
301 }
302};
303
304} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define assert(T)
Definition avr.h:10
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:19
AudioInfo info
Definition AudioCodecsBase.h:80
Encoding of PCM data.
Definition AudioCodecsBase.h:101
AudioInfo info
Definition AudioCodecsBase.h:120
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:175
Decoder for Codec2. Depends on https://github.com/pschatzmann/arduino-libcodec2.
Definition CodecCodec2.h:61
Codec2Decoder(int bps=3200)
Definition CodecCodec2.h:63
int bytesUncompressed()
Definition CodecCodec2.h:121
int input_pos
Definition CodecCodec2.h:159
struct CODEC2 * p_codec2
Definition CodecCodec2.h:155
virtual void setOutput(Print &out_stream)
Defines where the decoded result is written to.
Definition CodecCodec2.h:134
int bytesCompressed()
Definition CodecCodec2.h:117
bool is_active
Definition CodecCodec2.h:156
virtual void setBitsPerSecond(int bps)
Definition CodecCodec2.h:74
Vector< uint8_t > result_buffer
Definition CodecCodec2.h:158
virtual bool begin()
Definition CodecCodec2.h:78
virtual const char * mime() override
Provides the mime type of the data that is expected by this decoder.
Definition CodecCodec2.h:70
size_t write(const uint8_t *data, size_t len) override
Definition CodecCodec2.h:138
int bitsPerSecond()
Definition CodecCodec2.h:76
int bits_per_second
Definition CodecCodec2.h:160
void processByte(uint8_t byte)
Build decoding buffer and decode when frame is full.
Definition CodecCodec2.h:163
Print * p_print
Definition CodecCodec2.h:154
virtual void end()
Definition CodecCodec2.h:128
Vector< uint8_t > input_buffer
Definition CodecCodec2.h:157
Encoder for Codec2 - Depends on https://github.com/pschatzmann/arduino-libcodec2.
Definition CodecCodec2.h:190
int bytesUncompressed()
Definition CodecCodec2.h:209
struct CODEC2 * p_codec2
Definition CodecCodec2.h:279
virtual void setOutput(Print &out_stream)
Default output assignment (encoders may override to store Print reference)
Definition CodecCodec2.h:259
int bytesCompressed()
Definition CodecCodec2.h:205
bool is_active
Definition CodecCodec2.h:280
virtual void setBitsPerSecond(int bps)
Definition CodecCodec2.h:201
Vector< uint8_t > result_buffer
Definition CodecCodec2.h:283
bool begin()
Definition CodecCodec2.h:215
size_t write(const uint8_t *in_ptr, size_t in_size) override
Definition CodecCodec2.h:263
virtual const char * mime()
Provides the mime type of the encoded result.
Definition CodecCodec2.h:257
int bitsPerSecond()
Definition CodecCodec2.h:203
int buffer_pos
Definition CodecCodec2.h:281
int bits_per_second
Definition CodecCodec2.h:284
void processByte(uint8_t byte)
Definition CodecCodec2.h:287
Print * p_print
Definition CodecCodec2.h:278
virtual void end()
Definition CodecCodec2.h:251
Vector< uint8_t > input_buffer
Definition CodecCodec2.h:282
Codec2Encoder(int bps=3200)
Definition CodecCodec2.h:192
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(size_t 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 LMSEchoCancellationStream.h:6
void delay(uint32_t ms)
Definition Arduino.h:259
int getCodec2Mode(int bits_per_second)
Convert bits per sample to Codec2 mode.
Definition CodecCodec2.h:27
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57