arduino-audio-tools
Loading...
Searching...
No Matches
CodecWAV.h
Go to the documentation of this file.
1#pragma once
2
7
8#define READ_BUFFER_SIZE 512
9#define MAX_WAV_HEADER_LEN 200
10
11namespace audio_tools {
12
38
39static const char *wav_mime = "audio/wav";
40
67class WAVHeader {
68 public:
69 WAVHeader() = default;
70
73 int write(uint8_t *data, size_t data_len) {
74 return buffer.writeArray(data, data_len);
75 }
76
78 bool parse() {
79 LOGI("WAVHeader::begin: %u", (unsigned)buffer.available());
80 this->data_pos = 0l;
81 memset((void *)&headerInfo, 0, sizeof(WAVAudioInfo));
82
83 if (!setPos("RIFF")) return false;
84 // RIFF stores chunk_size (= file_size - 8): normalize to full file size
86 if (!setPos("WAVE")) return false;
87 if (!setPos("fmt ")) return false;
88 int fmt_length = read_int32();
95 if (!setPos("data")) return false;
97 if (headerInfo.data_length == 0 || headerInfo.data_length >= 0x7fff0000) {
100 }
101
102 logInfo();
103 buffer.clear();
104 return true;
105 }
106
109 int pos = getDataPos();
110 return pos > 0 && buffer.available() >= pos;
111 }
112
114 size_t available() { return buffer.available(); }
115
118 int pos =
120 .indexOf("data");
121 return pos > 0 ? pos + 8 : 0;
122 }
123
126
128 void setAudioInfo(WAVAudioInfo info) { headerInfo = info; }
129
131 bool writeHeader(Print *out) {
132 return writeHeader(out, headerInfo);
133 }
134
136 bool writeHeader(Print *out, const WAVAudioInfo &info) {
137 writeRiffHeader(buffer, info);
138 writeFMT(buffer, info);
139 if (isADPCM(info.format) && info.ext_adpcm_header) {
140 writeFactChunk(buffer, info);
141 }
142 writeDataHeader(buffer, info);
143 int len = buffer.available();
144 int written = out->write(buffer.data(), len);
145 if (written != len) {
146 LOGE("Failed to write WAV header to output: written %d of %d bytes", written, len);
147 }
148 return written == len;
149 }
150
155 static int extraHeaderBytes(const WAVAudioInfo &info) {
156 if (!info.ext_adpcm_header) return 0;
157 switch (info.format) {
158 case AudioFormat::ADPCM: // MS ADPCM: 34 byte fmt extension + 12 byte fact chunk
159 return 34 + 12;
160 case AudioFormat::DVI_ADPCM: // IMA/DVI ADPCM: 4 byte fmt extension + 12 byte fact chunk
161 return 4 + 12;
162 default:
163 return 0;
164 }
165 }
166
168 void clear() {
169 data_pos = 0;
170 WAVAudioInfo empty;
171 empty.sample_rate = 0;
172 empty.channels = 0;
173 empty.bits_per_sample = 0;
174 headerInfo = empty;
176 buffer.reset();
177 }
178
180 void dumpHeader() {
181 char msg[buffer.available() + 1];
182 memset(msg, 0, buffer.available() + 1);
183 for (int j = 0; j < buffer.available(); j++) {
184 char c = (char)buffer.data()[j];
185 if (!isalpha(c)) {
186 c = '.';
187 }
188 msg[j] = c;
189 }
190 LOGI("Header: %s", msg);
191 }
192
193 protected:
196 size_t data_pos = 0;
197
198 bool setPos(const char *id) {
199 int id_len = strlen(id);
200 int pos = indexOf(id);
201 if (pos < 0) return false;
202 data_pos = pos + id_len;
203 return true;
204 }
205
206 int indexOf(const char *str) {
207 return StrView((char *)buffer.data(), MAX_WAV_HEADER_LEN,
209 .indexOf(str);
210 }
211
213 uint32_t tag = 0;
214 tag = (tag << 8) | getChar();
215 tag = (tag << 8) | getChar();
216 tag = (tag << 8) | getChar();
217 tag = (tag << 8) | getChar();
218 return tag;
219 }
220
221 uint32_t getChar32() { return getChar(); }
222
224 uint32_t value = 0;
225 value |= getChar32() << 0;
226 value |= getChar32() << 8;
227 value |= getChar32() << 16;
228 value |= getChar32() << 24;
229 return value;
230 }
231
233 uint16_t value = 0;
234 value |= getChar() << 0;
235 value |= getChar() << 8;
236 return value;
237 }
238
239 void skip(int n) {
240 int i;
241 for (i = 0; i < n; i++) getChar();
242 }
243
244 int getChar() {
245 if (data_pos < buffer.size())
246 return buffer.data()[data_pos++];
247 else
248 return -1;
249 }
250
251 void seek(long int offset, int origin) {
252 if (origin == SEEK_SET) {
253 data_pos = offset;
254 } else if (origin == SEEK_CUR) {
255 data_pos += offset;
256 }
257 }
258
259 size_t tell() { return data_pos; }
260
261 bool eof() { return data_pos >= buffer.size() - 1; }
262
263 void logInfo() {
264 LOGI("WAVHeader sound_pos: %d", getDataPos());
265 LOGI("WAVHeader channels: %d ", headerInfo.channels);
266 LOGI("WAVHeader bits_per_sample: %d", headerInfo.bits_per_sample);
267 LOGI("WAVHeader sample_rate: %d ", (int)headerInfo.sample_rate);
268 LOGI("WAVHeader format: %d", (int)headerInfo.format);
269 }
270
272 const WAVAudioInfo &info) {
273 buffer.writeArray((uint8_t *)"RIFF", 4);
274 // chunk_size = file_size - 8 (RIFF header size)
275 uint32_t chunk_size = info.file_size > 8 ? info.file_size - 8 : 0;
276 LOGI("writeRiffHeader: file_size=%u riff_size=%u", info.file_size, chunk_size);
278 buffer.writeArray((uint8_t *)"WAVE", 4);
279 }
280
284 uint16_t fmt_len = 16;
285 if (is_ima_adpcm) fmt_len = 20;
286 else if (is_ms_adpcm) fmt_len = 50;
287
289 uint32_t byte_rate = info.byte_rate;
290 if ((is_ms_adpcm || is_ima_adpcm) && spb > 0 && info.block_align > 0) {
291 // average bytes/sec = (sample_rate * block_align) / samples_per_block
292 byte_rate = ((uint64_t)info.sample_rate * info.block_align) / spb;
293 }
294
295 buffer.writeArray((uint8_t *)"fmt ", 4);
298 write16(buffer, info.channels);
300 write32(buffer, byte_rate);
301 write16(buffer, info.block_align); // frame size
303
304 if (is_ima_adpcm) {
305 write16(buffer, 2); // cbSize: size of extra format bytes
306 write16(buffer, spb); // wSamplesPerBlock
307 } else if (is_ms_adpcm) {
308 // standard MS ADPCM coefficient table (7 predictor pairs)
309 static const int16_t ms_adpcm_coef[7][2] = {
310 {256, 0}, {512, -256}, {0, 0}, {192, 64},
311 {240, 0}, {460, -208}, {392, -232}};
312 write16(buffer, 32); // cbSize: size of extra format bytes
313 write16(buffer, spb); // wSamplesPerBlock
314 write16(buffer, 7); // wNumCoef
315 for (auto &c : ms_adpcm_coef) {
316 write16(buffer, (uint16_t)c[0]);
317 write16(buffer, (uint16_t)c[1]);
318 }
319 }
320 }
321
325 buffer.writeArray((uint8_t *)"fact", 4);
326 write32(buffer, 4); // chunk size
329 if (!info.is_streamed && spb > 0 && info.block_align > 0) {
330 sample_length = (info.data_length / info.block_align) * spb;
331 }
333 }
334
336 buffer.writeArray((uint8_t *)"data", 4);
337 uint32_t data_length = info.data_length;
339 if (headerInfo.is_streamed && data_length == 0) {
340 data_length = ~0; // use max value for streamed data if not set
341 }
342 if (!headerInfo.is_streamed && info.file_size >= header_bytes && (data_length == 0 || data_length == ~0)) {
343 data_length = info.file_size - header_bytes; // data length = file size - header size
344 }
345 LOGI("writeDataHeader: data_length=%u", data_length);
346 write32(buffer, data_length);
347 int offset = info.offset;
348 if (offset > 0) {
349 uint8_t empty[offset];
350 memset(empty, 0, offset);
351 buffer.writeArray(empty, offset); // resolve issue with wrong aligment
352 }
353 }
354
355 static bool isADPCM(AudioFormat format) {
356 return format == AudioFormat::ADPCM || format == AudioFormat::DVI_ADPCM;
357 }
358
362 if (info.channels <= 0 || info.block_align <= 0) return 0;
363 switch (info.format) {
364 case AudioFormat::ADPCM: // MS ADPCM
365 return ((info.block_align / info.channels) - 7) * 2 + 2;
366 case AudioFormat::DVI_ADPCM: // IMA/DVI ADPCM
367 return ((info.block_align / info.channels) - 4) * 2 + 1;
368 default:
369 return 0;
370 }
371 }
372
374 buffer.writeArray((uint8_t *)&value, 4);
375 }
376
378 buffer.writeArray((uint8_t *)&value, 2);
379 }
380
381};
382
404class WAVDecoder : public AudioDecoder {
405
406 public:
410 WAVDecoder() = default;
411
417
420 TRACED();
422 p_decoder = &dec;
423 }
424
426 void setOutput(Print &out_stream) override { this->p_print = &out_stream; }
427
429 bool begin() override {
430 TRACED();
431 header.clear();
434 buffer24.reset();
435 isFirst = true;
436 active = true;
437 return true;
438 }
439
441 void end() override {
442 TRACED();
444 buffer24.reset();
445 active = false;
446 }
447
449 const char *mime() { return wav_mime; }
450
453
455 AudioInfo audioInfo() override {
457 if (convert8to16 && info.format == AudioFormat::PCM &&
458 info.bits_per_sample == 8) {
460 }
461 // 32 bits gives better result
462 if (convert24 && info.format == AudioFormat::PCM &&
463 info.bits_per_sample == 24) {
465 }
466 // non-PCM (e.g. ADPCM) is decoded by p_decoder to 16-bit PCM
467 if (info.format != AudioFormat::PCM) {
469 }
470 return info;
471 }
472
474 virtual size_t write(const uint8_t *data, size_t len) override {
475 TRACED();
476 size_t result = 0;
477 if (active) {
478 if (isFirst) {
479 int data_start = decodeHeader((uint8_t *)data, len);
480 // we do not have the complete header yet: need more data
481 if (data_start == 0) return len;
482 // process the outstanding data
483 result = data_start +
484 write_out((uint8_t *)data + data_start, len - data_start);
485
486 } else if (isValid) {
487 result = write_out((uint8_t *)data, len);
488 }
489 }
490 return result;
491 }
492
494 virtual operator bool() override { return active; }
495
499 }
500
504 }
505
508
509 protected:
511 bool isFirst = true;
512 bool isValid = true;
513 bool active = false;
519 bool convert8to16 = true; // Optional conversion flag
520 bool convert24 = true; // Optional conversion flag
521 const size_t batch_size = 256;
522
523 Print &out() { return p_decoder == nullptr ? *p_print : dec_out; }
524
525 virtual size_t write_out(const uint8_t *in_ptr, size_t in_size) {
526 // check if we need to convert int24 data from 3 bytes to 4 bytes
527 size_t result = 0;
529 header.audioInfo().bits_per_sample == 24 && sizeof(int24_t) == 4) {
531 result = in_size;
534 result = write_out_8to16(in_ptr, in_size);
535 } else {
536 result = out().write(in_ptr, in_size);
537 }
538 return result;
539 }
540
542 size_t write_out_8to16(const uint8_t *in_ptr, size_t in_size) {
543 size_t total_written = 0;
544 size_t samples_remaining = in_size;
545 size_t offset = 0;
547 while (samples_remaining > 0) {
548 size_t current_batch =
550 for (size_t i = 0; i < current_batch; ++i) {
551 out_buf[i] = ((int16_t)in_ptr[offset + i] - 128) << 8;
552 }
554 offset += current_batch;
556 }
557 return in_size;
558 }
559
561 size_t write_out_24(const uint8_t *in_ptr, size_t in_size) {
562 // store 1 sample
565
566 for (size_t i = 0; i < in_size; i++) {
567 // Add byte to buffer
569
570 // Process complete sample when buffer is full
571 if (byte_buffer.isFull()) {
575 if (buffer24.isFull()) {
577 buffer24.reset();
578 }
580 }
581 }
582
583 return in_size;
584 }
585
586
589 int result = in_size;
590 // we expect at least the full header
591 int written = header.write(in_ptr, in_size);
592 if (!header.isDataComplete()) {
593 LOGW("WAV header misses 'data' section in len: %d",
594 (int)header.available());
596 return 0;
597 }
598 // parse header
599 if (!header.parse()) {
600 LOGE("WAV header parsing failed");
601 return 0;
602 }
603
604 isFirst = false;
606
607 LOGI("WAV sample_rate: %d", (int)header.audioInfo().sample_rate);
608 LOGI("WAV data_length: %u", (unsigned)header.audioInfo().data_length);
609 LOGI("WAV is_streamed: %d", header.audioInfo().is_streamed);
610 LOGI("WAV is_valid: %s", header.audioInfo().is_valid ? "true" : "false");
611
612 // check format
614 isValid = format == decoder_format;
615 if (isValid) {
616 // update blocksize
617 if (p_decoder != nullptr) {
618 int block_size = header.audioInfo().block_align;
619 p_decoder->setBlockSize(block_size);
620 }
621
622 // update sampling rate if the target supports it
625 } else {
626 LOGE("WAV format not supported: %d", (int)format);
627 }
628 return header.getDataPos();
629 }
630
632 if (p_decoder != nullptr) {
633 assert(p_print != nullptr);
637 }
638 }
639};
640
651class WAVEncoder : public AudioEncoder {
652 public:
656 WAVEncoder() = default;
657
662
665 TRACED();
667 p_encoder = &enc;
668 }
669
671 void setOutput(Print &out) override {
672 TRACED();
673 p_print = &out;
674 }
675
677 const char *mime() override { return wav_mime; }
678
682 info.format = AudioFormat::PCM;
686 info.is_streamed = true;
687 info.is_valid = true;
688 info.data_length = 0x7fff0000;
689 info.file_size = info.data_length + 36;
690 return info;
691 }
692
694 virtual void setAudioInfo(AudioInfo from) override {
698 // recalculate byte rate, block align...
700 }
701
706 wav_info = ai;
707 LOGI("sample_rate: %d", (int)wav_info.sample_rate);
708 LOGI("channels: %d", wav_info.channels);
709 LOGI("bits_per_sample: %d", wav_info.bits_per_sample);
710 // bytes per second
716 }
717 }
718
721 header.clear();
723 return begin();
724 }
725
727 virtual bool begin() override {
728 TRACED();
730
731 // normalize streaming mode and payload limits at start time
733 wav_info.data_length >= 0x7fff0000) {
734 LOGI("is_streamed! because length is %u",
735 (unsigned)wav_info.data_length);
736 wav_info.is_streamed = true;
738 size_limit = 0;
739 } else {
740 wav_info.is_streamed = false;
742 LOGI("size_limit is %d", (int)size_limit);
743 }
744
745 header_written = false;
746 is_open = true;
747 return true;
748 }
749
751 void end() override { is_open = false; }
752
754 virtual size_t write(const uint8_t *data, size_t len) override {
755 if (!is_open) {
756 LOGE("The WAVEncoder is not open - please call begin()");
757 return 0;
758 }
759
760 if (p_print == nullptr) {
761 LOGE("No output stream was provided");
762 return 0;
763 }
764
765 if (!header_written) {
766 LOGI("Writing Header");
768 LOGE("Failed to write WAV header");
769 is_open = false;
770 return 0;
771 }
772 header_written = true;
773 }
774
775 int32_t result = 0;
776 Print *p_out = p_encoder == nullptr ? p_print : &enc_out;
777
778 if (wav_info.is_streamed) {
779 result = p_out->write((uint8_t *)data, len);
780 } else if (size_limit > 0) {
781 size_t write_size = min((size_t)len, (size_t)size_limit);
782 result = p_out->write((uint8_t *)data, write_size);
783 size_limit -= result;
784
785 if (size_limit <= 0) {
786 LOGI("The defined size was written - so we close the WAVEncoder now");
787 is_open = false;
788 }
789 }
790 return result;
791 }
792
794 operator bool() override { return is_open; }
795
797 bool isOpen() { return is_open; }
798
800 void setDataOffset(uint16_t offset) { wav_info.offset = offset; }
801
805
807 void setDataLength(uint32_t data_length) {
808 wav_info.data_length = data_length;
810 (data_length == 0 || data_length >= 0x7fff0000);
811 if (!wav_info.is_streamed) {
812 // full file size = RIFF chunk (36) + format specific extra header
813 // bytes (e.g. ADPCM 'fmt ' extension + 'fact' chunk) + data chunk payload
816 }
818 }
819
822
825
826 protected:
828 Print *p_print = nullptr; // final output CopyEncoder copy; // used for PCM
833 bool header_written = false;
834 volatile bool is_open = false;
835
837 if (p_encoder != nullptr) {
838 assert(p_print != nullptr);
842 enc_out.begin();
843 // block size only available after begin(): update block size
845 }
846 }
847};
848
849} // namespace audio_tools
WAV Audio Formats used by Microsoft e.g. in AVI video files.
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define DEFAULT_BITS_PER_SAMPLE
Definition AudioToolsConfig.h:104
#define DEFAULT_CHANNELS
Definition AudioToolsConfig.h:100
#define DEFAULT_SAMPLE_RATE
Definition AudioToolsConfig.h:96
#define MAX_WAV_HEADER_LEN
Definition CodecWAV.h:9
#define assert(T)
Definition avr.h:10
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
Extended AudioDecoder interface to support block size configuration.
Definition AudioCodecsBase.h:120
virtual void setBlockSize(int blockSize)=0
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
AudioInfo info
Definition AudioCodecsBase.h:76
Print * p_print
Definition AudioCodecsBase.h:75
Extended AudioEncoder interface to support block size configuration.
Definition AudioCodecsBase.h:126
Encoding of PCM data.
Definition AudioCodecsBase.h:97
AudioInfo info
Definition AudioCodecsBase.h:116
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition AudioCodecsBase.h:106
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:174
Shared functionality of all buffers.
Definition Buffers.h:23
void clear()
same as reset
Definition Buffers.h:96
A more natural Print class to process encoded data (aac, wav, mp3...). Just define the output and the...
Definition AudioEncoded.h:21
void setEncoder(AudioEncoder *encoder)
Definition AudioEncoded.h:131
bool begin() override
Starts the processing - sets the status to active.
Definition AudioEncoded.h:161
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition AudioEncoded.h:87
void setDecoder(AudioDecoder *decoder)
Definition AudioEncoded.h:144
void setOutput(Print *outputStream)
Defines the output.
Definition AudioEncoded.h:107
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:184
size_t size() override
Definition Buffers.h:315
bool write(T sample) override
write add an entry to the buffer
Definition Buffers.h:218
void setClearWithZero(bool flag)
Sets the buffer to 0 on clear.
Definition Buffers.h:326
int available() override
provides the number of entries that are available to read
Definition Buffers.h:245
bool isFull() override
checks if the buffer is full
Definition Buffers.h:252
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:213
T * data()
Provides address of actual data.
Definition Buffers.h:296
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:317
void reset() override
clears the buffer
Definition Buffers.h:298
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:28
virtual int indexOf(const char c, int start=0)
Definition StrView.h:260
A simple WAVDecoder: We parse the header data on the first record to determine the format....
Definition CodecWAV.h:404
virtual size_t write(const uint8_t *data, size_t len) override
Write incoming WAV data (header + PCM) into output.
Definition CodecWAV.h:474
bool active
Definition CodecWAV.h:513
void setOutput(Print &out_stream) override
Defines the output Stream.
Definition CodecWAV.h:426
bool isFirst
Definition CodecWAV.h:511
void setDecoder(AudioDecoderExt &dec, AudioFormat fmt)
Defines an optional decoder if the format is not PCM.
Definition CodecWAV.h:419
size_t write_out_24(const uint8_t *in_ptr, size_t in_size)
convert 3 byte int24 to 4 byte int32
Definition CodecWAV.h:561
Print & out()
Definition CodecWAV.h:523
int decodeHeader(uint8_t *in_ptr, size_t in_size)
Decodes the header data: Returns the start pos of the data.
Definition CodecWAV.h:588
AudioDecoderExt * p_decoder
Definition CodecWAV.h:515
void setConvert8Bit(bool enable)
Convert 8 bit to 16 bit PCM data (default: enabled)
Definition CodecWAV.h:497
void setupEncodedAudio()
Definition CodecWAV.h:631
void end() override
Finish decoding and release temporary buffers.
Definition CodecWAV.h:441
AudioFormat decoder_format
Definition CodecWAV.h:514
WAVHeader & getHeader()
Access to the internal header parser and info.
Definition CodecWAV.h:507
const char * mime()
Provides MIME type "audio/wav".
Definition CodecWAV.h:449
bool isValid
Definition CodecWAV.h:512
WAVDecoder()=default
Construct a new WAVDecoder object for PCM data.
const size_t batch_size
Definition CodecWAV.h:521
SingleBuffer< uint8_t > byte_buffer
Definition CodecWAV.h:517
WAVAudioInfo & audioInfoEx()
Extended WAV specific info (original header values)
Definition CodecWAV.h:452
WAVHeader header
Definition CodecWAV.h:510
WAVDecoder(AudioDecoderExt &dec, AudioFormat fmt)
Construct a new WAVDecoder object for ADPCM data.
Definition CodecWAV.h:416
void setConvert24Bit(bool enable)
Convert 24 bit (3 byte) to 32 bit (4 byte) PCM data (default: enabled)
Definition CodecWAV.h:502
bool begin() override
Prepare decoder for a new WAV stream.
Definition CodecWAV.h:429
size_t write_out_8to16(const uint8_t *in_ptr, size_t in_size)
Convert 8-bit PCM to 16-bit PCM and write out.
Definition CodecWAV.h:542
EncodedAudioOutput dec_out
Definition CodecWAV.h:516
bool convert24
Definition CodecWAV.h:520
virtual size_t write_out(const uint8_t *in_ptr, size_t in_size)
Definition CodecWAV.h:525
AudioInfo audioInfo() override
Exposed AudioInfo (may reflect conversion flags)
Definition CodecWAV.h:455
bool convert8to16
Definition CodecWAV.h:519
SingleBuffer< int32_t > buffer24
Definition CodecWAV.h:518
A simple WAV file encoder. If no AudioEncoderExt is specified the WAV file contains PCM data,...
Definition CodecWAV.h:651
virtual size_t write(const uint8_t *data, size_t len) override
Writes PCM data to be encoded as WAV.
Definition CodecWAV.h:754
void setOutput(Print &out) override
Defines the otuput stream.
Definition CodecWAV.h:671
volatile bool is_open
Definition CodecWAV.h:834
bool isOpen()
Check if encoder is open.
Definition CodecWAV.h:797
void setupEncodedAudio()
Definition CodecWAV.h:836
virtual bool begin() override
starts the processing using the actual WAVAudioInfo
Definition CodecWAV.h:727
bool header_written
Definition CodecWAV.h:833
AudioEncoderExt * p_encoder
Definition CodecWAV.h:829
bool begin(WAVAudioInfo ai)
starts the processing
Definition CodecWAV.h:720
WAVAudioInfo wav_info
Definition CodecWAV.h:831
void end() override
stops the processing
Definition CodecWAV.h:751
virtual void setAudioInfo(WAVAudioInfo ai)
Defines the WAVAudioInfo.
Definition CodecWAV.h:703
int64_t size_limit
Definition CodecWAV.h:832
WAVEncoder()=default
Construct a new WAVEncoder object for PCM data.
void setDataOffset(uint16_t offset)
Adds n empty bytes at the beginning of the data.
Definition CodecWAV.h:800
WAVHeader & getHeader()
Access to the internal header parser and info.
Definition CodecWAV.h:824
EncodedAudioOutput enc_out
Definition CodecWAV.h:830
void setExtADPCMHeader(bool enable)
Definition CodecWAV.h:804
WAVAudioInfo & audioInfoEx()
Extended WAV specific info.
Definition CodecWAV.h:821
WAVEncoder(AudioEncoderExt &enc, AudioFormat fmt)
Construct a new WAVEncoder object for ADPCM data.
Definition CodecWAV.h:661
WAVAudioInfo defaultConfig()
Provides the default configuration.
Definition CodecWAV.h:680
WAVHeader header
Definition CodecWAV.h:827
const char * mime() override
Provides "audio/wav".
Definition CodecWAV.h:677
virtual void setAudioInfo(AudioInfo from) override
Update actual WAVAudioInfo.
Definition CodecWAV.h:694
Print * p_print
Definition CodecWAV.h:828
void setEncoder(AudioEncoderExt &enc, AudioFormat fmt)
Associates an external encoder for non-PCM formats.
Definition CodecWAV.h:664
void setDataLength(uint32_t data_length)
Defines the WAV payload length in bytes (without header)
Definition CodecWAV.h:807
Parser for Wav header data for details see https://de.wikipedia.org/wiki/RIFF_WAVE.
Definition CodecWAV.h:67
void writeDataHeader(BaseBuffer< uint8_t > &buffer, const WAVAudioInfo &info)
Definition CodecWAV.h:335
void logInfo()
Definition CodecWAV.h:263
void write16(BaseBuffer< uint8_t > &buffer, uint16_t value)
Definition CodecWAV.h:377
bool parse()
Call when header data write is complete to parse the data.
Definition CodecWAV.h:78
bool isDataComplete()
Returns true if the header is complete (containd data tag)
Definition CodecWAV.h:108
void skip(int n)
Definition CodecWAV.h:239
void seek(long int offset, int origin)
Definition CodecWAV.h:251
void setAudioInfo(WAVAudioInfo info)
Sets the info in the header.
Definition CodecWAV.h:128
bool eof()
Definition CodecWAV.h:261
void writeFMT(BaseBuffer< uint8_t > &buffer, const WAVAudioInfo &info)
Definition CodecWAV.h:281
bool writeHeader(Print *out, const WAVAudioInfo &info)
Just write a wav header with explicit info to the indicated output.
Definition CodecWAV.h:136
size_t available()
number of bytes available in the header buffer
Definition CodecWAV.h:114
bool writeHeader(Print *out)
Just write a wav header to the indicated outputbu.
Definition CodecWAV.h:131
int getChar()
Definition CodecWAV.h:244
int getDataPos()
Determines the data start position using the data tag.
Definition CodecWAV.h:117
SingleBuffer< uint8_t > buffer
Definition CodecWAV.h:195
WAVAudioInfo & audioInfo()
provides the info from the header
Definition CodecWAV.h:125
static uint16_t samplesPerBlock(const WAVAudioInfo &info)
Definition CodecWAV.h:361
static bool isADPCM(AudioFormat format)
Definition CodecWAV.h:355
int write(uint8_t *data, size_t data_len)
Definition CodecWAV.h:73
void clear()
Reset internal stored header information and buffer.
Definition CodecWAV.h:168
uint32_t read_tag()
Definition CodecWAV.h:212
void writeRiffHeader(BaseBuffer< uint8_t > &buffer, const WAVAudioInfo &info)
Definition CodecWAV.h:271
WAVAudioInfo headerInfo
Definition CodecWAV.h:194
uint16_t read_int16()
Definition CodecWAV.h:232
bool setPos(const char *id)
Definition CodecWAV.h:198
uint32_t read_int32()
Definition CodecWAV.h:223
int indexOf(const char *str)
Definition CodecWAV.h:206
void writeFactChunk(BaseBuffer< uint8_t > &buffer, const WAVAudioInfo &info)
Definition CodecWAV.h:324
size_t data_pos
Definition CodecWAV.h:196
static int extraHeaderBytes(const WAVAudioInfo &info)
Definition CodecWAV.h:155
void write32(BaseBuffer< uint8_t > &buffer, uint64_t value)
Definition CodecWAV.h:373
void dumpHeader()
Debug helper: dumps header bytes as printable characters.
Definition CodecWAV.h:180
size_t tell()
Definition CodecWAV.h:259
uint32_t getChar32()
Definition CodecWAV.h:221
24bit integer which is used for I2S sound processing. The values are really using 3 bytes....
Definition Int24_3bytes_t.h:21
24bit integer which is used for I2S sound processing. The values are represented as int32_t,...
Definition Int24_4bytes_t.h:22
AudioFormat
Audio format codes used by Microsoft e.g. in avi or wav files.
Definition AudioFormat.h:19
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
static const char * wav_mime
Definition CodecWAV.h:39
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
Sound information which is available in the WAV header.
Definition CodecWAV.h:19
AudioFormat format
Definition CodecWAV.h:27
bool is_streamed
Definition CodecWAV.h:30
bool is_valid
Definition CodecWAV.h:31
int block_align
Definition CodecWAV.h:29
WAVAudioInfo(const AudioInfo &from)
Definition CodecWAV.h:21
uint32_t file_size
Definition CodecWAV.h:33
int offset
Definition CodecWAV.h:34
int byte_rate
Definition CodecWAV.h:28
uint32_t data_length
Definition CodecWAV.h:32
bool ext_adpcm_header
write the extended 'fmt ' chunk + 'fact' chunk for ADPCM formats
Definition CodecWAV.h:36