arduino-audio-tools
Loading...
Searching...
No Matches
CodecLC3.h
Go to the documentation of this file.
1
11#pragma once
12
14#include "lc3.h"
15
16namespace audio_tools {
17
18// 20 to 400
19#define DEFAULT_BYTE_COUNT 40
20// 7500 or 10000
21#define LC3_DEFAULT_DT_US 7500
22
31class LC3Decoder : public AudioDecoder {
32 public:
34 uint16_t inputByteCount = DEFAULT_BYTE_COUNT) {
35 this->dt_us = dt_us;
36 this->info = info;
37 this->input_byte_count = inputByteCount;
38 }
39
41 uint16_t inputByteCount = DEFAULT_BYTE_COUNT) {
42 this->dt_us = dt_us;
43 this->input_byte_count = inputByteCount;
44 info.sample_rate = 32000;
46 info.channels = 1;
47 }
48
49 virtual bool begin() {
50 TRACEI();
51
52 // Return the number of PCM samples in a frame
53 num_frames = lc3_frame_samples(dt_us, info.sample_rate);
54 dec_size = lc3_decoder_size(dt_us, info.sample_rate);
55
56 LOGI("channels: %d", info.channels);
57 LOGI("sample_rate: %d", info.sample_rate);
58 LOGI("input_byte_count: %d", input_byte_count);
59 LOGI("dt_us: %d", dt_us);
60 LOGI("num_frames: %d", num_frames);
61 LOGI("dec_size: %d", dec_size);
62
63 if (!checkValues()) {
64 LOGE("Invalid Parameters");
65 return false;
66 }
67
68 // setup memory
72
73 // setup decoder
74 lc3_decoder = lc3_setup_decoder(dt_us, info.sample_rate, 0,
75 (void *)lc3_decoder_memory.data());
77
78 input_pos = 0;
79 active = true;
80 return true;
81 }
82
83 virtual void end() {
84 TRACEI();
85 active = false;
86 }
87
88 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
89
90 operator bool() { return active; }
91
92 virtual size_t write(const uint8_t *data, size_t len) {
93 if (!active) return 0;
94 LOGD("write %u", len);
95
96 uint8_t *p_ptr8 = (uint8_t *)data;
97
98 for (int j = 0; j < len; j++) {
99 input_buffer[input_pos++] = p_ptr8[j];
100 if (input_pos >= input_buffer.size()) {
101 if (lc3_decode(lc3_decoder, input_buffer.data(), input_buffer.size(),
102 pcm_format, (int16_t *)output_buffer.data(), 1) != 0) {
103 LOGE("lc3_decode");
104 }
105
106 // write all data to final output
107 int requested = output_buffer.size();
108 int written =
109 p_print->write((const uint8_t *)output_buffer.data(), requested);
110 if (written != requested) {
111 LOGE("Decoder Bytes requested: %d - written: %d", requested, written);
112 }
113 input_pos = 0;
114 }
115 }
116 return len;
117 }
118
119 protected:
120 Print *p_print = nullptr;
121 lc3_decoder_t lc3_decoder = nullptr;
122 lc3_pcm_format pcm_format;
126 size_t input_pos = 0;
127 int dt_us;
128 uint16_t input_byte_count = 20; // up to 400
129 uint16_t num_frames;
130 unsigned dec_size;
131 bool active = false;
132
133 bool checkValues() {
134 if (p_print == nullptr) {
135 LOGE("Output is not defined");
136 return false;
137 }
138
139 if (!LC3_CHECK_DT_US(dt_us)) {
140 LOGE("dt_us: %d", dt_us);
141 return false;
142 }
143
144 if (!LC3_CHECK_SR_HZ(info.sample_rate)) {
145 LOGE("sample_rate: %d", info.sample_rate);
146 return false;
147 }
148
149 if (info.channels!=1){
150 LOGE("channels: %d", info.channels);
151 }
152
153 if (num_frames == -1) {
154 LOGE("num_frames could not be determined - using m");
155 return false;
156 }
157
158 if (dec_size == 0) {
159 LOGE("dec_size");
160 return false;
161 }
162
163 switch (info.bits_per_sample) {
164 case 16:
165 pcm_format = LC3_PCM_FORMAT_S16;
166 break;
167 case 24:
168 pcm_format = LC3_PCM_FORMAT_S24;
169 break;
170 default:
171 LOGE("Bits per sample not supported: %d", info.bits_per_sample);
172 return false;
173 }
174 return true;
175 }
176};
177
186class LC3Encoder : public AudioEncoder {
187 public:
189 uint16_t outputByteCount = DEFAULT_BYTE_COUNT) {
190 this->dt_us = dt_us;
191 info.sample_rate = 32000;
193 info.channels = 1;
194 output_byte_count = outputByteCount;
195 }
196
197 bool begin() {
198 TRACEI();
199
200 unsigned enc_size = lc3_encoder_size(dt_us, info.sample_rate);
201 num_frames = lc3_frame_samples(dt_us, info.sample_rate);
202
203 LOGI("sample_rate: %d", info.sample_rate);
204 LOGI("channels: %d", info.channels);
205 LOGI("dt_us: %d", dt_us);
206 LOGI("output_byte_count: %d", output_byte_count);
207 LOGI("enc_size: %d", enc_size);
208 LOGI("num_frames: %d", num_frames);
209
210 if (!checkValues()) {
211 return false;
212 }
213
214 // setup memory
215 lc3_encoder_memory.resize(enc_size);
218
219 // setup encoder
220 lc3_encoder = lc3_setup_encoder(dt_us, info.sample_rate, 0,
222
223 input_pos = 0;
224 active = true;
225 return true;
226 }
227
228 virtual void end() {
229 TRACEI();
230 active = false;
231 }
232
233 virtual const char *mime() { return "audio/lc3"; }
234
235 virtual void setOutput(Print &out_stream) { p_print = &out_stream; }
236
237 operator bool() { return lc3_encoder != nullptr; }
238
239 virtual size_t write(const uint8_t *data, size_t len) {
240 if (!active) return 0;
241 LOGD("write %u", len);
242 uint8_t *p_ptr8 = (uint8_t *)data;
243
244 for (int j = 0; j < len; j++) {
245 input_buffer[input_pos++] = p_ptr8[j];
246 if (input_pos >= num_frames * 2) {
247 if (lc3_encode(lc3_encoder, pcm_format,
248 (const int16_t *)input_buffer.data(), 1,
250 LOGE("lc3_encode");
251 }
252
253 // write all data to final output
254 int requested = output_buffer.size();
255 int written = p_print->write(output_buffer.data(), requested);
256 if (written != requested) {
257 LOGE("Encoder Bytes requested: %d - written: %d", requested, written);
258 }
259 input_pos = 0;
260 }
261 }
262 return len;
263 }
264
265 protected:
266 Print *p_print = nullptr;
267 unsigned dt_us = 1000;
268 uint16_t num_frames;
269 lc3_encoder_t lc3_encoder = nullptr;
270 lc3_pcm_format pcm_format;
271 uint16_t output_byte_count = 20;
275 int input_pos = 0;
276 bool active = false;
277
278 bool checkValues() {
279 if (p_print == nullptr) {
280 LOGE("Output is not defined");
281 return false;
282 }
283
284 if (!LC3_CHECK_DT_US(dt_us)) {
285 LOGE("dt_us: %d", dt_us);
286 return false;
287 }
288
289 if (!LC3_CHECK_SR_HZ(info.sample_rate)) {
290 LOGE("sample_rate: %d", info.sample_rate);
291 return false;
292 }
293
294 if (info.channels!=1){
295 LOGE("channels: %d", info.channels);
296 }
297
298 if (num_frames == -1) {
299 LOGE("Invalid num_frames");
300 return false;
301 }
302
303 switch (info.bits_per_sample) {
304 case 16:
305 pcm_format = LC3_PCM_FORMAT_S16;
306 break;
307 case 24:
308 pcm_format = LC3_PCM_FORMAT_S24;
309 break;
310 default:
311 LOGE("Bits per sample not supported: %d", info.bits_per_sample);
312 return false;
313 }
314 return true;
315 }
316};
317
318} // namespace audio_tools
#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 DEFAULT_BYTE_COUNT
Definition CodecLC3.h:19
#define LC3_DEFAULT_DT_US
Definition CodecLC3.h:21
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:18
AudioInfo info
Definition AudioCodecsBase.h:76
Encoding of PCM data.
Definition AudioCodecsBase.h:97
AudioInfo info
Definition AudioCodecsBase.h:116
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:174
Decoder for LC3. Depends on https://github.com/pschatzmann/arduino-liblc3.
Definition CodecLC3.h:31
bool active
Definition CodecLC3.h:131
Vector< uint8_t > lc3_decoder_memory
Definition CodecLC3.h:123
virtual void setOutput(Print &out_stream)
Defines where the decoded result is written to.
Definition CodecLC3.h:88
virtual bool begin()
Definition CodecLC3.h:49
uint16_t num_frames
Definition CodecLC3.h:129
lc3_decoder_t lc3_decoder
Definition CodecLC3.h:121
LC3Decoder(int dt_us=7500, uint16_t inputByteCount=40)
Definition CodecLC3.h:40
LC3Decoder(AudioInfo info, int dt_us=7500, uint16_t inputByteCount=40)
Definition CodecLC3.h:33
unsigned dec_size
Definition CodecLC3.h:130
virtual size_t write(const uint8_t *data, size_t len)
Definition CodecLC3.h:92
lc3_pcm_format pcm_format
Definition CodecLC3.h:122
uint16_t input_byte_count
Definition CodecLC3.h:128
Print * p_print
Definition CodecLC3.h:120
size_t input_pos
Definition CodecLC3.h:126
virtual void end()
Definition CodecLC3.h:83
Vector< uint8_t > input_buffer
Definition CodecLC3.h:125
bool checkValues()
Definition CodecLC3.h:133
int dt_us
Definition CodecLC3.h:127
Vector< uint16_t > output_buffer
Definition CodecLC3.h:124
Encoder for LC3 - Depends on https://github.com/pschatzmann/arduino-liblc3.
Definition CodecLC3.h:186
bool active
Definition CodecLC3.h:276
int input_pos
Definition CodecLC3.h:275
virtual void setOutput(Print &out_stream)
Default output assignment (encoders may override to store Print reference)
Definition CodecLC3.h:235
Vector< uint8_t > output_buffer
Definition CodecLC3.h:273
uint16_t num_frames
Definition CodecLC3.h:268
bool begin()
Definition CodecLC3.h:197
virtual const char * mime()
Provides the mime type of the encoded result.
Definition CodecLC3.h:233
virtual size_t write(const uint8_t *data, size_t len)
Definition CodecLC3.h:239
unsigned dt_us
Definition CodecLC3.h:267
lc3_pcm_format pcm_format
Definition CodecLC3.h:270
uint16_t output_byte_count
Definition CodecLC3.h:271
lc3_encoder_t lc3_encoder
Definition CodecLC3.h:269
Print * p_print
Definition CodecLC3.h:266
LC3Encoder(int dt_us=7500, uint16_t outputByteCount=40)
Definition CodecLC3.h:188
virtual void end()
Definition CodecLC3.h:228
Vector< uint8_t > input_buffer
Definition CodecLC3.h:274
bool checkValues()
Definition CodecLC3.h:278
Vector< uint8_t > lc3_encoder_memory
Definition CodecLC3.h:272
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
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
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