3#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
25 if (p_decoder)
delete p_decoder;
29 void setId(AVCodecID
id) {
31 if (p_decoder !=
nullptr) {
37 void setBlockSize(
int blockSize)
override {
39 if (p_decoder ==
nullptr)
return;
46 if (p_decoder ==
nullptr)
return block_size;
47 return p_decoder->blockSize();
53 if (p_decoder ==
nullptr)
return 0;
54 return p_decoder->frameSize() * 2;
57 bool begin()
override {
59 if (p_decoder ==
nullptr) {
62 if (is_started)
return true;
68 block_size = p_decoder->blockSize();
69 assert(block_size > 0);
70 assert(p_decoder->frameSize() > 0);
71 adpcm_block.resize(block_size);
73 notifyAudioChange(info);
80 if (p_decoder !=
nullptr) p_decoder->end();
81 adpcm_block.resize(0);
85 virtual void setOutput(
Print &out_stream)
override { p_print = &out_stream; }
87 virtual size_t write(
const uint8_t *data,
size_t len)
override {
90 uint8_t *input_buffer8 = (uint8_t *)data;
91 LOGD(
"write: %d", (
int)len);
92 for (
int j = 0; j < len; j++) {
93 decode(input_buffer8[j]);
99 if (p_decoder !=
nullptr) p_decoder->flush();
102 operator bool()
override {
return is_started; }
105 adpcm_ffmpeg::ADPCMDecoder *p_decoder =
nullptr;
106 Vector<uint8_t> adpcm_block;
107 Print *p_print =
nullptr;
108 int current_byte = 0;
109 int block_size = ADAPCM_DEFAULT_BLOCK_SIZE;
110 AVCodecID codec_id = AV_CODEC_ID_ADPCM_MS;
111 bool is_started =
false;
113 virtual bool decode(uint8_t
byte) {
114 if (p_decoder ==
nullptr)
return false;
115 adpcm_block[current_byte++] = byte;
117 if (current_byte >= block_size) {
119 adpcm_ffmpeg::AVFrame &frame =
120 p_decoder->decode(&adpcm_block[0], block_size);
122 int16_t *data = (int16_t *)frame.data[0];
123 size_t byte_count = frame.nb_samples *
sizeof(int16_t) * info.
channels;
124 size_t written = p_print->write((uint8_t *)data, byte_count);
125 if (written != byte_count) {
126 LOGE(
"decode %d -> %d -> %d", block_size, (
int)byte_count,
129 LOGD(
"decode %d -> %d -> %d", block_size, (
int)byte_count,
142 if (p_decoder !=
nullptr) {
148 if (codec_id == AV_CODEC_ID_ADPCM_IMA_AMV) {
153 p_decoder = adpcm_ffmpeg::ADPCMDecoderFactory::create(codec_id);
154 if (p_decoder !=
nullptr) {
155 p_decoder->setCodecID(codec_id);
156 p_decoder->setBlockSize(block_size);
158 LOGE(
"Decoder not implemented");
181 if (p_encoder !=
nullptr)
delete p_encoder;
187 if (p_encoder !=
nullptr) {
195 if (p_encoder ==
nullptr)
return;
202 if (p_encoder ==
nullptr)
return 0;
203 return p_encoder->blockSize();
209 if (p_encoder ==
nullptr)
return 0;
210 return p_encoder->frameSize() * 2;
213 bool begin()
override {
215 if (p_encoder ==
nullptr) {
218 if (is_started)
return true;
224 assert(p_encoder->frameSize() != 0);
225 total_samples = p_encoder->frameSize() * info.
channels;
226 pcm_block.resize(total_samples);
233 void end()
override {
236 if (p_encoder ==
nullptr)
return;
241 const char *
mime()
override {
return "audio/adpcm"; }
243 void setOutput(
Print &out_stream)
override { p_print = &out_stream; }
245 operator bool()
override {
return is_started; }
247 size_t write(
const uint8_t *data,
size_t len)
override {
248 LOGD(
"write: %d", (
int)len);
249 int16_t *data16 = (int16_t *)data;
250 for (
int j = 0; j < len / 2; j++) {
257 AVCodecID codec_id = AV_CODEC_ID_ADPCM_MS;
258 adpcm_ffmpeg::ADPCMEncoder *p_encoder =
nullptr;
259 Vector<int16_t> pcm_block;
260 Print *p_print =
nullptr;
261 bool is_started =
false;
262 int current_sample = 0;
263 int total_samples = 0;
265 int block_size = ADAPCM_DEFAULT_BLOCK_SIZE;
267 virtual bool encode(int16_t sample) {
268 if (p_encoder ==
nullptr)
return false;
269 pcm_block[current_sample++] = sample;
270 if (current_sample >= total_samples) {
272 adpcm_ffmpeg::AVPacket &packet =
273 p_encoder->encode(&pcm_block[0], total_samples);
274 if (packet.size > 0) {
275 size_t written = p_print->write(packet.data, packet.size);
276 if (written != packet.size) {
277 LOGE(
"encode %d->%d->%d", 2 * total_samples, (
int)packet.size,
280 LOGD(
"encode %d->%d->%d", 2 * total_samples, (
int)packet.size,
293 if (p_encoder !=
nullptr) {
299 if (codec_id == AV_CODEC_ID_ADPCM_IMA_AMV) {
304 p_encoder = adpcm_ffmpeg::ADPCMEncoderFactory::create(codec_id);
305 if (p_encoder !=
nullptr) {
306 p_encoder->setCodecID(codec_id);
307 p_encoder->setBlockSize(block_size);
309 LOGE(
"Encoder not implemented");