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
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) {
396 data_length = info.
file_size - header_bytes;
398 LOGI(
"writeDataHeader: data_length=%u", data_length);
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++) {
602 if (data_start == 0)
return len;
607 result = data_start +
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));
854 "WAV header exceeds the maximum supported size of %d bytes "
855 "without a 'data' chunk - aborting",
861 LOGW(
"WAV header misses 'data' section in len: %d",
870 LOGE(
"WAV header parsing failed");
898 LOGE(
"WAV format not supported: 0x%04X", (
unsigned)format);
903 int result = data_start - buffered_before;
904 if (result < 0) result = 0;
905 if (result > (
int)in_size) result = (
int)in_size;
914 "Natively supported: PCM (0x%04X), IEEE_FLOAT (0x%04X), ALAW "
915 "(0x%04X), MULAW (0x%04X)",
920 "No additional decoders registered - use "
921 "setDecoder()/addDecoder() to support e.g. ADPCM formats");
923 for (
int i = 0; i <
decoders.size(); i++) {
924 LOGE(
"Registered decoder for format: 0x%04X",
932 for (
int i = 0; i <
decoders.size(); i++) {
1037 info.is_streamed =
true;
1038 info.is_valid =
true;
1039 info.data_length = 0x7fff0000;
1040 info.file_size =
info.data_length + 36;
1099 LOGI(
"is_streamed! because length is %u",
1121 LOGE(
"The WAVEncoder is not open - please call begin()");
1126 LOGE(
"No output stream was provided");
1131 LOGI(
"Writing Header");
1133 LOGE(
"Failed to write WAV header");
1149 size_t write_size = min((
size_t)len, (
size_t)
size_limit);
1164 if (frame_size <= 0) frame_size = 1;
1166 if (chunk == 0) chunk = frame_size;
1168 while (result < len && size_limit > 0) {
1169 size_t n = min(chunk, len - result);
1171 size_t accepted = p_out->
write((
uint8_t *)data + result, n);
1174 if (accepted < n)
break;
1179 LOGI(
"The defined size was written - so we close the WAVEncoder now");
1290 "setupEncodedAudio: no output stream was provided - call "
1291 "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