11 #include "AudioTools/AudioCodecs/AudioCodecsBase.h"
13 #include "sbc/formats.h"
30 result_buffer =
new uint8_t[bufferSize];
31 result_buffer_size = bufferSize;
35 if (result_buffer !=
nullptr)
36 delete[] result_buffer;
37 if (input_buffer !=
nullptr)
38 delete[] input_buffer;
41 virtual bool begin() {
57 operator bool() {
return is_active; }
59 virtual size_t write(
const uint8_t *data,
size_t len) {
60 LOGD(
"write: %d", len);
66 uint8_t *start = (uint8_t *)data;
70 LOGI(
"framelen: %d", framelen);
72 if (isValidFrameLen(framelen)) {
73 start = start + framelen;
74 count = len - framelen;
80 for (
int j = 0; j < count; j++) {
90 int bytesUncompressed() {
99 Print *p_print =
nullptr;
101 bool is_first =
true;
102 bool is_active =
false;
103 uint8_t *result_buffer =
nullptr;
104 int result_buffer_size;
106 uint8_t *input_buffer =
nullptr;
113 int codeSize() {
return sbc_get_codesize(&sbc); }
118 info.
channels = sbc.mode == SBC_MODE_MONO ? 1 : 2;
119 LOGI(
"channels: %d", info.
channels);
120 switch (sbc.frequency) {
134 LOGE(
"Unsupported sample rate");
139 notifyAudioChange(info);
142 bool isValidFrameLen(
int len) {
return len > 0 && len < 256; }
146 size_t result_len = 0;
147 int frame_len = sbc_parse(&sbc, data, length);
148 if (isValidFrameLen(frame_len)) {
154 setupInputBuffer(frame_len);
160 void setupInputBuffer(
int len) {
161 LOGI(
"input_buffer: %d", len);
162 if (input_buffer !=
nullptr)
163 delete[] input_buffer;
164 input_buffer =
new uint8_t[len];
170 input_buffer[input_pos++] = byte;
173 if (input_pos >= framelen) {
174 size_t result_len = 0;
175 sbc_decode(&sbc, input_buffer, framelen, result_buffer,
176 result_buffer_size, &result_len);
177 if (result_len > 0) {
178 p_print->write(result_buffer, result_len);
196 SBCEncoder(
int subbands = 8,
int blocks = 16,
int bitpool = 32,
197 int allocation_method = SBC_AM_LOUDNESS) {
206 if (subbands == 8 || subbands == 4) {
207 this->subbands = subbands;
209 LOGE(
"Invalid subbands: %d - using 8", subbands);
216 if (blocks == 16 || blocks == 12 || blocks == 8 || blocks == 4) {
217 this->blocks = blocks;
219 LOGE(
"Invalid blocks: %d - using 16", blocks);
229 if (allocation_method == SBC_AM_LOUDNESS || allocation_method == SBC_AM_SNR) {
230 this->allocation_method = allocation_method;
232 LOGE(
"Invalid allocation Method: %d - using SBC_AM_LOUDNESS", allocation_method);
233 this->allocation_method = SBC_AM_LOUDNESS;
243 buffer.resize(current_codesize);
255 virtual const char *
mime() {
return "audio/sbc"; }
257 virtual void setOutput(
Print &out_stream) { p_print = &out_stream; }
259 operator bool() {
return is_active; }
261 virtual size_t write(
const uint8_t *data,
size_t len) {
262 LOGD(
"write: %d", len);
267 if (p_print==
nullptr){
268 LOGE(
"output not defined");
273 for (
int j = 0; j < len; j++) {
274 processByte(data[j]);
281 int bytesUncompressed() {
284 int bytesCompressed() {
289 Print *p_print =
nullptr;
291 bool is_first =
true;
292 bool is_active =
false;
293 int current_codesize = 0;
295 Vector<uint8_t> buffer{0};
296 Vector<uint8_t> result_buffer{0};
300 int allocation_method;
319 sbc.frequency = SBC_FREQ_16000;
322 sbc.frequency = SBC_FREQ_32000;
325 sbc.frequency = SBC_FREQ_44100;
328 sbc.frequency = SBC_FREQ_48000;
337 sbc.mode = SBC_MODE_MONO;
340 sbc.mode = SBC_MODE_STEREO;
343 LOGE(
"Invalid channels: %d", info.
channels);
349 sbc.subbands = SBC_SB_4;
352 sbc.subbands = SBC_SB_8;
355 LOGE(
"Invalid subbands: %d", subbands);
361 sbc.blocks = SBC_BLK_4;
364 sbc.blocks = SBC_BLK_8;
367 sbc.blocks = SBC_BLK_12;
370 sbc.blocks = SBC_BLK_16;
373 LOGE(
"Invalid blocks: %d", blocks);
377 sbc.bitpool = bitpool;
378 sbc.allocation = allocation_method;
383 void processByte(uint8_t
byte) {
384 buffer[buffer_pos++] = byte;
385 if (buffer_pos >= current_codesize) {
390 sbc_encode(&sbc, &buffer[0], current_codesize, &result_buffer[0],
391 result_buffer.size(), &written);
392 LOGD(
"sbc_encode: %d -> %d (buffer: %d))", current_codesize, written,
393 result_buffer.size());
394 p_print->write(&result_buffer[0], written);