arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
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
97 void setOutput(Print &outputStream) override { 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 TRACED();
139 if (!active) {
140 TRACED();
141 const CodecNOP *nop = CodecNOP::instance();
142 if (decoder_ptr != nop || encoder_ptr != nop) {
143 active = true;
144 if (!decoder_ptr->begin(cfg)) active = false;
145 if (!encoder_ptr->begin(cfg)) active = false;
146 } else {
147 LOGW("no decoder or encoder defined");
148 }
149 }
150 return active;
151 }
152
154 virtual bool begin(AudioInfo newInfo) override {
155 cfg = newInfo;
156 return begin();
157 }
158
160 void end() override {
161 if (active) {
162 TRACEI();
163 decoder_ptr->end();
164 encoder_ptr->end();
165 active = false;
166 }
167 }
168
170 virtual size_t write(const uint8_t *data, size_t len) override {
171 if (len == 0) {
172 // LOGI("write: %d", 0);
173 return 0;
174 }
175 LOGD("EncodedAudioOutput::write: %d", (int)len);
176
177 if (writer_ptr == nullptr || data == nullptr) {
178 LOGE("NPE");
179 return 0;
180 }
181
182 if (check_available_for_write && availableForWrite() == 0) {
183 return 0;
184 }
185
186 size_t result = writer_ptr->write(data, len);
187 LOGD("EncodedAudioOutput::write: %d -> %d", (int)len, (int)result);
188 return result;
189 }
190
191 int availableForWrite() override {
192 if (!check_available_for_write) return frame_size;
193 return min(ptr_out->availableForWrite(), frame_size);
194 }
195
197 operator bool() override { return active; }
198
200 AudioDecoder &decoder() { return *decoder_ptr; }
201
203 AudioEncoder &encoder() { return *encoder_ptr; }
204
206 bool isCheckAvailableForWrite() { return check_available_for_write; }
207
209 void setFrameSize(int size) { frame_size = size; }
210
211 protected:
212 // AudioInfo info;
213 AudioDecoder *decoder_ptr = CodecNOP::instance(); // decoder
214 AudioEncoder *encoder_ptr = CodecNOP::instance(); // decoder
215 AudioWriter *writer_ptr = nullptr;
216 Print *ptr_out = nullptr;
217 bool active = false;
218 bool check_available_for_write = false;
219 int frame_size = DEFAULT_BUFFER_SIZE;
220};
221
222// legacy name
223using EncodedAudioPrint = EncodedAudioOutput;
224
233 public:
234 EncodedAudioStream() = default;
235
237 setDecoder(decoder);
238 setStream(*ioStream);
239 }
240
242 setDecoder(decoder);
243 setStream(*ioStream);
244 }
245
247 setDecoder(decoder);
248 setOutput(*outputStream);
249 }
250
252 setDecoder(decoder);
253 setOutput(*outputStream);
254 }
255
257 setEncoder(encoder);
258 setOutput(*outputStream);
259 }
260
262
264
265 virtual ~EncodedAudioStream() { end(); }
266
267 void setEncoder(AudioEncoder *encoder) { enc_out.setEncoder(encoder); }
268
269 void setDecoder(AudioDecoder *decoder) { enc_out.setDecoder(decoder); }
270
271 AudioEncoder *getEncoder() { return enc_out.getEncoder(); }
272
273 AudioDecoder *getDecoder() { return enc_out.getDecoder(); }
274
276 AudioDecoder &decoder() { return *getDecoder(); }
277
279 AudioEncoder &encoder() { return *getEncoder(); }
280
281 void setStream(Stream *stream) { setStream(*stream); }
282
283 void setStream(AudioStream *stream) { setStream(*stream); }
284
285 void setOutput(AudioOutput *stream) { setOutput(*stream); }
286
287 void setOutput(Print *stream) { setOutput(*stream); }
288
289 void setStream(AudioStream &stream) override {
291 enc_out.setOutput(&stream);
292 }
293
294 void setStream(Stream &stream) override {
296 enc_out.setOutput(&stream);
297 }
298
299 void setOutput(AudioOutput &stream) override {
300 ReformatBaseStream::setOutput(stream);
301 enc_out.setOutput(&stream);
302 }
303
304 void setOutput(Print &out) override {
305 ReformatBaseStream::setOutput(out);
306 enc_out.setOutput(&out);
307 }
308
309 AudioInfo defaultConfig() {
310 AudioInfo ai;
311 return ai;
312 }
313
314 bool begin(AudioInfo info) {
315 setAudioInfo(info);
316 return begin();
317 }
318
319 bool begin() override {
320 // is_output_notify = false;
321 setupReader();
322 ReformatBaseStream::begin();
323 return enc_out.begin(audioInfo());
324 }
325
326 void end() override {
327 enc_out.end();
328 reader.end();
329 }
330
331 int availableForWrite() override { return enc_out.availableForWrite(); }
332
333 size_t write(const uint8_t *data, size_t len) override {
334 // addNotifyOnFirstWrite();
335 return enc_out.write(data, len);
336 }
337
338 size_t readBytes(uint8_t *data, size_t len) override {
339 return reader.readBytes(data, len);
340 }
341
343 enc_out.addNotifyAudioChange(bi);
344 }
345
347 float getByteFactor() override { return byte_factor; }
348 void setByteFactor(float factor) { byte_factor = factor; }
349
351 void setFrameSize(int size) { enc_out.setFrameSize(size); }
352
353 protected:
354 EncodedAudioOutput enc_out;
355 float byte_factor = 2.0f;
356};
357
366 public:
367 void setWriter(AudioWriter *writer) { p_writer = writer; }
368 size_t write(const uint8_t *data, size_t len) {
369 return p_writer->write(data, len);
370 };
371
372 protected:
373 AudioWriter *p_writer = nullptr;
374};
375
384 public:
385 virtual bool begin() = 0;
386 virtual void end() = 0;
387 virtual void setAudioInfo(AudioInfo info) {
388 if (this->info != info && info.channels != 0 && info.sample_rate != 0) {
389 this->info = info;
390 if (p_writer1 != nullptr) p_writer1->setAudioInfo(info);
391 if (p_writer2 != nullptr) p_writer2->setAudioInfo(info);
392 }
393 }
394 virtual size_t write(uint8_t *data, size_t size) = 0;
395
396 protected:
397 AudioInfo info;
398 AudioWriter *p_writer1 = nullptr;
399 AudioWriter *p_writer2 = nullptr;
401 bool active = false;
402};
403
405 public:
406 void setupOutput(AudioWriter *writer1, AudioWriter *writer2, Print &print) {
407 p_print = &print;
408 p_writer1 = writer1;
409 p_writer2 = writer2;
410 print2.setWriter(p_writer2);
411 }
412
413 void setupOutput(AudioWriter *writer1, Print &print) {
414 p_print = &print;
415 p_writer1 = writer1;
416 }
417
418 virtual bool begin() {
419 if (!active) {
420 active = true;
421 if (p_writer2 != nullptr) {
422 p_writer1->setOutput(print2);
423 p_writer2->setOutput(*p_print);
424 p_writer1->begin();
425 p_writer2->begin();
426 } else {
427 p_writer1->setOutput(*p_print);
428 p_writer1->begin();
429 }
430 }
431 return true;
432 }
433 virtual void end() {
434 if (active) {
435 if (p_writer1 != nullptr) p_writer1->end();
436 if (p_writer2 != nullptr) p_writer2->end();
437 }
438 active = false;
439 }
440 virtual size_t write(uint8_t *data, size_t size) {
441 TRACED();
442 return p_writer1->write(data, size);
443 }
444
445 protected:
446 Print *p_print = nullptr;
448};
449
450} // 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
Encoding of PCM data.
Definition AudioCodecsBase.h:90
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition AudioCodecsBase.h:99
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
Base class for Output Adpapters.
Definition AudioIO.h:231
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:119
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:127
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition BaseStream.h:150
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:365
Dummy no implmentation Codec. This is used so that we can initialize some pointers to decoders and en...
Definition AudioCodecsBase.h:124
ContainerTarget: forwards requests to both the output and the encoder/decoder and sets up the output ...
Definition AudioEncoded.h:383
Definition AudioEncoded.h:404
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:170
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:160
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:209
virtual bool begin(AudioInfo newInfo) override
Starts the processing - sets the status to active.
Definition AudioEncoded.h:154
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:200
void setOutput(Print &outputStream) override
Defines/Changes the output target.
Definition AudioEncoded.h:97
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:203
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:206
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:232
void setOutput(Print &out) override
Defines/Changes the output target.
Definition AudioEncoded.h:304
void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioEncoded.h:294
void addNotifyAudioChange(AudioInfoSupport &bi) override
Adds target to be notified about audio changes.
Definition AudioEncoded.h:342
float getByteFactor() override
approx compression factor: e.g. mp3 is around 4
Definition AudioEncoded.h:347
void setFrameSize(int size)
defines the size of the decoded frame in bytes
Definition AudioEncoded.h:351
AudioDecoder & decoder()
Provides the initialized decoder.
Definition AudioEncoded.h:276
AudioEncoder & encoder()
Provides the initialized encoder.
Definition AudioEncoded.h:279
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