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 cfg = 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
260// legacy name
261using EncodedAudioPrint = EncodedAudioOutput;
262
271 public:
272 EncodedAudioStream() = default;
273
275 setDecoder(decoder);
276 setStream(*ioStream);
277 }
278
280 setDecoder(decoder);
281 setStream(*ioStream);
282 }
283
285 setDecoder(decoder);
286 setOutput(*outputStream);
287 }
288
290 setDecoder(decoder);
291 setOutput(*outputStream);
292 }
293
295 setEncoder(encoder);
296 setOutput(*outputStream);
297 }
298
300
302
303 virtual ~EncodedAudioStream() { end(); }
304
305 void setEncoder(AudioEncoder *encoder) { enc_out.setEncoder(encoder); }
306
307 void setDecoder(AudioDecoder *decoder) { enc_out.setDecoder(decoder); }
308
309 AudioEncoder *getEncoder() { return enc_out.getEncoder(); }
310
311 AudioDecoder *getDecoder() { return enc_out.getDecoder(); }
312
314 AudioDecoder &decoder() { return *getDecoder(); }
315
317 AudioEncoder &encoder() { return *getEncoder(); }
318
319 void setStream(Stream *stream) { setStream(*stream); }
320
321 void setStream(AudioStream *stream) { setStream(*stream); }
322
323 void setOutput(AudioOutput *stream) { setOutput(*stream); }
324
325 void setOutput(Print *stream) { setOutput(*stream); }
326
327 void setStream(AudioStream &stream) override {
329 enc_out.setOutput(&stream);
330 }
331
332 void setStream(Stream &stream) override {
334 enc_out.setOutput(&stream);
335 }
336
337 void setOutput(AudioOutput &stream) override {
338 ReformatBaseStream::setOutput(stream);
339 enc_out.setOutput(&stream);
340 }
341
342 void setOutput(Print &out) override {
343 ReformatBaseStream::setOutput(out);
344 enc_out.setOutput(&out);
345 }
346
347 AudioInfo defaultConfig() {
348 AudioInfo ai;
349 return ai;
350 }
351
352 bool begin(AudioInfo info) {
353 setAudioInfo(info);
354 return begin();
355 }
356
357 bool begin() override {
358 // is_output_notify = false;
359 setupReader();
360 ReformatBaseStream::begin();
361 enc_out.addNotifyAudioChange(*this);
362 return enc_out.begin(audioInfo());
363 }
364
365 void end() override {
366 enc_out.end();
367 reader.end();
368 }
369
370 int availableForWrite() override { return enc_out.availableForWrite(); }
371
372 size_t write(const uint8_t *data, size_t len) override {
373 // addNotifyOnFirstWrite();
374 return enc_out.write(data, len);
375 }
376
377 size_t readBytes(uint8_t *data, size_t len) override {
378 return reader.readBytes(data, len);
379 }
380
382 enc_out.addNotifyAudioChange(bi);
383 }
384
386 float getByteFactor() override { return byte_factor; }
387 void setByteFactor(float factor) { byte_factor = factor; }
388
390 void setFrameSize(int size) { enc_out.setFrameSize(size); }
391
392 EncodedAudioStream& operator=(EncodedAudioStream const& src) {
393 enc_out = src.enc_out;
394 byte_factor = src.byte_factor;
395 p_stream = src.p_stream;
396 p_print = src.p_print;
397 info = src.info;
398 return *this;
399 };
400
401 AudioInfo audioInfo() override {
402 return enc_out.audioInfo();;
403 }
404
405 void setAudioInfo(AudioInfo newInfo) override {
407 enc_out.setAudioInfo(newInfo);
408 }
409
410 protected:
411 EncodedAudioOutput enc_out;
412 float byte_factor = 2.0f;
413};
414
423 public:
424 void setWriter(AudioWriter *writer) { p_writer = writer; }
425 size_t write(const uint8_t *data, size_t len) {
426 return p_writer->write(data, len);
427 };
428
429 protected:
430 AudioWriter *p_writer = nullptr;
431};
432
441 public:
442 virtual bool begin() = 0;
443 virtual void end() = 0;
444 virtual void setAudioInfo(AudioInfo info) {
445 if (this->info != info && info.channels != 0 && info.sample_rate != 0) {
446 this->info = info;
447 if (p_writer1 != nullptr) p_writer1->setAudioInfo(info);
448 if (p_writer2 != nullptr) p_writer2->setAudioInfo(info);
449 }
450 }
451 virtual size_t write(uint8_t *data, size_t size) = 0;
452
453 protected:
454 AudioInfo info;
455 AudioWriter *p_writer1 = nullptr;
456 AudioWriter *p_writer2 = nullptr;
458 bool active = false;
459};
460
462 public:
463 void setupOutput(AudioWriter *writer1, AudioWriter *writer2, Print &print) {
464 p_print = &print;
465 p_writer1 = writer1;
466 p_writer2 = writer2;
467 print2.setWriter(p_writer2);
468 }
469
470 void setupOutput(AudioWriter *writer1, Print &print) {
471 p_print = &print;
472 p_writer1 = writer1;
473 }
474
475 virtual bool begin() {
476 if (!active) {
477 active = true;
478 if (p_writer2 != nullptr) {
479 p_writer1->setOutput(print2);
480 p_writer2->setOutput(*p_print);
481 p_writer1->begin();
482 p_writer2->begin();
483 } else {
484 p_writer1->setOutput(*p_print);
485 p_writer1->begin();
486 }
487 }
488 return true;
489 }
490 virtual void end() {
491 if (active) {
492 if (p_writer1 != nullptr) p_writer1->end();
493 if (p_writer2 != nullptr) p_writer2->end();
494 }
495 active = false;
496 }
497 virtual size_t write(uint8_t *data, size_t size) {
498 TRACED();
499 return p_writer1->write(data, size);
500 }
501
502 protected:
503 Print *p_print = nullptr;
505};
506
507} // 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:96
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition AudioCodecsBase.h:105
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition AudioTypes.h:151
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:133
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:22
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioOutput.h:59
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:207
virtual void setAudioInfo(AudioInfo from)=0
Defines the input AudioInfo.
Adapter class which lets an AudioWriter behave like a Print.
Definition AudioEncoded.h:422
ContainerTarget: forwards requests to both the output and the encoder/decoder and sets up the output ...
Definition AudioEncoded.h:440
Definition AudioEncoded.h:461
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:270
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioEncoded.h:342
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioEncoded.h:332
void addNotifyAudioChange(AudioInfoSupport &bi) override
Adds target to be notified about audio changes.
Definition AudioEncoded.h:381
void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition AudioEncoded.h:405
float getByteFactor() override
approx compression factor: e.g. mp3 is around 4
Definition AudioEncoded.h:386
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:390
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:314
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:317
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioEncoded.h:401
Abstract class: Objects can be put into a pipleline.
Definition AudioOutput.h:97
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:53
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