3 #include "AudioTools/AudioCodecs/AudioCodecsBase.h"
5 #define WAVE_FORMAT_IMA_ADPCM 0x0011
6 #define TAG(a, b, c, d) ((static_cast<uint32_t>(a) << 24) | (static_cast<uint32_t>(b) << 16) | (static_cast<uint32_t>(c) << 8) | (d))
7 #define READ_BUFFER_SIZE 512
11 const int16_t ima_index_table[16] {
12 -1, -1, -1, -1, 2, 4, 6, 8,
13 -1, -1, -1, -1, 2, 4, 6, 8
16 const int32_t ima_step_table[89] {
17 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
18 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
19 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
20 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
21 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
22 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
23 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
24 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
25 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
43 int format = WAVE_FORMAT_IMA_ADPCM;
46 int frames_per_block = 0;
48 bool is_valid =
false;
49 uint32_t data_length = 0;
50 uint32_t file_size = 0;
54 int32_t predictor = 0;
58 const char* wav_ima_mime =
"audio/x-wav";
69 IMA_ERR_INVALID_CHUNK = -2,
70 IMA_ERR_INVALID_CONTAINER,
84 headerInfo.is_valid =
false;
85 header_complete =
false;
94 bool chunkUnknown =
false;
95 uint32_t tag = read_tag();
96 uint32_t length = read_int32();
98 return IMA_ERR_INVALID_CHUNK;
100 if (tag == TAG(
'R',
'I',
'F',
'F')) {
101 uint32_t container_type = read_tag();
102 if (container_type != TAG(
'W',
'A',
'V',
'E')) {
103 return IMA_ERR_INVALID_CONTAINER;
106 else if (tag == TAG(
'f',
'm',
't',
' ')) {
109 return IMA_ERR_INVALID_CHUNK;
111 headerInfo.format = read_int16();
114 headerInfo.byte_rate = read_int32();
115 headerInfo.block_align = read_int16();
120 headerInfo.frames_per_block = read_int16();
121 if (headerInfo.format != WAVE_FORMAT_IMA_ADPCM || headerInfo.
channels > 2) {
123 LOGE(
"Format not supported: %d, %d\n", headerInfo.format, headerInfo.
channels);
124 return IMA_ERR_INVALID_CHUNK;
126 headerInfo.is_valid =
true;
128 }
else if (tag == TAG(
'f',
'a',
'c',
't')) {
132 headerInfo.num_samples = read_int32();
133 }
else if (tag == TAG(
'd',
'a',
't',
'a')) {
135 headerInfo.data_length = length;
140 if (tag != TAG(
'R',
'I',
'F',
'F') && length > 20) skip_len = length - 20;
141 return chunkUnknown ? IMA_CHUNK_UNKNOWN : IMA_CHUNK_OK;
147 int write(uint8_t* data,
size_t data_len) {
150 while (data_len > 0 && !header_complete) {
154 write_len = min(skip_len, data_len);
155 skip_len -= write_len;
156 data_offset += write_len;
157 data_len -= write_len;
161 write_len = min(data_len, max_chunk_len - chunk_len);
162 memmove(chunk_buffer + chunk_len, data + data_offset, write_len);
163 chunk_len += write_len;
164 data_offset += write_len;
165 data_len -= write_len;
167 if (chunk_len == max_chunk_len) {
169 if (max_chunk_len == 8) {
170 uint32_t chunk_tag = read_tag();
171 uint32_t chunk_size = read_int32();
172 if (isFirstChunk && chunk_tag != TAG(
'R',
'I',
'F',
'F')) {
173 headerInfo.is_valid =
false;
174 return IMA_ERR_INVALID_CONTAINER;
176 isFirstChunk =
false;
177 if (chunk_tag == TAG(
'R',
'I',
'F',
'F')) chunk_size = 4;
178 else if (chunk_tag == TAG(
'd',
'a',
't',
'a')) {
180 header_complete =
true;
187 write_len = min((
size_t)chunk_size, (
size_t)20);
188 max_chunk_len += write_len;
195 case IMA_ERR_INVALID_CONTAINER:
196 case IMA_ERR_INVALID_CHUNK:
197 headerInfo.is_valid =
false;
212 return header_complete;
221 struct WavIMAAudioInfo headerInfo;
222 uint8_t chunk_buffer[28];
223 size_t chunk_len = 0;
224 size_t max_chunk_len = 8;
227 bool header_complete =
false;
228 bool isFirstChunk =
true;
230 uint32_t read_tag() {
231 uint32_t tag = getChar();
232 tag = (tag << 8) | getChar();
233 tag = (tag << 8) | getChar();
234 tag = (tag << 8) | getChar();
238 uint32_t read_int32() {
239 uint32_t value = (uint32_t)getChar();
240 value |= (uint32_t)getChar() << 8;
241 value |= (uint32_t)getChar() << 16;
242 value |= (uint32_t)getChar() << 24;
246 uint16_t read_int16() {
247 uint16_t value = getChar();
248 value |= getChar() << 8;
253 n = min((
size_t)n, chunk_len - data_pos);
254 for (
int i=0; i<n; i++)
if (data_pos < chunk_len) data_pos++;
259 if (data_pos < chunk_len)
return chunk_buffer[data_pos++];
264 LOGI(
"WavIMAHeader format: %d", headerInfo.format);
265 LOGI(
"WavIMAHeader channels: %d", headerInfo.
channels);
266 LOGI(
"WavIMAHeader sample_rate: %d", headerInfo.
sample_rate);
267 LOGI(
"WavIMAHeader block align: %d", headerInfo.block_align);
303 this->out = &out_stream;
304 this->active = active;
316 this->out = &out_stream;
321 if (input_buffer !=
nullptr)
delete[] input_buffer;
322 if (output_buffer !=
nullptr)
delete[] output_buffer;
327 this->out = &out_stream;
332 ima_states[0].predictor = 0;
333 ima_states[0].step_index = 0;
334 ima_states[1].predictor = 0;
335 ima_states[1].step_index = 0;
338 header.clearHeader();
351 WavIMAAudioInfo &audioInfoEx() {
352 return header.audioInfo();
356 return header.audioInfo();
359 virtual size_t write(
const uint8_t *data,
size_t len) {
364 int written = header.write((uint8_t*)data, len);
365 if (written == IMA_ERR_INVALID_CONTAINER || written == IMA_ERR_INVALID_CHUNK) {
368 LOGE(
"File is not valid");
376 size_t len_open = len - written;
377 uint8_t *sound_ptr = (uint8_t *) data + written;
379 isValid = header.audioInfo().is_valid;
381 LOGI(
"WAV sample_rate: %d", header.audioInfo().
sample_rate);
382 LOGI(
"WAV data_length: %u", (
unsigned) header.audioInfo().data_length);
383 LOGI(
"WAV is_valid: %s", header.audioInfo().is_valid ?
"true" :
"false");
385 isValid = header.audioInfo().is_valid;
387 if (input_buffer !=
nullptr)
delete[] input_buffer;
388 if (output_buffer !=
nullptr)
delete[] output_buffer;
389 bytes_per_encoded_block = header.audioInfo().block_align;
390 bytes_per_decoded_block = header.audioInfo().frames_per_block * header.audioInfo().
channels * 2;
391 samples_per_decoded_block = bytes_per_decoded_block >> 1;
392 input_buffer =
new uint8_t[bytes_per_encoded_block];
393 output_buffer =
new int16_t[samples_per_decoded_block];
397 bi.channels = header.audioInfo().
channels;
398 bi.bits_per_sample = 16;
399 remaining_bytes = header.audioInfo().data_length;
400 notifyAudioChange(bi);
402 LOGI(
"WavIMADecoder writing first sound data");
403 processInput(sound_ptr, len_open);
405 }
else if (isValid) {
406 processInput((uint8_t*)data, len);
415 uint8_t buffer[READ_BUFFER_SIZE];
416 int len = in.readBytes(buffer, READ_BUFFER_SIZE);
417 return write(buffer, len);
420 virtual operator bool() {
430 uint8_t *input_buffer =
nullptr;
431 int32_t input_pos = 0;
432 size_t remaining_bytes = 0;
433 size_t bytes_per_encoded_block = 0;
434 int16_t *output_buffer =
nullptr;
435 size_t bytes_per_decoded_block = 0;
436 size_t samples_per_decoded_block = 0;
437 IMAState ima_states[2];
439 int16_t decodeSample(uint8_t sample,
int channel = 0) {
440 int step_index = ima_states[channel].step_index;
441 int32_t step = ima_step_table[step_index];
442 step_index += ima_index_table[sample];
443 if (step_index < 0) step_index = 0;
444 else if (step_index > 88) step_index = 88;
445 ima_states[channel].step_index = step_index;
446 int32_t predictor = ima_states[channel].predictor;
447 uint8_t sign = sample & 8;
448 uint8_t delta = sample & 7;
449 int32_t diff = step >> 3;
450 if (delta & 4) diff += step;
451 if (delta & 2) diff += (step >> 1);
452 if (delta & 1) diff += (step >> 2);
453 if (sign) predictor -= diff;
454 else predictor += diff;
455 if (predictor < -32768) predictor = -32768;
456 else if (predictor > 32767) predictor = 32767;
457 ima_states[channel].predictor = predictor;
458 return (int16_t)predictor;
461 void decodeBlock(
int channels) {
462 if (channels == 0 || channels > 2)
return;
465 ima_states[0].predictor = (int16_t)((input_buffer[1] << 8) + input_buffer[0]);
466 ima_states[0].step_index = input_buffer[2];
467 output_buffer[0] = ima_states[0].predictor;
469 ima_states[1].predictor = (int16_t)(input_buffer[5] << 8) + input_buffer[4];
470 ima_states[1].step_index = input_buffer[6];
471 output_buffer[1] = ima_states[1].predictor;
475 for (
int i=0; i<samples_per_decoded_block-channels; i++) {
476 uint8_t sample = (i & 1) ? input_buffer[input_pos++] >> 4 : input_buffer[input_pos] & 15;
477 if (channels == 1) output_buffer[output_pos++] = decodeSample(sample);
479 output_buffer[output_pos] = decodeSample(sample, (i >> 3) & 1);
481 if ((i & 15) == 7) output_pos -= 15;
482 else if ((i & 15) == 15) output_pos--;
487 void processInput(
const uint8_t* data,
size_t size) {
488 int max_size = min(size, remaining_bytes);
489 for (
int i=0; i<max_size; i++) {
490 input_buffer[input_pos++] = data[i];
491 if (input_pos == bytes_per_encoded_block) {
492 decodeBlock(header.audioInfo().channels);
494 out->write((uint8_t*)output_buffer, bytes_per_decoded_block);
497 remaining_bytes -= max_size;
498 if (remaining_bytes == 0) active =
false;