11 #include "AudioTools/AudioCodecs/AudioCodecsBase.h"
12 #include "AudioTools/CoreAudio/Buffers.h"
13 #include "AudioTools/CoreAudio/AudioBasic/Net.h"
16 #ifndef FLAC_READ_TIMEOUT_MS
17 #define FLAC_READ_TIMEOUT_MS 10000
20 #ifndef FLAC_BUFFER_SIZE
21 #define FLAC_BUFFER_SIZE (8 * 1024)
46 void setTimeout(uint64_t readTimeout=FLAC_READ_TIMEOUT_MS) {
47 read_timeout_ms = readTimeout;
49 void setOgg(
bool isOgg) {
55 info.
sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
56 info.
channels = FLAC__stream_decoder_get_channels(decoder);
64 if (decoder ==
nullptr) {
65 if ((decoder = FLAC__stream_decoder_new()) == NULL) {
66 LOGE(
"ERROR: allocating decoder");
70 LOGI(
"FLAC__stream_decoder_new");
74 auto state = FLAC__stream_decoder_get_state(decoder);
75 if (state != FLAC__STREAM_DECODER_UNINITIALIZED){
76 FLAC__stream_decoder_finish(decoder);
80 FLAC__stream_decoder_set_md5_checking(decoder, is_md5_checing);
89 if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
90 LOGE(
"ERROR: initializing decoder: %s", FLAC__StreamDecoderInitStatusString[init_status]);
101 if (decoder !=
nullptr){
103 FLAC__stream_decoder_delete(decoder);
111 while(FLAC__stream_decoder_process_single(decoder));
115 operator bool() {
return is_active; }
122 LOGW(
"FLAC not active");
125 if (p_input ==
nullptr) {
126 LOGE(
"setInput was not called");
129 if (!FLAC__stream_decoder_process_single(decoder)) {
130 LOGE(
"FLAC__stream_decoder_process_single");
138 is_md5_checing = flag;
142 bool is_active =
false;
144 bool is_md5_checing =
false;
146 FLAC__StreamDecoder *decoder =
nullptr;
147 FLAC__StreamDecoderInitStatus init_status;
148 uint64_t time_last_read = 0;
149 uint64_t read_timeout_ms = FLAC_READ_TIMEOUT_MS;
157 FLAC__StreamDecoderErrorStatus status,
159 LOGE(FLAC__StreamDecoderErrorStatusString[status]);
162 size_t readBytes(uint8_t *data,
size_t len)
override {
163 return p_input->readBytes(data, len);
167 static FLAC__StreamDecoderReadStatus
read_callback(
const FLAC__StreamDecoder *decoder, FLAC__byte result_buffer[],
size_t *bytes,
void *client_data) {
168 FLAC__StreamDecoderReadStatus result = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
169 LOGD(
"read_callback: %d", (
int) *bytes);
171 if (
self ==
nullptr || !self->is_active) {
172 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
176 *bytes =
self->readBytes(result_buffer, *bytes);
177 LOGD(
"-> %d", (
int) *bytes);
178 if (self->isEof(*bytes)){
179 result = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
180 self->is_active =
false;
193 if (
millis() - time_last_read >= read_timeout_ms){
200 static FLAC__StreamDecoderWriteStatus
write_callback(
const FLAC__StreamDecoder *decoder,
const FLAC__Frame *frame,
const FLAC__int32 *
const buffer[],
void *client_data) {
201 LOGD(
"write_callback: %u", (
unsigned)frame->header.blocksize);
204 AudioInfo actual_info =
self->audioInfo();
205 if (self->info != actual_info){
206 self->info = actual_info;
207 self->info.logInfo();
208 int bps = FLAC__stream_decoder_get_bits_per_sample(decoder);
210 LOGI(
"Converting from %d bits", bps);
212 self->info = actual_info;
213 self->notifyAudioChange(self->info);
217 int bps = FLAC__stream_decoder_get_bits_per_sample(decoder);
218 int16_t result_frame[actual_info.
channels];
222 for (
int j = 0; j < frame->header.blocksize; j++) {
223 for (
int i = 0; i < actual_info.
channels; i++) {
225 result_frame[i] = buffer[i][j]<<8;
227 self->p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
231 for (
int j = 0; j < frame->header.blocksize; j++) {
232 for (
int i = 0; i < actual_info.
channels; i++) {
233 result_frame[i] = buffer[i][j];
235 self->p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
239 for (
int j = 0; j < frame->header.blocksize; j++) {
240 for (
int i = 0; i < actual_info.
channels; i++) {
241 result_frame[i] = buffer[i][j] >> 8;
243 self->p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
247 for (
int j = 0; j < frame->header.blocksize; j++) {
248 for (
int i = 0; i < actual_info.
channels; i++) {
249 result_frame[i] = buffer[i][j] >> 16;
251 self->p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
255 LOGE(
"Unsupported bps: %d", bps);
258 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
280 void setOgg(
bool isOgg) {
284 bool isOgg() {
return is_ogg;}
286 void setBlockSize(
int size){
287 flac_block_size = size;
290 int blockSize() {
return flac_block_size; }
292 void setCompressionLevel(
int level){
293 flac_compression_level = level;
296 int compressionLevel() {
return flac_compression_level;}
302 const char *
mime()
override {
return "audio/flac"; }
313 if (p_encoder==
nullptr){
314 p_encoder = FLAC__stream_encoder_new();
315 if (p_encoder==
nullptr){
316 LOGE(
"FLAC__stream_encoder_new");
323 FLAC__stream_encoder_set_channels(p_encoder, cfg.
channels);
324 FLAC__stream_encoder_set_bits_per_sample(p_encoder, cfg.
bits_per_sample);
325 FLAC__stream_encoder_set_sample_rate(p_encoder, cfg.
sample_rate);
326 FLAC__stream_encoder_set_blocksize(p_encoder, flac_block_size);
327 FLAC__stream_encoder_set_compression_level(p_encoder, flac_compression_level);
330 FLAC__StreamEncoderInitStatus status;
332 status = FLAC__stream_encoder_init_ogg_stream(p_encoder,
nullptr, write_callback,
nullptr,
nullptr,
nullptr,
this);
334 status = FLAC__stream_encoder_init_stream(p_encoder, write_callback,
nullptr,
nullptr,
nullptr,
this);
336 if (status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
337 LOGE(
"ERROR: initializing decoder: %s", FLAC__StreamEncoderInitStatusString[status]);
338 if (status==FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR){
339 LOGE(
" -> %s", FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(p_encoder)]);
356 if (p_encoder !=
nullptr) {
357 FLAC__stream_encoder_delete(p_encoder);
364 virtual size_t write(
const uint8_t *data,
size_t len)
override {
365 if (!is_open || p_print ==
nullptr)
return 0;
366 LOGD(
"write: %zu", len);
370 int32_t *data32=
nullptr;
373 samples = len /
sizeof(int16_t);
375 writeBuffer((int16_t*)data, samples);
376 data32 = buffer.data();
381 samples = len /
sizeof(int32_t);
383 data32 = (int32_t*) data;
392 if (FLAC__stream_encoder_process_interleaved(p_encoder, data32, frames)){
395 LOGE(
"FLAC__stream_encoder_process_interleaved");
402 operator bool()
override {
return is_open; }
404 bool isOpen() {
return is_open; }
408 Vector<FLAC__int32> buffer;
409 Print *p_print =
nullptr;
410 FLAC__StreamEncoder *p_encoder=
nullptr;
411 bool is_open =
false;
413 int flac_block_size = 512;
414 int flac_compression_level = 8;
416 static FLAC__StreamEncoderWriteStatus write_callback(
const FLAC__StreamEncoder *encoder,
const FLAC__byte buffer[],
size_t bytes, uint32_t samples, uint32_t current_frame,
void *client_data){
418 if (self->p_print!=
nullptr){
419 size_t written =
self->p_print->write((uint8_t*)buffer, bytes);
421 LOGE(
"write_callback %zu -> %zu", bytes, written);
422 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
425 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
428 void writeBuffer(int16_t * data,
size_t samples) {
429 buffer.resize(samples);
430 for (
int j=0;j<samples;j++){