Skip to content

Commit 2e88628

Browse files
committed
Correct ADPCM
1 parent 2d3fc49 commit 2e88628

File tree

5 files changed

+68
-16
lines changed

5 files changed

+68
-16
lines changed

examples/tests/codecs/test-codec-adpcm/test-codec-adpcm.ino

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with
1818
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
1919
//AudioBoardStream out(AudioKitEs8388V1);
2020
//I2SStream out;
21-
AudioBoardStream out(AudioKitEs8388V1);
22-
EncodedAudioStream decoder(&out, new ADPCMDecoder(AV_CODEC_ID_ADPCM_IMA_WAV)); // encode and write
23-
EncodedAudioStream encoder(&decoder, new ADPCMEncoder(AV_CODEC_ID_ADPCM_IMA_WAV)); // encode and write
21+
//AudioBoardStream out(AudioKitEs8388V1);
22+
CsvOutput<int16_t> out(Serial);
23+
AVCodecID id = AV_CODEC_ID_ADPCM_IMA_WAV;
24+
EncodedAudioStream decoder(&out, new ADPCMDecoder(id)); // encode and write
25+
EncodedAudioStream encoder(&decoder, new ADPCMEncoder(id)); // encode and write
2426
StreamCopy copier(encoder, sound);
2527

2628
void setup() {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include "AudioTools.h"
2+
#include "AudioCodecs/CodecWAV.h"
3+
#include "AudioCodecs/CodecADPCM.h"
4+
5+
AudioInfo info(16000, 2, 16);
6+
SineWaveGenerator<int16_t> sineWave( 32000);
7+
GeneratedSoundStream<int16_t> sound( sineWave);
8+
CsvOutput<int16_t> out(Serial);
9+
AVCodecID id = AV_CODEC_ID_ADPCM_IMA_WAV;
10+
ADPCMDecoder adpcm_decoder(id);
11+
ADPCMEncoder adpcm_encoder(id);
12+
WAVDecoder wav_decoder(adpcm_decoder, AudioFormat::ADPCM);
13+
WAVEncoder wav_encoder(adpcm_encoder, AudioFormat::ADPCM);
14+
EncodedAudioStream decoder(&out, &wav_decoder);
15+
EncodedAudioStream encoder(&decoder, &wav_encoder);
16+
StreamCopy copier(encoder, sound);
17+
18+
void setup() {
19+
Serial.begin(115200);
20+
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
21+
22+
// start Output
23+
auto cfgi = out.defaultConfig(TX_MODE);
24+
cfgi.copyFrom(info);
25+
out.begin(cfgi);
26+
27+
// Setup sine wave
28+
auto cfgs = sineWave.defaultConfig();
29+
cfgs.copyFrom(info);
30+
sineWave.begin(info, N_B4);
31+
32+
// start decoder
33+
decoder.begin(info);
34+
35+
// start encoder
36+
encoder.begin(info);
37+
}
38+
39+
void loop() {
40+
copier.copy();
41+
}

src/AudioCodecs/CodecWAV.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,14 @@ class WAVHeader {
149149
}
150150

151151
/// Just write a wav header to the indicated output
152-
void writeHeader(Print *out) {
152+
int writeHeader(Print *out) {
153153
SingleBuffer<uint8_t> buffer(50);
154154
writeRiffHeader(buffer);
155155
writeFMT(buffer);
156156
writeDataHeader(buffer);
157157
len = buffer.available();
158158
out->write(buffer.data(), buffer.available());
159+
return len;
159160
}
160161

161162
protected:
@@ -325,9 +326,9 @@ class WAVDecoder : public AudioDecoder {
325326
if (active) {
326327
if (isFirst) {
327328
result = decodeHeader((uint8_t*) data, len);
328-
if (result<len){
329-
result += write_out((uint8_t *)data+result, len-result);
330-
}
329+
// if (result<len){
330+
// result += write_out((uint8_t *)data+result, len-result);
331+
// }
331332
} else if (isValid) {
332333
result = write_out((uint8_t *)data, len);
333334
}
@@ -354,7 +355,8 @@ class WAVDecoder : public AudioDecoder {
354355
virtual size_t write_out(const uint8_t *in_ptr, size_t in_size) {
355356
// check if we need to convert int24 data from 3 bytes to 4 bytes
356357
size_t result = 0;
357-
if (header.audioInfo().bits_per_sample == 24 && sizeof(int24_t)==4){
358+
if (header.audioInfo().format == AudioFormat::PCM
359+
&& header.audioInfo().bits_per_sample == 24 && sizeof(int24_t)==4){
358360
write_out_24(in_ptr, in_size);
359361
result = in_size;
360362
} else {
@@ -440,8 +442,10 @@ class WAVDecoder : public AudioDecoder {
440442
bi.bits_per_sample = header.audioInfo().bits_per_sample;
441443
notifyAudioChange(bi);
442444
// write prm data from first record
443-
LOGI("WAVDecoder writing first sound data");
444-
result = out().write(sound_ptr, len);
445+
if (len > 0) {
446+
LOGI("WAVDecoder writing first sound data");
447+
result = out().write(sound_ptr, len);
448+
}
445449
} else {
446450
LOGE("WAV format not supported: %d", (int)format);
447451
}
@@ -453,7 +457,7 @@ class WAVDecoder : public AudioDecoder {
453457
assert(p_print!=nullptr);
454458
dec_out.setOutput(p_print);
455459
dec_out.setDecoder(p_decoder);
456-
dec_out.begin();
460+
dec_out.begin(info);
457461
}
458462
}
459463
};
@@ -522,6 +526,7 @@ class WAVEncoder : public AudioEncoder {
522526
/// Defines the WAVAudioInfo
523527
virtual void setAudioInfo(WAVAudioInfo ai) {
524528
AudioEncoder::setAudioInfo(ai);
529+
if (p_encoder) p_encoder->setAudioInfo(ai);
525530
audioInfo = ai;
526531
LOGI("sample_rate: %d", (int)audioInfo.sample_rate);
527532
LOGI("channels: %d", audioInfo.channels);
@@ -575,8 +580,8 @@ class WAVEncoder : public AudioEncoder {
575580
if (!header_written) {
576581
LOGI("Writing Header");
577582
header.setAudioInfo(audioInfo);
578-
header.writeHeader(p_print);
579-
audioInfo.file_size -= 44;
583+
int len = header.writeHeader(p_print);
584+
audioInfo.file_size -= len;
580585
header_written = true;
581586
}
582587

src/AudioTools/AudioOutput.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ template <typename T> class CsvOutput : public AudioOutput {
175175
return 0;
176176
}
177177

178+
if (len==0){
179+
return 0;
180+
}
181+
178182
if (cfg.channels == 0) {
179183
LOGW("Channels not defined: using 2");
180184
cfg.channels = 2;

tests-cmake/codec/wav/wav.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ AudioInfo info(16000, 2, 16);
2020
SineWaveGenerator<int16_t> sineWave( 32000); // subclass of SoundGenerator with max amplitude of 32000
2121
GeneratedSoundStream<int16_t> sound( sineWave); // Stream generated from sine wave
2222
//I2SStream out;
23-
PortAudioStream out;
24-
//CsvOutput<int16_t> out(Serial);
23+
//PortAudioStream out;
24+
CsvOutput<int16_t> out(Serial);
2525
#if USE_ADPCM
2626
ADPCMDecoder adpcm_decoder(AV_CODEC_ID_ADPCM_IMA_WAV);
2727
ADPCMEncoder adpcm_encoder(AV_CODEC_ID_ADPCM_IMA_WAV);
@@ -35,7 +35,7 @@ StreamCopy copier(encoder, sound);
3535

3636
void setup() {
3737
Serial.begin(115200);
38-
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
38+
AudioLogger::instance().begin(Serial, AudioLogger::Debug);
3939

4040
// start I2S
4141
Serial.println("starting Output...");

0 commit comments

Comments
 (0)