8#define READ_BUFFER_SIZE 512
9#define MAX_WAV_HEADER_LEN 200
14#define MAX_WAV_HEADER_LEN_LIMIT 2048
20#define WAV_ENCODER_COMPRESSED_CHUNK_SIZE 1024
97 int write(uint8_t *data,
size_t data_len) {
114 if (!
setPos(
"RIFF"))
return false;
117 if (!
setPos(
"WAVE"))
return false;
118 if (!
setPos(
"fmt "))
return false;
126 if (!
setPos(
"data"))
return false;
159 return pos > 0 ? pos + 8 : 0;
185 if (written != len) {
186 LOGE(
"Failed to write WAV header to output: written %d of %d bytes", written, len);
188 return written == len;
230 LOGI(
"Header: %s", msg);
239 int id_len = strlen(
id);
241 if (pos < 0)
return false;
281 for (i = 0; i < n; i++)
getChar();
291 void seek(
long int offset,
int origin) {
292 if (origin == SEEK_SET) {
294 }
else if (origin == SEEK_CUR) {
316 LOGI(
"writeRiffHeader: file_size=%u riff_size=%u", info.
file_size, chunk_size);
324 uint16_t fmt_len = 16;
325 if (is_ima_adpcm) fmt_len = 20;
326 else if (is_ms_adpcm) fmt_len = 50;
345 uint16_t bits_per_coded_sample =
360 }
else if (is_ms_adpcm) {
362 static const int16_t ms_adpcm_coef[7][2] = {
363 {256, 0}, {512, -256}, {0, 0}, {192, 64},
364 {240, 0}, {460, -208}, {392, -232}};
368 for (
auto &c : ms_adpcm_coef) {
380 uint32_t sample_length = 0;
396 data_length = info.
file_size - header_bytes;
398 LOGI(
"writeDataHeader: data_length=%u", data_length);
402 uint8_t empty[offset];
403 memset(empty, 0, offset);
512 "addDecoder: could not determine the WAV format tag for this "
513 "decoder - please provide it explicitly");
516 for (
int i = 0; i <
decoders.size(); i++) {
595 virtual size_t write(
const uint8_t *data,
size_t len)
override {
602 if (data_start == 0)
return len;
607 result = data_start +
608 write_out((uint8_t *)data + data_start, len - data_start);
612 result =
write_out((uint8_t *)data, len);
619 virtual operator bool()
override {
return active; }
680 virtual size_t write_out(
const uint8_t *in_ptr,
size_t in_size) {
699 result =
out().
write(in_ptr, in_size);
706 size_t samples_remaining = in_size;
709 while (samples_remaining > 0) {
710 size_t current_batch =
712 for (
size_t i = 0; i < current_batch; ++i) {
713 out_buf[i] = ((int16_t)in_ptr[offset + i] - 128) << 8;
715 writeDataT<int16_t>(&
out(), out_buf, current_batch);
716 offset += current_batch;
717 samples_remaining -= current_batch;
728 for (
size_t i = 0; i < in_size; i++) {
735 int32_t converted_sample = sample24.scale32();
754 for (
size_t i = 0; i < in_size; i++) {
760 if (sample_f > 1.0f) sample_f = 1.0f;
761 if (sample_f < -1.0f) sample_f = -1.0f;
777 size_t remaining = in_size;
780 while (remaining > 0) {
781 size_t current_batch =
783 for (
size_t i = 0; i < current_batch; ++i) {
786 writeDataT<int16_t>(&
out(), out_buf, current_batch);
787 offset += current_batch;
788 remaining -= current_batch;
795 size_t remaining = in_size;
798 while (remaining > 0) {
799 size_t current_batch =
801 for (
size_t i = 0; i < current_batch; ++i) {
804 writeDataT<int16_t>(&
out(), out_buf, current_batch);
805 offset += current_batch;
806 remaining -= current_batch;
814 int t = (a_val & 0x0f) << 4;
815 int seg = ((unsigned)a_val & 0x70) >> 4;
828 return (int16_t)((a_val & 0x80) ? t : -t);
834 int t = ((u_val & 0x0f) << 3) + 0x84;
835 t <<= ((unsigned)u_val & 0x70) >> 4;
836 return (int16_t)((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
849 "WAV header exceeds the maximum supported size of %d bytes "
850 "without a 'data' chunk - aborting",
856 LOGW(
"WAV header misses 'data' section in len: %d",
863 LOGE(
"WAV header parsing failed");
891 LOGE(
"WAV format not supported: 0x%04X", (
unsigned)format);
902 "Natively supported: PCM (0x%04X), IEEE_FLOAT (0x%04X), ALAW "
903 "(0x%04X), MULAW (0x%04X)",
908 "No additional decoders registered - use "
909 "setDecoder()/addDecoder() to support e.g. ADPCM formats");
911 for (
int i = 0; i <
decoders.size(); i++) {
912 LOGE(
"Registered decoder for format: 0x%04X",
920 for (
int i = 0; i <
decoders.size(); i++) {
966 size_t write(
const uint8_t *data,
size_t len)
override {
1025 info.is_streamed =
true;
1026 info.is_valid =
true;
1027 info.data_length = 0x7fff0000;
1028 info.file_size =
info.data_length + 36;
1087 LOGI(
"is_streamed! because length is %u",
1107 virtual size_t write(
const uint8_t *data,
size_t len)
override {
1109 LOGE(
"The WAVEncoder is not open - please call begin()");
1114 LOGE(
"No output stream was provided");
1119 LOGI(
"Writing Header");
1121 LOGE(
"Failed to write WAV header");
1132 result = p_out->
write((uint8_t *)data, len);
1137 size_t write_size = min((
size_t)len, (
size_t)
size_limit);
1138 result = p_out->
write((uint8_t *)data, write_size);
1152 if (frame_size <= 0) frame_size = 1;
1154 if (chunk == 0) chunk = frame_size;
1156 while (result < len && size_limit > 0) {
1157 size_t n = min(chunk, len - result);
1159 size_t accepted = p_out->
write((uint8_t *)data + result, n);
1162 if (accepted < n)
break;
1167 LOGI(
"The defined size was written - so we close the WAVEncoder now");
1278 "setupEncodedAudio: no output stream was provided - call "
1279 "setOutput() before begin()");
#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 MAX_WAV_HEADER_LEN
Definition CodecWAV.h:9
#define MAX_WAV_HEADER_LEN_LIMIT
Definition CodecWAV.h:14
#define WAV_ENCODER_COMPRESSED_CHUNK_SIZE
Definition CodecWAV.h:20
#define assert(T)
Definition avr.h:10
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
AudioFormat
Audio format codes used by Microsoft e.g. in avi or wav files.
Definition AudioFormat.h:21
Associates a WAV format tag with the decoder responsible for it.
Definition CodecWAV.h:651
AudioFormat format
Definition CodecWAV.h:652
AudioDecoderExt * decoder
Definition CodecWAV.h:653
DecoderEntry(AudioFormat fmt, AudioDecoderExt *dec)
Definition CodecWAV.h:655