arduino-audio-tools
Loading...
Searching...
No Matches
AudioEncoded.h
1#pragma once
2
3#include "AudioCodecsBase.h"
4#include "AudioToolsConfig.h"
5#include "AudioTools/CoreAudio/AudioLogger.h"
6#include "AudioTools/CoreAudio/AudioIO.h"
7#include "AudioTools/CoreAudio/AudioOutput.h"
8#include "AudioTools/CoreAudio/AudioStreams.h"
9#include "AudioTools/CoreAudio/AudioTypes.h"
10
11namespace audio_tools {
12
22 public:
23 EncodedAudioOutput() { active = false; }
24
26 setDecoder(decoder);
27 active = false;
28 }
29
31 setEncoder(encoder);
32 active = false;
33 }
34
36 setDecoder(decoder);
37 setOutput(outputStream);
38 active = false;
39 }
40
42 setDecoder(decoder);
43 setOutput(outputStream);
44 active = false;
45 }
46
48 setDecoder(decoder);
49 setOutput(outputStream);
50 active = false;
51 }
52
54 setEncoder(encoder);
55 setOutput(outputStream);
56 active = false;
57 }
58
60 setEncoder(encoder);
61 setOutput(outputStream);
62 active = false;
63 }
64
66 setEncoder(encoder);
67 setOutput(outputStream);
68 active = false;
69 }
70
71 virtual ~EncodedAudioOutput() { end(); }
72
75 TRACEI();
76 decoder_ptr->addNotifyAudioChange(bi);
77 }
78
79 AudioInfo defaultConfig() {
80 AudioInfo cfg;
81 return cfg;
82 }
83
84 virtual void setAudioInfo(AudioInfo newInfo) override {
85 TRACED();
86 if (this->cfg != newInfo && newInfo) {
87 this->cfg = newInfo;
88 decoder_ptr->setAudioInfo(cfg);
89 encoder_ptr->setAudioInfo(cfg);
90 }
91 }
92
94 AudioInfo audioInfo() override {
95 // return info from decoder if avilable
96 if (decoder_ptr != undefined && *decoder_ptr){
97 AudioInfo info = decoder_ptr->audioInfo();
98 if (info) return info;
99 }
101 }
102
104 void setOutput(Print *outputStream) {
105 ptr_out = outputStream;
106 if (decoder_ptr != undefined) {
107 decoder_ptr->setOutput(*ptr_out);
108 }
109 if (encoder_ptr != undefined) {
110 encoder_ptr->setOutput(*ptr_out);
111 }
112 }
113
114 void setOutput(AudioStream* out) {
115 setOutput((Print*)out);
116 to_notify = out;
117 }
118
119 void setOutput(AudioOutput*out){
120 setOutput((Print*)out);
121 to_notify = out;
122 }
123
124 void setOutput(Print &outputStream) override { setOutput(&outputStream); }
125 void setOutput(AudioOutput &outputStream) { setOutput(&outputStream); }
126 void setOutput(AudioStream &outputStream) { setOutput(&outputStream); }
127
128 void setEncoder(AudioEncoder *encoder) {
129 if (encoder == nullptr) {
130 encoder = undefined;
131 }
132 encoder_ptr = encoder;
133 writer_ptr = encoder;
134 if (ptr_out != nullptr) {
135 encoder_ptr->setOutput(*ptr_out);
136 }
137 }
138
139 AudioEncoder *getEncoder() { return encoder_ptr; }
140
141 void setDecoder(AudioDecoder *decoder) {
142 if (decoder == nullptr) {
143 decoder = undefined;
144 }
145 decoder_ptr = decoder;
146 writer_ptr = decoder;
147 if (ptr_out != nullptr) {
148 decoder_ptr->setOutput(*ptr_out);
149 }
150 }
151
152 AudioDecoder *getDecoder() { return decoder_ptr; }
153
155 bool begin() override {
156 TRACED();
157 if (!active) {
158 TRACED();
159 // Setup notification
160 if (to_notify != nullptr) {
161 decoder_ptr->addNotifyAudioChange(*to_notify);
162 }
163 // Get notifications from decoder
164 decoder_ptr->addNotifyAudioChange(*this);
165 if (decoder_ptr != undefined || encoder_ptr != undefined) {
166 active = true;
167 if (!decoder_ptr->begin(cfg)) active = false;
168 if (!encoder_ptr->begin(cfg)) active = false;
169 } else {
170 LOGW("no decoder or encoder defined");
171 }
172 }
173 return active;
174 }
175
177 virtual bool begin(AudioInfo newInfo) override {
178 setAudioInfo(newInfo);
179 return begin();
180 }
181
183 void end() override {
184 if (active) {
185 TRACEI();
186 decoder_ptr->end();
187 encoder_ptr->end();
188 active = false;
189 }
190 }
191
193 virtual size_t write(const uint8_t *data, size_t len) override {
194 if (len == 0) {
195 // LOGI("write: %d", 0);
196 return 0;
197 }
198 LOGD("EncodedAudioOutput::write: %d", (int)len);
199
200 if (writer_ptr == nullptr || data == nullptr) {
201 LOGE("NPE");
202 return 0;
203 }
204
205 if (check_available_for_write && availableForWrite() == 0) {
206 return 0;
207 }
208
209 size_t result = writer_ptr->write(data, len);
210 LOGD("EncodedAudioOutput::write: %d -> %d", (int)len, (int)result);
211 return result;
212 }
213
214 int availableForWrite() override {
215 if (!check_available_for_write) return frame_size;
216 return min(ptr_out->availableForWrite(), frame_size);
217 }
218
220 operator bool() override { return active; }
221
223 AudioDecoder &decoder() { return *decoder_ptr; }
224
226 AudioEncoder &encoder() { return *encoder_ptr; }
227
229 bool isCheckAvailableForWrite() { return check_available_for_write; }
230
232 void setFrameSize(int size) { frame_size = size; }
233
234 EncodedAudioOutput& operator=(EncodedAudioOutput const& src) {
235 decoder_ptr = src.decoder_ptr;
236 encoder_ptr = src.encoder_ptr;
237 ptr_out = src.ptr_out;
238 active = src.active;
239 check_available_for_write = src.check_available_for_write;
240 frame_size = src.frame_size;
241 cfg = src.cfg;
242 is_active = src.is_active;
243 return *this;
244 }
245
246
247 protected:
248 // AudioInfo info;
249 CodecNOP* undefined = CodecNOP::instance();
250 AudioDecoder *decoder_ptr = undefined; // decoder
251 AudioEncoder *encoder_ptr = undefined; // decoder
252 AudioWriter *writer_ptr = nullptr;
253 Print *ptr_out = nullptr;
254 AudioInfoSupport *to_notify = nullptr;
255 bool active = false;
256 bool check_available_for_write = false;
257 int frame_size = DEFAULT_BUFFER_SIZE;
258};
259
263
272 public:
273 EncodedAudioStream() = default;
274
276 setDecoder(decoder);
277 setStream(*ioStream);
278 }
279
281 setDecoder(decoder);
282 setStream(*ioStream);
283 }
284
286 setDecoder(decoder);
287 setOutput(*outputStream);
288 }
289
291 setDecoder(decoder);
292 setOutput(*outputStream);
293 }
294
296 setEncoder(encoder);
297 setOutput(*outputStream);
298 }
299
301
303
304 virtual ~EncodedAudioStream() { end(); }
305
306 void setEncoder(AudioEncoder *encoder) { enc_out.setEncoder(encoder); }
307
308 void setDecoder(AudioDecoder *decoder) { enc_out.setDecoder(decoder); }
309
310 AudioEncoder *getEncoder() { return enc_out.getEncoder(); }
311
312 AudioDecoder *getDecoder() { return enc_out.getDecoder(); }
313
315 AudioDecoder &decoder() { return *getDecoder(); }
316
318 AudioEncoder &encoder() { return *getEncoder(); }
319
320 void setStream(Stream *stream) { setStream(*stream); }
321
322 void setStream(AudioStream *stream) { setStream(*stream); }
323
324 void setOutput(AudioOutput *stream) { setOutput(*stream); }
325
326 void setOutput(Print *stream) { setOutput(*stream); }
327
328 void setStream(AudioStream &stream) override {
330 enc_out.setOutput(&stream);
331 }
332
333 void setStream(Stream &stream) override {
335 enc_out.setOutput(&stream);
336 }
337
338 void setOutput(AudioOutput &stream) override {
339 ReformatBaseStream::setOutput(stream);
340 enc_out.setOutput(&stream);
341 }
342
343 void setOutput(Print &out) override {
344 ReformatBaseStream::setOutput(out);
345 enc_out.setOutput(&out);
346 }
347
348 AudioInfo defaultConfig() {
349 AudioInfo ai;
350 return ai;
351 }
352
353 bool begin(AudioInfo info) {
354 setAudioInfo(info);
355 return begin();
356 }
357
358 bool begin() override {
359 // is_output_notify = false;
360 setupReader();
361 ReformatBaseStream::begin();
362 enc_out.addNotifyAudioChange(*this);
363 return enc_out.begin(audioInfo());
364 }
365
366 void end() override {
367 enc_out.end();
368 reader.end();
369 }
370
371 int availableForWrite() override { return enc_out.availableForWrite(); }
372
373 size_t write(const uint8_t *data, size_t len) override {
374 // addNotifyOnFirstWrite();
375 return enc_out.write(data, len);
376 }
377
378 size_t readBytes(uint8_t *data, size_t len) override {
379 return reader.readBytes(data, len);
380 }
381
383 enc_out.addNotifyAudioChange(bi);
384 }
385
387 float getByteFactor() override { return byte_factor; }
388 void setByteFactor(float factor) { byte_factor = factor; }
389
391 void setFrameSize(int size) { enc_out.setFrameSize(size); }
392
393 EncodedAudioStream& operator=(EncodedAudioStream const& src) {
394 enc_out = src.enc_out;
395 byte_factor = src.byte_factor;
396 p_stream = src.p_stream;
397 p_print = src.p_print;
398 info = src.info;
399 return *this;
400 };
401
402 AudioInfo audioInfo() override {
403 return enc_out.audioInfo();;
404 }
405
406 void setAudioInfo(AudioInfo newInfo) override {
408 enc_out.setAudioInfo(newInfo);
409 }
410
411 protected:
412 EncodedAudioOutput enc_out;
413 float byte_factor = 2.0f;
414};
415
424 public:
425 void setWriter(AudioWriter *writer) { p_writer = writer; }
426 size_t write(const uint8_t *data, size_t len) {
427 return p_writer->write(data, len);
428 };
429
430 protected:
431 AudioWriter *p_writer = nullptr;
432};
433
442 public:
443 virtual bool begin() = 0;
444 virtual void end() = 0;
445 virtual void setAudioInfo(AudioInfo info) {
446 if (this->info != info && info.channels != 0 && info.sample_rate != 0) {
447 this->info = info;
448 if (p_writer1 != nullptr) p_writer1->setAudioInfo(info);
449 if (p_writer2 != nullptr) p_writer2->setAudioInfo(info);
450 }
451 }
452 virtual size_t write(uint8_t *data, size_t size) = 0;
453
454 protected:
455 AudioInfo info;
456 AudioWriter *p_writer1 = nullptr;
457 AudioWriter *p_writer2 = nullptr;
459 bool active = false;
460};
461
463 public:
464 void setupOutput(AudioWriter *writer1, AudioWriter *writer2, Print &print) {
465 p_print = &print;
466 p_writer1 = writer1;
467 p_writer2 = writer2;
468 print2.setWriter(p_writer2);
469 }
470
471 void setupOutput(AudioWriter *writer1, Print &print) {
472 p_print = &print;
473 p_writer1 = writer1;
474 }
475
476 virtual bool begin() {
477 if (!active) {
478 active = true;
479 if (p_writer2 != nullptr) {
480 p_writer1->setOutput(print2);
481 p_writer2->setOutput(*p_print);
482 p_writer1->begin();
483 p_writer2->begin();
484 } else {
485 p_writer1->setOutput(*p_print);
486 p_writer1->begin();
487 }
488 }
489 return true;
490 }
491 virtual void end() {
492 if (active) {
493 if (p_writer1 != nullptr) p_writer1->end();
494 if (p_writer2 != nullptr) p_writer2->end();
495 }
496 active = false;
497 }
498 virtual size_t write(uint8_t *data, size_t size) {
499 TRACED();
500 return p_writer1->write(data, size);
501 }
502
503 protected:
504 Print *p_print = nullptr;
506};
507
508} // namespace audio_tools
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition AudioCodecsBase.h:28
virtual void setOutput(AudioStream &out_stream)
Defines where the decoded result is written to.
Definition AudioCodecsBase.h:36
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioCodecsBase.h:25
Encoding of PCM data.
Definition AudioCodecsBase.h:97
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition AudioCodecsBase.h:106
virtual void setOutput(Print &out_stream) override
Default output assignment (encoders may override to store Print reference)
Definition AudioCodecsBase.h:109
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition AudioTypes.h:153
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:135
virtual void setAudioInfo(AudioInfo info)=0
Defines the input AudioInfo.
Base class for Output Adpapters.
Definition AudioIO.h:231
Abstract Audio Ouptut class.
Definition AudioOutput.h:25
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioOutput.h:62
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:122
E.g. used by Encoders and Decoders.
Definition AudioTypes.h:209
virtual void setAudioInfo(AudioInfo from)=0
Defines the input AudioInfo.
Adapter class which lets an AudioWriter behave like a Print.
Definition AudioEncoded.h:423
ContainerTarget: forwards requests to both the output and the encoder/decoder and sets up the output ...
Definition AudioEncoded.h:441
Definition AudioEncoded.h:462
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:193
void addNotifyAudioChange(AudioInfoSupport &bi) override
Define object which need to be notified if the basinfo is changing.
Definition AudioEncoded.h:74
void end() override
Ends the processing.
Definition AudioEncoded.h:183
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:232
virtual bool begin(AudioInfo newInfo) override
Starts the processing - sets the status to active.
Definition AudioEncoded.h:177
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:223
void setOutput(Print &outputStream) override
Defines/Changes the output target.
Definition AudioEncoded.h:124
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:226
bool begin() override
Starts the processing - sets the status to active.
Definition AudioEncoded.h:155
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition AudioEncoded.h:84
bool isCheckAvailableForWrite()
Is Available for Write check activated ?
Definition AudioEncoded.h:229
AudioInfo audioInfo() override
Provide audio info from decoder if relevant.
Definition AudioEncoded.h:94
void setOutput(Print *outputStream)
Defines the output.
Definition AudioEncoded.h:104
A more natural Stream class to process encoded data (aac, wav, mp3...) which also supports the decodi...
Definition AudioEncoded.h:271
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioEncoded.h:343
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioEncoded.h:333
void addNotifyAudioChange(AudioInfoSupport &bi) override
Adds target to be notified about audio changes.
Definition AudioEncoded.h:382
void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition AudioEncoded.h:406
float getByteFactor() override
approx compression factor: e.g. mp3 is around 4
Definition AudioEncoded.h:387
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:391
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:315
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:318
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioEncoded.h:402
Abstract class: Objects can be put into a pipleline.
Definition AudioOutput.h:100
Definition NoArduino.h:62
Base class for chained converting streams.
Definition AudioIO.h:156
virtual void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioIO.h:158
Definition NoArduino.h:142
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
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