3 #include "AudioCodecs/AudioCodecsBase.h"
7 #define TAG(a, b, c, d) \
8 ((static_cast<uint32_t>(a) << 24) | (static_cast<uint32_t>(b) << 16) | \
9 (static_cast<uint32_t>(c) << 8) | (d))
10 #define READ_BUFFER_SIZE 512
31 bool is_streamed =
true;
32 bool is_valid =
false;
33 uint32_t data_length = 0;
34 uint32_t file_size = 0;
38 static const char *wav_mime =
"audio/wav";
52 int write(uint8_t *data,
size_t data_len) {
53 int write_len = min(data_len, 44 - len);
54 memmove(buffer, data + len, write_len);
56 LOGI(
"WAVHeader::write: %u -> %d -> %d", (
unsigned)data_len, write_len,
63 LOGI(
"WAVHeader::begin: %u", (
unsigned)len);
67 uint32_t tag, tag2, length;
70 length = read_int32();
71 if (!length || length >= 0x7fff0000) {
72 headerInfo.is_streamed =
true;
75 if (tag != TAG(
'R',
'I',
'F',
'F') || length < 4) {
76 seek(length, SEEK_CUR);
79 headerInfo.file_size = length;
82 if (tag2 != TAG(
'W',
'A',
'V',
'E')) {
83 seek(length, SEEK_CUR);
88 uint32_t subtag, sublength;
91 sublength = read_int32();
93 if (length < sublength)
break;
94 if (subtag == TAG(
'f',
'm',
't',
' ')) {
100 headerInfo.channels = read_int16();
101 headerInfo.sample_rate = read_int32();
102 headerInfo.byte_rate = read_int32();
103 headerInfo.block_align = read_int16();
104 headerInfo.bits_per_sample = read_int16();
106 if (sublength < 28) {
112 skip(sublength - 28);
114 skip(sublength - 16);
116 headerInfo.is_valid =
true;
117 }
else if (subtag == TAG(
'd',
'a',
't',
'a')) {
119 headerInfo.data_length = sublength;
120 if (!headerInfo.data_length || headerInfo.is_streamed) {
121 headerInfo.is_streamed =
true;
125 seek(sublength, SEEK_CUR);
133 seek(length, SEEK_CUR);
154 writeRiffHeader(buffer);
156 writeDataHeader(buffer);
166 size_t sound_pos = 0;
168 uint32_t read_tag() {
170 tag = (tag << 8) | getChar();
171 tag = (tag << 8) | getChar();
172 tag = (tag << 8) | getChar();
173 tag = (tag << 8) | getChar();
177 uint32_t getChar32() {
return getChar(); }
179 uint32_t read_int32() {
181 value |= getChar32() << 0;
182 value |= getChar32() << 8;
183 value |= getChar32() << 16;
184 value |= getChar32() << 24;
188 uint16_t read_int16() {
190 value |= getChar() << 0;
191 value |= getChar() << 8;
197 for (i = 0; i < n; i++) getChar();
202 return buffer[data_pos++];
207 void seek(
long int offset,
int origin) {
208 if (origin == SEEK_SET) {
210 }
else if (origin == SEEK_CUR) {
215 size_t tell() {
return data_pos; }
217 bool eof() {
return data_pos >= len - 1; }
220 LOGI(
"WAVHeader sound_pos: %lu", (
unsigned long)sound_pos);
221 LOGI(
"WAVHeader channels: %d ", headerInfo.
channels);
223 LOGI(
"WAVHeader sample_rate: %d ", (
int) headerInfo.
sample_rate);
224 LOGI(
"WAVHeader format: %d", (
int)headerInfo.format);
227 void writeRiffHeader(BaseBuffer<uint8_t> &buffer) {
228 buffer.writeArray((uint8_t *)
"RIFF", 4);
229 write32(buffer, headerInfo.file_size - 8);
230 buffer.writeArray((uint8_t *)
"WAVE", 4);
233 void writeFMT(BaseBuffer<uint8_t> &buffer) {
234 uint16_t fmt_len = 16;
235 buffer.writeArray((uint8_t *)
"fmt ", 4);
236 write32(buffer, fmt_len);
237 write16(buffer, (uint16_t)headerInfo.format);
238 write16(buffer, headerInfo.
channels);
240 write32(buffer, headerInfo.byte_rate);
241 write16(buffer, headerInfo.block_align);
245 void write32(BaseBuffer<uint8_t> &buffer, uint64_t value) {
246 buffer.writeArray((uint8_t *)&value, 4);
249 void write16(BaseBuffer<uint8_t> &buffer, uint16_t value) {
250 buffer.writeArray((uint8_t *)&value, 2);
253 void writeDataHeader(BaseBuffer<uint8_t> &buffer) {
254 buffer.writeArray((uint8_t *)
"data", 4);
255 write32(buffer, headerInfo.file_size);
256 int offset = headerInfo.offset;
258 uint8_t empty[offset];
259 memset(empty, 0, offset);
260 buffer.writeArray(empty, offset);
294 decoder_format = fmt;
301 bool begin()
override {
310 void end()
override {
316 const char *mime() {
return wav_mime; }
318 WAVAudioInfo &audioInfoEx() {
return header.
audioInfo(); }
322 virtual size_t write(
const uint8_t *data,
size_t len)
override {
327 result = decodeHeader((uint8_t*) data, len);
329 result += write_out((uint8_t *)data+result, len-result);
331 }
else if (isValid) {
332 result = write_out((uint8_t *)data, len);
338 virtual operator bool()
override {
return active; }
346 AudioDecoderExt *p_decoder =
nullptr;
347 EncodedAudioOutput dec_out;
348 SingleBuffer<uint8_t> buffer24;
351 return p_decoder==
nullptr ? *p_print : dec_out;
354 virtual size_t write_out(
const uint8_t *in_ptr,
size_t in_size) {
357 if (header.audioInfo().bits_per_sample == 24 &&
sizeof(int24_t)==4){
358 write_out_24(in_ptr, in_size);
361 result = out().write(in_ptr, in_size);
367 size_t write_out_24(
const uint8_t *in_ptr,
size_t in_size) {
369 AudioInfo& info = header.audioInfo();
371 buffer24.resize(info.channels*3);
373 int32_t frame[info.channels];
374 uint8_t val24[3]={0};
377 for (
int j=0;j<in_size;j++){
378 buffer24.write(in_ptr[j]);
380 if (buffer24.availableForWrite()==0){
381 for (
int ch=0;ch<info.channels;ch++){
382 buffer24.readArray((uint8_t*)&val24[0], 3);
383 frame[ch] = interpret24bitAsInt32(val24);
386 assert(buffer24.available()==0);
388 size_t written = out().write((uint8_t*)frame,
sizeof(frame));
389 assert(written==
sizeof(frame));
396 int32_t interpret24bitAsInt32(uint8_t* byteArray) {
398 (
static_cast<int32_t
>(byteArray[2]) << 24)
399 | (
static_cast<int32_t
>(byteArray[1]) << 16)
400 | (
static_cast<int32_t
>(byteArray[0]) << 8)
405 int decodeHeader(uint8_t *in_ptr,
size_t in_size) {
408 int written = header.write(in_ptr, in_size);
409 if (!header.isDataComplete()) {
415 size_t len = in_size - written;
416 uint8_t *sound_ptr = (uint8_t *)in_ptr + written;
418 isValid = header.audioInfo().is_valid;
420 LOGI(
"WAV sample_rate: %d", (
int) header.audioInfo().sample_rate);
421 LOGI(
"WAV data_length: %u", (
unsigned)header.audioInfo().data_length);
422 LOGI(
"WAV is_streamed: %d", header.audioInfo().is_streamed);
423 LOGI(
"WAV is_valid: %s",
424 header.audioInfo().is_valid ?
"true" :
"false");
428 isValid = format == decoder_format;
431 if(p_decoder!=
nullptr){
432 int block_size = header.audioInfo().block_align;
433 p_decoder->setBlockSize(block_size);
438 bi.sample_rate = header.audioInfo().sample_rate;
439 bi.channels = header.audioInfo().channels;
440 bi.bits_per_sample = header.audioInfo().bits_per_sample;
441 notifyAudioChange(bi);
443 LOGI(
"WAVDecoder writing first sound data");
444 result = out().write(sound_ptr, len);
446 LOGE(
"WAV format not supported: %d", (
int)format);
451 void setupEncodedAudio() {
452 if (p_decoder!=
nullptr){
453 assert(p_print!=
nullptr);
454 dec_out.setOutput(p_print);
455 dec_out.setDecoder(p_decoder);
481 setEncoder(enc, fmt);
486 audioInfo.format = fmt;
497 const char *
mime()
override {
return wav_mime; }
502 info.format = AudioFormat::PCM;
506 info.is_streamed =
true;
507 info.is_valid =
true;
508 info.data_length = 0x7fff0000;
509 info.file_size = info.data_length + 36;
526 LOGI(
"sample_rate: %d", (
int)audioInfo.
sample_rate);
527 LOGI(
"channels: %d", audioInfo.
channels);
530 if (audioInfo.format == AudioFormat::PCM){
533 if (audioInfo.is_streamed || audioInfo.data_length == 0 ||
534 audioInfo.data_length >= 0x7fff0000) {
535 LOGI(
"is_streamed! because length is %u",
536 (
unsigned)audioInfo.data_length);
537 audioInfo.is_streamed =
true;
538 audioInfo.data_length = ~0;
540 size_limit = audioInfo.data_length;
541 LOGI(
"size_limit is %d", (
int)size_limit);
555 header_written =
false;
561 void end()
override { is_open =
false; }
564 virtual size_t write(
const uint8_t *data,
size_t len)
override {
566 LOGE(
"The WAVEncoder is not open - please call begin()");
570 if (p_print ==
nullptr) {
571 LOGE(
"No output stream was provided");
575 if (!header_written) {
576 LOGI(
"Writing Header");
577 header.setAudioInfo(audioInfo);
578 header.writeHeader(p_print);
579 audioInfo.file_size -= 44;
580 header_written =
true;
584 Print *p_out = p_encoder==
nullptr ? p_print : &enc_out;;
585 if (audioInfo.is_streamed) {
586 result = p_out->write((uint8_t *)data, len);
587 }
else if (size_limit > 0) {
588 size_t write_size = min((
size_t)len, (
size_t)size_limit);
589 result = p_out->write((uint8_t *)data, write_size);
590 size_limit -= result;
592 if (size_limit <= 0) {
593 LOGI(
"The defined size was written - so we close the WAVEncoder now");
600 operator bool()
override {
return is_open; }
602 bool isOpen() {
return is_open; }
609 Print *p_print =
nullptr;
613 int64_t size_limit = 0;
614 bool header_written =
false;
615 volatile bool is_open =
false;
617 void setupEncodedAudio() {
618 if (p_encoder!=
nullptr){
619 assert(p_print!=
nullptr);
621 enc_out.setEncoder(p_encoder);
625 audioInfo.block_align = p_encoder->blockSize();
AudioFormat
Audio format codes used by Microsoft e.g. in avi or wav files.
Definition: AudioFormat.h:19