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
86 int write(uint8_t *data,
size_t data_len) {
103 if (!
setPos(
"RIFF"))
return false;
106 if (!
setPos(
"WAVE"))
return false;
107 if (!
setPos(
"fmt "))
return false;
115 if (!
setPos(
"data"))
return false;
148 return pos > 0 ? pos + 8 : 0;
174 if (written != len) {
175 LOGE(
"Failed to write WAV header to output: written %d of %d bytes", written, len);
177 return written == len;
219 LOGI(
"Header: %s", msg);
228 int id_len = strlen(
id);
230 if (pos < 0)
return false;
270 for (i = 0; i < n; i++)
getChar();
280 void seek(
long int offset,
int origin) {
281 if (origin == SEEK_SET) {
283 }
else if (origin == SEEK_CUR) {
305 LOGI(
"writeRiffHeader: file_size=%u riff_size=%u", info.
file_size, chunk_size);
313 uint16_t fmt_len = 16;
314 if (is_ima_adpcm) fmt_len = 20;
315 else if (is_ms_adpcm) fmt_len = 50;
341 }
else if (is_ms_adpcm) {
343 static const int16_t ms_adpcm_coef[7][2] = {
344 {256, 0}, {512, -256}, {0, 0}, {192, 64},
345 {240, 0}, {460, -208}, {392, -232}};
349 for (
auto &c : ms_adpcm_coef) {
361 uint32_t sample_length = 0;
377 data_length = info.
file_size - header_bytes;
379 LOGI(
"writeDataHeader: data_length=%u", data_length);
383 uint8_t empty[offset];
384 memset(empty, 0, offset);
497 "addDecoder: could not determine the WAV format tag for this "
498 "decoder - please provide it explicitly");
501 for (
int i = 0; i <
decoders.size(); i++) {
580 virtual size_t write(
const uint8_t *data,
size_t len)
override {
587 if (data_start == 0)
return len;
592 result = data_start +
593 write_out((uint8_t *)data + data_start, len - data_start);
597 result =
write_out((uint8_t *)data, len);
604 virtual operator bool()
override {
return active; }
665 virtual size_t write_out(
const uint8_t *in_ptr,
size_t in_size) {
684 result =
out().
write(in_ptr, in_size);
691 size_t samples_remaining = in_size;
694 while (samples_remaining > 0) {
695 size_t current_batch =
697 for (
size_t i = 0; i < current_batch; ++i) {
698 out_buf[i] = ((int16_t)in_ptr[offset + i] - 128) << 8;
700 writeDataT<int16_t>(&
out(), out_buf, current_batch);
701 offset += current_batch;
702 samples_remaining -= current_batch;
713 for (
size_t i = 0; i < in_size; i++) {
720 int32_t converted_sample = sample24.scale32();
739 for (
size_t i = 0; i < in_size; i++) {
745 if (sample_f > 1.0f) sample_f = 1.0f;
746 if (sample_f < -1.0f) sample_f = -1.0f;
762 size_t remaining = in_size;
765 while (remaining > 0) {
766 size_t current_batch =
768 for (
size_t i = 0; i < current_batch; ++i) {
771 writeDataT<int16_t>(&
out(), out_buf, current_batch);
772 offset += current_batch;
773 remaining -= current_batch;
780 size_t remaining = in_size;
783 while (remaining > 0) {
784 size_t current_batch =
786 for (
size_t i = 0; i < current_batch; ++i) {
789 writeDataT<int16_t>(&
out(), out_buf, current_batch);
790 offset += current_batch;
791 remaining -= current_batch;
799 int t = (a_val & 0x0f) << 4;
800 int seg = ((unsigned)a_val & 0x70) >> 4;
813 return (int16_t)((a_val & 0x80) ? t : -t);
819 int t = ((u_val & 0x0f) << 3) + 0x84;
820 t <<= ((unsigned)u_val & 0x70) >> 4;
821 return (int16_t)((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
834 "WAV header exceeds the maximum supported size of %d bytes "
835 "without a 'data' chunk - aborting",
841 LOGW(
"WAV header misses 'data' section in len: %d",
848 LOGE(
"WAV header parsing failed");
876 LOGE(
"WAV format not supported: 0x%04X", (
unsigned)format);
887 "Natively supported: PCM (0x%04X), IEEE_FLOAT (0x%04X), ALAW "
888 "(0x%04X), MULAW (0x%04X)",
893 "No additional decoders registered - use "
894 "setDecoder()/addDecoder() to support e.g. ADPCM formats");
896 for (
int i = 0; i <
decoders.size(); i++) {
897 LOGE(
"Registered decoder for format: 0x%04X",
905 for (
int i = 0; i <
decoders.size(); i++) {
951 size_t write(
const uint8_t *data,
size_t len)
override {
1007 info.is_streamed =
true;
1008 info.is_valid =
true;
1009 info.data_length = 0x7fff0000;
1010 info.file_size =
info.data_length + 36;
1069 LOGI(
"is_streamed! because length is %u",
1089 virtual size_t write(
const uint8_t *data,
size_t len)
override {
1091 LOGE(
"The WAVEncoder is not open - please call begin()");
1096 LOGE(
"No output stream was provided");
1101 LOGI(
"Writing Header");
1103 LOGE(
"Failed to write WAV header");
1114 result = p_out->
write((uint8_t *)data, len);
1119 size_t write_size = min((
size_t)len, (
size_t)
size_limit);
1120 result = p_out->
write((uint8_t *)data, write_size);
1134 if (frame_size <= 0) frame_size = 1;
1136 if (chunk == 0) chunk = frame_size;
1138 while (result < len && size_limit > 0) {
1139 size_t n = min(chunk, len - result);
1141 size_t accepted = p_out->
write((uint8_t *)data + result, n);
1144 if (accepted < n)
break;
1149 LOGI(
"The defined size was written - so we close the WAVEncoder now");
1256 "setupEncodedAudio: no output stream was provided - call "
1257 "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:636
AudioFormat format
Definition CodecWAV.h:637
AudioDecoderExt * decoder
Definition CodecWAV.h:638
DecoderEntry(AudioFormat fmt, AudioDecoderExt *dec)
Definition CodecWAV.h:640