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