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"; }
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++) {
258 if (p_encoder ==
nullptr || info.
sample_rate == 0) {
274 AVCodecID codec_id = AV_CODEC_ID_ADPCM_MS;
275 adpcm_ffmpeg::ADPCMEncoder *p_encoder =
nullptr;
277 Print *p_print =
nullptr;
278 bool is_started =
false;
279 int current_sample = 0;
280 int total_samples = 0;
282 int block_size = ADAPCM_DEFAULT_BLOCK_SIZE;
284 virtual bool encode(int16_t sample) {
285 if (p_encoder ==
nullptr)
return false;
286 pcm_block[current_sample++] = sample;
287 if (current_sample >= total_samples) {
289 adpcm_ffmpeg::AVPacket &packet =
290 p_encoder->encode(&pcm_block[0], total_samples);
291 if (packet.size > 0) {
292 size_t written = p_print->write(packet.data, packet.size);
293 if (written != packet.size) {
294 LOGE(
"encode %d->%d->%d", 2 * total_samples, (
int)packet.size,
297 LOGD(
"encode %d->%d->%d", 2 * total_samples, (
int)packet.size,
311 if (p_encoder !=
nullptr) {
317 if (codec_id == AV_CODEC_ID_ADPCM_IMA_AMV) {
322 p_encoder = adpcm_ffmpeg::ADPCMEncoderFactory::create(codec_id);
323 if (p_encoder !=
nullptr) {
324 p_encoder->setCodecID(codec_id);
325 p_encoder->setBlockSize(block_size);
327 LOGE(
"Encoder not implemented");