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 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 &&
90 newInfo.sample_rate != 0) {
91 this->cfg = newInfo;
92 decoder_ptr->setAudioInfo(cfg);
93 encoder_ptr->setAudioInfo(cfg);
94 }
95 }
96
98 void setOutput(Print *outputStream) {
99 ptr_out = outputStream;
100 if (decoder_ptr != nullptr) {
101 decoder_ptr->setOutput(*ptr_out);
102 }
103 if (encoder_ptr != nullptr) {
104 encoder_ptr->setOutput(*ptr_out);
105 }
106 }
107
108 void setOutput(AudioStream* out) {
109 setOutput((Print*)out);
110 to_notify = out;
111 }
112
113 void setOutput(AudioOutput*out){
114 setOutput((Print*)out);
115 to_notify = out;
116 }
117
118 void setOutput(Print &outputStream) override { setOutput(&outputStream); }
119 void setOutput(AudioOutput &outputStream) { setOutput(&outputStream); }
120 void setOutput(AudioStream &outputStream) { setOutput(&outputStream); }
121
122 void setEncoder(AudioEncoder *encoder) {
123 if (encoder == nullptr) {
124 encoder = CodecNOP::instance();
125 }
126 encoder_ptr = encoder;
127 writer_ptr = encoder;
128 if (ptr_out != nullptr) {
129 encoder_ptr->setOutput(*ptr_out);
130 }
131 }
132
133 AudioEncoder *getEncoder() { return encoder_ptr; }
134
135 void setDecoder(AudioDecoder *decoder) {
136 if (decoder == nullptr) {
137 decoder = CodecNOP::instance();
138 }
139 decoder_ptr = decoder;
140 writer_ptr = decoder;
141 if (ptr_out != nullptr) {
142 decoder_ptr->setOutput(*ptr_out);
143 }
144 }
145
146 AudioDecoder *getDecoder() { return decoder_ptr; }
147
149 bool begin() override {
150 TRACED();
151 if (!active) {
152 TRACED();
153 // Setup notification
154 if (to_notify != nullptr) {
155 decoder_ptr->removeNotifyAudioChange(*to_notify);
156 decoder_ptr->addNotifyAudioChange(*to_notify);
157 }
158 if (decoder_ptr != undefined || encoder_ptr != undefined) {
159 active = true;
160 if (!decoder_ptr->begin(cfg)) active = false;
161 if (!encoder_ptr->begin(cfg)) active = false;
162 } else {
163 LOGW("no decoder or encoder defined");
164 }
165 }
166 return active;
167 }
168
170 virtual bool begin(AudioInfo newInfo) override {
171 cfg = newInfo;
172 return begin();
173 }
174
176 void end() override {
177 if (active) {
178 TRACEI();
179 decoder_ptr->end();
180 encoder_ptr->end();
181 active = false;
182 }
183 }
184
186 virtual size_t write(const uint8_t *data, size_t len) override {
187 if (len == 0) {
188 // LOGI("write: %d", 0);
189 return 0;
190 }
191 LOGD("EncodedAudioOutput::write: %d", (int)len);
192
193 if (writer_ptr == nullptr || data == nullptr) {
194 LOGE("NPE");
195 return 0;
196 }
197
198 if (check_available_for_write && availableForWrite() == 0) {
199 return 0;
200 }
201
202 size_t result = writer_ptr->write(data, len);
203 LOGD("EncodedAudioOutput::write: %d -> %d", (int)len, (int)result);
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() override { return active; }
214
216 AudioDecoder &decoder() { return *decoder_ptr; }
217
219 AudioEncoder &encoder() { return *encoder_ptr; }
220
222 bool isCheckAvailableForWrite() { return check_available_for_write; }
223
225 void setFrameSize(int size) { frame_size = size; }
226
227 EncodedAudioOutput& operator=(EncodedAudioOutput const& src) {
228 decoder_ptr = src.decoder_ptr;
229 encoder_ptr = src.encoder_ptr;
230 ptr_out = src.ptr_out;
231 active = src.active;
232 check_available_for_write = src.check_available_for_write;
233 frame_size = src.frame_size;
234 cfg = src.cfg;
235 is_active = src.is_active;
236 return *this;
237 }
238
240 AudioInfo audioInfo() override {
241 if (decoder_ptr != undefined){
242 return decoder_ptr->audioInfo();
243 }
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 return enc_out.begin(audioInfo());
362 }
363
364 void end() override {
365 enc_out.end();
366 reader.end();
367 }
368
369 int availableForWrite() override { return enc_out.availableForWrite(); }
370
371 size_t write(const uint8_t *data, size_t len) override {
372 // addNotifyOnFirstWrite();
373 return enc_out.write(data, len);
374 }
375
376 size_t readBytes(uint8_t *data, size_t len) override {
377 return reader.readBytes(data, len);
378 }
379
381 enc_out.addNotifyAudioChange(bi);
382 }
383
385 float getByteFactor() override { return byte_factor; }
386 void setByteFactor(float factor) { byte_factor = factor; }
387
389 void setFrameSize(int size) { enc_out.setFrameSize(size); }
390
391 EncodedAudioStream& operator=(EncodedAudioStream const& src) {
392 enc_out = src.enc_out;
393 byte_factor = src.byte_factor;
394 p_stream = src.p_stream;
395 p_print = src.p_print;
396 info = src.info;
397 return *this;
398 };
399
400 AudioInfo audioInfo() override { return enc_out.audioInfo(); }
401
402 protected:
403 EncodedAudioOutput enc_out;
404 float byte_factor = 2.0f;
405};
406
415 public:
416 void setWriter(AudioWriter *writer) { p_writer = writer; }
417 size_t write(const uint8_t *data, size_t len) {
418 return p_writer->write(data, len);
419 };
420
421 protected:
422 AudioWriter *p_writer = nullptr;
423};
424
433 public:
434 virtual bool begin() = 0;
435 virtual void end() = 0;
436 virtual void setAudioInfo(AudioInfo info) {
437 if (this->info != info && info.channels != 0 && info.sample_rate != 0) {
438 this->info = info;
439 if (p_writer1 != nullptr) p_writer1->setAudioInfo(info);
440 if (p_writer2 != nullptr) p_writer2->setAudioInfo(info);
441 }
442 }
443 virtual size_t write(uint8_t *data, size_t size) = 0;
444
445 protected:
446 AudioInfo info;
447 AudioWriter *p_writer1 = nullptr;
448 AudioWriter *p_writer2 = nullptr;
450 bool active = false;
451};
452
454 public:
455 void setupOutput(AudioWriter *writer1, AudioWriter *writer2, Print &print) {
456 p_print = &print;
457 p_writer1 = writer1;
458 p_writer2 = writer2;
459 print2.setWriter(p_writer2);
460 }
461
462 void setupOutput(AudioWriter *writer1, Print &print) {
463 p_print = &print;
464 p_writer1 = writer1;
465 }
466
467 virtual bool begin() {
468 if (!active) {
469 active = true;
470 if (p_writer2 != nullptr) {
471 p_writer1->setOutput(print2);
472 p_writer2->setOutput(*p_print);
473 p_writer1->begin();
474 p_writer2->begin();
475 } else {
476 p_writer1->setOutput(*p_print);
477 p_writer1->begin();
478 }
479 }
480 return true;
481 }
482 virtual void end() {
483 if (active) {
484 if (p_writer1 != nullptr) p_writer1->end();
485 if (p_writer2 != nullptr) p_writer2->end();
486 }
487 active = false;
488 }
489 virtual size_t write(uint8_t *data, size_t size) {
490 TRACED();
491 return p_writer1->write(data, size);
492 }
493
494 protected:
495 Print *p_print = nullptr;
497};
498
499} // 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
virtual bool removeNotifyAudioChange(AudioInfoSupport &bi)
Removes a target in order not to be notified about audio changes.
Definition AudioTypes.h:156
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:133
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
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:130
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:414
Dummy no implmentation Codec. This is used so that we can initialize some pointers to decoders and en...
Definition AudioCodecsBase.h:130
ContainerTarget: forwards requests to both the output and the encoder/decoder and sets up the output ...
Definition AudioEncoded.h:432
Definition AudioEncoded.h:453
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:186
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:176
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:225
virtual bool begin(AudioInfo newInfo) override
Starts the processing - sets the status to active.
Definition AudioEncoded.h:170
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:216
void setOutput(Print &outputStream) override
Defines/Changes the output target.
Definition AudioEncoded.h:118
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:219
bool begin() override
Starts the processing - sets the status to active.
Definition AudioEncoded.h:149
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:222
AudioInfo audioInfo() override
Provide audio info from decoder if relevant.
Definition AudioEncoded.h:240
void setOutput(Print *outputStream)
Defines the output.
Definition AudioEncoded.h:98
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:380
float getByteFactor() override
approx compression factor: e.g. mp3 is around 4
Definition AudioEncoded.h:385
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:389
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:400
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
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:59