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");
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 isOgg()
const {
return is_ogg; }
145 const char *
mime()
override {
return is_ogg ?
"audio/ogg; codecs=flac" :
"audio/flac"; }
149 bool is_active =
false;
151 bool is_md5_checing =
false;
153 FLAC__StreamDecoder *decoder =
nullptr;
154 FLAC__StreamDecoderInitStatus init_status;
155 uint64_t time_last_read = 0;
156 uint64_t read_timeout_ms = FLAC_READ_TIMEOUT_MS;
164 FLAC__StreamDecoderErrorStatus status,
166 LOGE(FLAC__StreamDecoderErrorStatusString[status]);
170 return p_input->readBytes(data, len);
174 static FLAC__StreamDecoderReadStatus
read_callback(
const FLAC__StreamDecoder *decoder, FLAC__byte result_buffer[],
size_t *bytes,
void *client_data) {
175 FLAC__StreamDecoderReadStatus result = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
176 LOGD(
"read_callback: %d", (
int) *bytes);
178 if (self ==
nullptr || !self->is_active) {
179 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
183 *bytes = self->
readBytes(result_buffer, *bytes);
184 LOGD(
"-> %d", (
int) *bytes);
185 if (self->
isEof(*bytes)){
186 result = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
187 self->is_active =
false;
200 if (
millis() - time_last_read >= read_timeout_ms){
207 static FLAC__StreamDecoderWriteStatus
write_callback(
const FLAC__StreamDecoder *decoder,
const FLAC__Frame *frame,
const FLAC__int32 *
const buffer[],
void *client_data) {
208 LOGD(
"write_callback: %u", (
unsigned)frame->header.blocksize);
212 if (self->info != actual_info){
213 self->info = actual_info;
214 self->info.logInfo();
215 int bps = FLAC__stream_decoder_get_bits_per_sample(decoder);
217 LOGI(
"Converting from %d bits", bps);
219 self->info = actual_info;
220 self->notifyAudioChange(self->info);
224 int bps = FLAC__stream_decoder_get_bits_per_sample(decoder);
225 int16_t result_frame[actual_info.
channels];
229 for (
int j = 0; j < frame->header.blocksize; j++) {
230 for (
int i = 0; i < actual_info.
channels; i++) {
232 result_frame[i] = buffer[i][j]<<8;
234 self->
p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
238 for (
int j = 0; j < frame->header.blocksize; j++) {
239 for (
int i = 0; i < actual_info.
channels; i++) {
240 result_frame[i] = buffer[i][j];
242 self->
p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
246 for (
int j = 0; j < frame->header.blocksize; j++) {
247 for (
int i = 0; i < actual_info.
channels; i++) {
248 result_frame[i] = buffer[i][j] >> 8;
250 self->
p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
254 for (
int j = 0; j < frame->header.blocksize; j++) {
255 for (
int i = 0; i < actual_info.
channels; i++) {
256 result_frame[i] = buffer[i][j] >> 16;
258 self->
p_print->write((uint8_t *)result_frame,
sizeof(result_frame));
262 LOGE(
"Unsupported bps: %d", bps);
265 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
287 void setOgg(
bool isOgg) {
291 bool isOgg() {
return is_ogg;}
293 void setBlockSize(
int size){
294 flac_block_size = size;
297 int blockSize() {
return flac_block_size; }
299 void setCompressionLevel(
int level){
300 flac_compression_level = level;
303 int compressionLevel() {
return flac_compression_level;}
309 const char *
mime()
override {
return "audio/flac"; }
320 if (p_encoder==
nullptr){
321 p_encoder = FLAC__stream_encoder_new();
322 if (p_encoder==
nullptr){
323 LOGE(
"FLAC__stream_encoder_new");
330 FLAC__stream_encoder_set_channels(p_encoder, cfg.
channels);
331 FLAC__stream_encoder_set_bits_per_sample(p_encoder, cfg.
bits_per_sample);
332 FLAC__stream_encoder_set_sample_rate(p_encoder, cfg.
sample_rate);
333 FLAC__stream_encoder_set_blocksize(p_encoder, flac_block_size);
334 FLAC__stream_encoder_set_compression_level(p_encoder, flac_compression_level);
337 FLAC__StreamEncoderInitStatus status;
339 status = FLAC__stream_encoder_init_ogg_stream(p_encoder,
nullptr, write_callback,
nullptr,
nullptr,
nullptr,
this);
341 status = FLAC__stream_encoder_init_stream(p_encoder, write_callback,
nullptr,
nullptr,
nullptr,
this);
343 if (status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
344 LOGE(
"ERROR: initializing decoder: %s", FLAC__StreamEncoderInitStatusString[status]);
345 if (status==FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR){
346 LOGE(
" -> %s", FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(p_encoder)]);
363 if (p_encoder !=
nullptr) {
364 FLAC__stream_encoder_delete(p_encoder);
371 virtual size_t write(
const uint8_t *data,
size_t len)
override {
372 if (!is_open || p_print ==
nullptr)
return 0;
373 LOGD(
"write: %zu", len);
377 int32_t *data32=
nullptr;
380 samples = len /
sizeof(int16_t);
382 writeBuffer((int16_t*)data, samples);
383 data32 = buffer.data();
388 samples = len /
sizeof(int32_t);
390 data32 = (int32_t*) data;
399 if (FLAC__stream_encoder_process_interleaved(p_encoder, data32, frames)){
402 LOGE(
"FLAC__stream_encoder_process_interleaved");
409 operator bool()
override {
return is_open; }
411 bool isOpen() {
return is_open; }
415 Vector<FLAC__int32> buffer;
416 Print *p_print =
nullptr;
417 FLAC__StreamEncoder *p_encoder=
nullptr;
418 bool is_open =
false;
420 int flac_block_size = 512;
421 int flac_compression_level = 8;
423 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){
425 if (self->p_print!=
nullptr){
426 size_t written = self->p_print->write((uint8_t*)buffer, bytes);
428 LOGE(
"write_callback %zu -> %zu", bytes, written);
429 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
432 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
435 void writeBuffer(int16_t * data,
size_t samples) {
436 buffer.resize(samples);
437 for (
int j=0;j<samples;j++){