3#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
17 if (
id == AV_CODEC_ID_ADPCM_IMA_AMV) {
22 p_decoder = adpcm_ffmpeg::ADPCMDecoderFactory::create(
id);
23 if (p_decoder !=
nullptr) {
24 p_decoder->setCodecID(
id);
27 LOGE(
"Decoder not implemented");
32 void setBlockSize(
int blockSize)
override {
33 if (p_decoder ==
nullptr)
return;
40 if (p_decoder ==
nullptr)
return 0;
41 return p_decoder->blockSize();
47 if (p_decoder ==
nullptr)
return 0;
48 return p_decoder->frameSize() * 2;
51 bool begin()
override {
53 if (p_decoder ==
nullptr)
return false;
54 if (is_started)
return true;
60 block_size = p_decoder->blockSize();
61 assert(block_size > 0);
62 assert(p_decoder->frameSize() > 0);
63 adpcm_block.resize(block_size);
65 notifyAudioChange(info);
72 if (p_decoder !=
nullptr) p_decoder->end();
73 adpcm_block.resize(0);
77 virtual void setOutput(
Print &out_stream)
override { p_print = &out_stream; }
79 virtual size_t write(
const uint8_t *data,
size_t len)
override {
82 uint8_t *input_buffer8 = (uint8_t *)data;
83 LOGD(
"write: %d", (
int)len);
84 for (
int j = 0; j < len; j++) {
85 decode(input_buffer8[j]);
91 if (p_decoder !=
nullptr) p_decoder->flush();
94 operator bool()
override {
return is_started; }
97 adpcm_ffmpeg::ADPCMDecoder *p_decoder =
nullptr;
98 Vector<uint8_t> adpcm_block;
99 Print *p_print =
nullptr;
100 int current_byte = 0;
102 bool is_started =
false;
104 virtual bool decode(uint8_t
byte) {
105 if (p_decoder ==
nullptr)
return false;
106 adpcm_block[current_byte++] = byte;
108 if (current_byte >= block_size) {
110 adpcm_ffmpeg::AVFrame &frame =
111 p_decoder->decode(&adpcm_block[0], block_size);
113 int16_t *data = (int16_t *)frame.data[0];
114 size_t byte_count = frame.nb_samples *
sizeof(int16_t) * info.
channels;
115 size_t written = p_print->write((uint8_t *)data, byte_count);
116 if (written != byte_count) {
117 LOGE(
"decode %d -> %d -> %d", block_size, (
int)byte_count,
120 LOGD(
"decode %d -> %d -> %d", block_size, (
int)byte_count,
141 if (
id == AV_CODEC_ID_ADPCM_IMA_AMV) {
146 p_encoder = adpcm_ffmpeg::ADPCMEncoderFactory::create(
id);
147 if (p_encoder !=
nullptr) {
148 p_encoder->setCodecID(
id);
151 LOGE(
"Encoder not implemented");
158 if (p_encoder ==
nullptr)
return 0;
159 return p_encoder->blockSize();
165 if (p_encoder ==
nullptr)
return 0;
166 return p_encoder->frameSize() * 2;
169 bool begin()
override {
171 if (p_encoder ==
nullptr)
return false;
172 if (is_started)
return true;
178 assert(p_encoder->frameSize() != 0);
179 total_samples = p_encoder->frameSize() * info.
channels;
180 pcm_block.resize(total_samples);
187 void end()
override {
190 if (p_encoder ==
nullptr)
return;
195 const char *
mime()
override {
return "audio/adpcm"; }
197 void setOutput(
Print &out_stream)
override { p_print = &out_stream; }
199 operator bool()
override {
return is_started; }
201 size_t write(
const uint8_t *data,
size_t len)
override {
202 LOGD(
"write: %d", (
int)len);
203 int16_t *data16 = (int16_t *)data;
204 for (
int j = 0; j < len / 2; j++) {
211 adpcm_ffmpeg::ADPCMEncoder *p_encoder =
nullptr;
212 Vector<int16_t> pcm_block;
213 Print *p_print =
nullptr;
214 bool is_started =
false;
215 int current_sample = 0;
216 int total_samples = 0;
218 virtual bool encode(int16_t sample) {
219 if (p_encoder ==
nullptr)
return false;
220 pcm_block[current_sample++] = sample;
221 if (current_sample >= total_samples) {
223 adpcm_ffmpeg::AVPacket &packet =
224 p_encoder->encode(&pcm_block[0], total_samples);
225 if (packet.size > 0) {
226 size_t written = p_print->write(packet.data, packet.size);
227 if (written != packet.size) {
228 LOGE(
"encode %d->%d->%d", 2 * total_samples, (
int)packet.size,
231 LOGD(
"encode %d->%d->%d", 2 * total_samples, (
int)packet.size,