arduino-audio-tools
Loading...
Searching...
No Matches
AudioEncoded.h
1#pragma once
2
3#include "AudioConfig.h"
4#include "AudioLogger.h"
5#include "AudioTools/CoreAudio/AudioIO.h"
6#include "AudioTools/CoreAudio/AudioOutput.h"
7#include "AudioTools/CoreAudio/AudioStreams.h"
8#include "AudioTools/CoreAudio/AudioTypes.h"
9#include "AudioCodecsBase.h"
10
11namespace audio_tools {
12
22 public:
24 active = false;
25 }
26
28 setDecoder(decoder);
29 active = false;
30 }
31
33 setEncoder(encoder);
34 active = false;
35 }
36
38 setDecoder(decoder);
39 setOutput(outputStream);
40 active = false;
41 }
42
44 setDecoder(decoder);
45 setOutput(outputStream);
46 active = false;
47 }
48
50 setDecoder(decoder);
51 setOutput(outputStream);
52 active = false;
53 }
54
56 setEncoder(encoder);
57 setOutput(outputStream);
58 active = false;
59 }
60
62 setEncoder(encoder);
63 setOutput(outputStream);
64 active = false;
65 }
66
68 setEncoder(encoder);
69 setOutput(outputStream);
70 active = false;
71 }
72
75 TRACEI();
76 decoder_ptr->addNotifyAudioChange(bi);
77 }
78
79 AudioInfo defaultConfig() {
80 AudioInfo cfg;
81 cfg.channels = 2;
82 cfg.sample_rate = 44100;
83 cfg.bits_per_sample = 16;
84 return cfg;
85 }
86
87 virtual void setAudioInfo(AudioInfo newInfo) override {
88 TRACED();
89 if (this->cfg != newInfo && newInfo.channels != 0 && newInfo.sample_rate != 0) {
90 this->cfg = newInfo;
91 decoder_ptr->setAudioInfo(cfg);
92 encoder_ptr->setAudioInfo(cfg);
93 }
94 }
95
96
97 void setOutput(Print &outputStream) { setOutput(&outputStream); }
98
100 void setOutput(Print *outputStream) {
101 ptr_out = outputStream;
102 if (decoder_ptr != nullptr) {
103 decoder_ptr->setOutput(*ptr_out);
104 }
105 if (encoder_ptr != nullptr) {
106 encoder_ptr->setOutput(*ptr_out);
107 }
108 }
109
110 void setEncoder(AudioEncoder *encoder) {
111 if (encoder == nullptr) {
112 encoder = CodecNOP::instance();
113 }
114 encoder_ptr = encoder;
115 writer_ptr = encoder;
116 if (ptr_out != nullptr) {
117 encoder_ptr->setOutput(*ptr_out);
118 }
119 }
120
121 AudioEncoder *getEncoder() { return encoder_ptr; }
122
123 void setDecoder(AudioDecoder *decoder) {
124 if (decoder == nullptr) {
125 decoder = CodecNOP::instance();
126 }
127 decoder_ptr = decoder;
128 writer_ptr = decoder;
129 if (ptr_out != nullptr) {
130 decoder_ptr->setOutput(*ptr_out);
131 }
132 }
133
134 AudioDecoder *getDecoder() { return decoder_ptr; }
135
137 bool begin() override {
138#if USE_AUDIO_LOGGING
139 custom_log_level.set();
140#endif
141 TRACED();
142 if (!active) {
143 TRACED();
144 const CodecNOP *nop = CodecNOP::instance();
145 if (decoder_ptr != nop || encoder_ptr != nop) {
146 active = true;
147 if (!decoder_ptr->begin(cfg)) active = false;
148 if (!encoder_ptr->begin(cfg)) active = false;
149 } else {
150 LOGW("no decoder or encoder defined");
151 }
152 }
153#if USE_AUDIO_LOGGING
154 custom_log_level.reset();
155#endif
156 return active;
157 }
158
160 virtual bool begin(AudioInfo newInfo) {
161 cfg = newInfo;
162 return begin();
163 }
164
166 void end() override {
167#if USE_AUDIO_LOGGING
168 custom_log_level.set();
169#endif
170 TRACEI();
171 decoder_ptr->end();
172 encoder_ptr->end();
173 active = false;
174#if USE_AUDIO_LOGGING
175 custom_log_level.reset();
176#endif
177 }
178
180 virtual size_t write(const uint8_t *data, size_t len) override {
181 if (len == 0) {
182 //LOGI("write: %d", 0);
183 return 0;
184 }
185#if USE_AUDIO_LOGGING
186 custom_log_level.set();
187#endif
188 LOGD("EncodedAudioOutput::write: %d", (int)len);
189
190 if (writer_ptr == nullptr || data == nullptr) {
191 LOGE("NPE");
192 return 0;
193 }
194
195 if (check_available_for_write && availableForWrite() == 0) {
196 return 0;
197 }
198
199 size_t result = writer_ptr->write(data, len);
200 LOGD("EncodedAudioOutput::write: %d -> %d", (int)len, (int)result);
201#if USE_AUDIO_LOGGING
202 custom_log_level.reset();
203#endif
204 return result;
205 }
206
207 int availableForWrite() override {
208 if (!check_available_for_write) return frame_size;
209 return min(ptr_out->availableForWrite(), frame_size);
210 }
211
213 operator bool() { return active; }
214
216 AudioDecoder &decoder() { return *decoder_ptr; }
217
219 AudioEncoder &encoder() { return *encoder_ptr; }
220
221#if USE_AUDIO_LOGGING
223 void setLogLevel(AudioLogger::LogLevel level) { custom_log_level.set(level); }
224#endif
226 bool isCheckAvailableForWrite() { return check_available_for_write; }
227
229 void setFrameSize(int size) { frame_size = size; }
230
231 protected:
232 // AudioInfo info;
233 AudioDecoder *decoder_ptr = CodecNOP::instance(); // decoder
234 AudioEncoder *encoder_ptr = CodecNOP::instance(); // decoder
235 AudioWriter *writer_ptr = nullptr;
236 Print *ptr_out = nullptr;
237 bool active = false;
238 bool check_available_for_write = false;
239#if USE_AUDIO_LOGGING
240 CustomLogLevel custom_log_level;
241#endif
242 int frame_size = DEFAULT_BUFFER_SIZE;
243};
244
245// legacy name
246using EncodedAudioPrint = EncodedAudioOutput;
247
256 public:
257 EncodedAudioStream() = default;
258
260 setDecoder(decoder);
261 setStream(*ioStream);
262 }
263
265 setDecoder(decoder);
266 setStream(*ioStream);
267 }
268
270 setDecoder(decoder);
271 setOutput(*outputStream);
272 }
273
275 setDecoder(decoder);
276 setOutput(*outputStream);
277 }
278
280 setEncoder(encoder);
281 setOutput(*outputStream);
282 }
283
285
287
288 void setEncoder(AudioEncoder *encoder) { enc_out.setEncoder(encoder); }
289
290 void setDecoder(AudioDecoder *decoder) { enc_out.setDecoder(decoder); }
291
292 AudioEncoder *getEncoder() { return enc_out.getEncoder(); }
293
294 AudioDecoder *getDecoder() { return enc_out.getDecoder(); }
295
297 AudioDecoder &decoder() { return *getDecoder(); }
298
300 AudioEncoder &encoder() { return *getEncoder(); }
301
302 void setStream(Stream *stream) {
303 setStream(*stream);
304 }
305
306 void setStream(AudioStream *stream) {
307 setStream(*stream);
308 }
309
310 void setOutput(AudioOutput *stream) {
311 setOutput(*stream);
312 }
313
314 void setOutput(Print *stream) {
315 setOutput(*stream);
316 }
317
318 void setStream(AudioStream &stream) {
320 enc_out.setOutput(&stream);
321 }
322
323 void setStream(Stream &stream) {
325 enc_out.setOutput(&stream);
326 }
327
328 void setOutput(AudioOutput &stream) {
329 ReformatBaseStream::setOutput(stream);
330 enc_out.setOutput(&stream);
331 }
332
333 void setOutput(Print &out) {
334 ReformatBaseStream::setOutput(out);
335 enc_out.setOutput(&out);
336 }
337
338 AudioInfo defaultConfig() {
339 AudioInfo ai;
340 return ai;
341 }
342
343 bool begin(AudioInfo info) {
344 setAudioInfo(info);
345 return begin();
346 }
347
348 bool begin() {
349 //is_output_notify = false;
350 setupReader();
351 ReformatBaseStream::begin();
352 return enc_out.begin(audioInfo());
353 }
354
355 void end() {
356 enc_out.end();
357 reader.end();
358 }
359
360 int availableForWrite() { return enc_out.availableForWrite(); }
361
362 size_t write(const uint8_t *data, size_t len) {
363 //addNotifyOnFirstWrite();
364 return enc_out.write(data, len);
365 }
366
367 size_t readBytes(uint8_t *data, size_t len) {
368 return reader.readBytes(data, len);
369 }
370
372 enc_out.addNotifyAudioChange(bi);
373 }
374
376 float getByteFactor() { return byte_factor; }
377 void setByteFactor(float factor) {byte_factor = factor;}
378
379#if USE_AUDIO_LOGGING
381 void setLogLevel(AudioLogger::LogLevel level) { enc_out.setLogLevel(level); }
382#endif
383
385 void setFrameSize(int size) { enc_out.setFrameSize(size); }
386
387 protected:
388 EncodedAudioOutput enc_out;
389 float byte_factor = 2.0f;
390
391};
392
401 public:
402 void setWriter(AudioWriter *writer) { p_writer = writer; }
403 size_t write(const uint8_t *data, size_t len) {
404 return p_writer->write(data, len);
405 };
406
407 protected:
408 AudioWriter *p_writer = nullptr;
409};
410
419 public:
420 virtual bool begin() = 0;
421 virtual void end() = 0;
422 virtual void setAudioInfo(AudioInfo info) {
423 if (this->info != info && info.channels != 0 && info.sample_rate != 0) {
424 this->info = info;
425 if (p_writer1 != nullptr) p_writer1->setAudioInfo(info);
426 if (p_writer2 != nullptr) p_writer2->setAudioInfo(info);
427 }
428 }
429 virtual size_t write(uint8_t *data, size_t size) = 0;
430
431 protected:
432 AudioInfo info;
433 AudioWriter *p_writer1 = nullptr;
434 AudioWriter *p_writer2 = nullptr;
436 bool active = false;
437};
438
440 public:
441 void setupOutput(AudioWriter *writer1, AudioWriter *writer2, Print &print) {
442 p_print = &print;
443 p_writer1 = writer1;
444 p_writer2 = writer2;
445 print2.setWriter(p_writer2);
446 }
447
448 void setupOutput(AudioWriter *writer1, Print &print) {
449 p_print = &print;
450 p_writer1 = writer1;
451 }
452
453 virtual bool begin() {
454 if (!active) {
455 active = true;
456 if (p_writer2 != nullptr) {
457 p_writer1->setOutput(print2);
458 p_writer2->setOutput(*p_print);
459 p_writer1->begin();
460 p_writer2->begin();
461 } else {
462 p_writer1->setOutput(*p_print);
463 p_writer1->begin();
464 }
465 }
466 return true;
467 }
468 virtual void end() {
469 if (active) {
470 if (p_writer1 != nullptr) p_writer1->end();
471 if (p_writer2 != nullptr) p_writer2->end();
472 }
473 active = false;
474 }
475 virtual size_t write(uint8_t *data, size_t size) {
476 TRACED();
477 return p_writer1->write(data, size);
478 }
479
480 protected:
481 Print *p_print = nullptr;
483};
484
485} // namespace audio_tools
Docoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:16
virtual void setOutput(AudioStream &out_stream)
Defines where the decoded result is written to.
Definition AudioCodecsBase.h:34
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
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition AudioTypes.h:162
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:139
Base class for Output Adpapters.
Definition AudioIO.h:225
Abstract Audio Ouptut class.
Definition AudioOutput.h:22
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:113
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:121
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition BaseStream.h:144
E.g. used by Encoders and Decoders.
Definition AudioTypes.h:224
virtual void setAudioInfo(AudioInfo from)=0
Defines the input AudioInfo.
Adapter class which lets an AudioWriter behave like a Print.
Definition AudioEncoded.h:400
Dummy no implmentation Codec. This is used so that we can initialize some pointers to decoders and en...
Definition AudioCodecsBase.h:118
ContainerTarget: forwards requests to both the output and the encoder/decoder and sets up the output ...
Definition AudioEncoded.h:418
Definition AudioEncoded.h:439
A more natural Print class to process encoded data (aac, wav, mp3...). Just define the output and the...
Definition AudioEncoded.h:21
virtual size_t write(const uint8_t *data, size_t len) override
encoder decode the data
Definition AudioEncoded.h:180
void addNotifyAudioChange(AudioInfoSupport &bi) override
Define object which need to be notified if the basinfo is changing.
Definition AudioEncoded.h:74
virtual bool begin(AudioInfo newInfo)
Starts the processing - sets the status to active.
Definition AudioEncoded.h:160
void end() override
Ends the processing.
Definition AudioEncoded.h:166
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:229
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:216
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:219
bool begin() override
Starts the processing - sets the status to active.
Definition AudioEncoded.h:137
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition AudioEncoded.h:87
bool isCheckAvailableForWrite()
Is Available for Write check activated ?
Definition AudioEncoded.h:226
void setOutput(Print &outputStream)
Defines/Changes the output target.
Definition AudioEncoded.h:97
void setOutput(Print *outputStream)
Defines the output.
Definition AudioEncoded.h:100
A more natural Stream class to process encoded data (aac, wav, mp3...) which also supports the decodi...
Definition AudioEncoded.h:255
void addNotifyAudioChange(AudioInfoSupport &bi) override
Adds target to be notified about audio changes.
Definition AudioEncoded.h:371
void setStream(Stream &stream)
Defines/Changes the input & output.
Definition AudioEncoded.h:323
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:385
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:297
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:300
float getByteFactor()
approx compression factor: e.g. mp3 is around 4
Definition AudioEncoded.h:376
void setOutput(Print &out)
Defines/Changes the output target.
Definition AudioEncoded.h:333
Abstract class: Objects can be put into a pipleline.
Definition AudioOutput.h:97
Definition NoArduino.h:58
Base class for chained converting streams.
Definition AudioIO.h:154
virtual void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioIO.h:156
Definition NoArduino.h:125
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioConfig.h:877
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