27 bool convertTo16Bits =
true,
bool releaseOnEnd =
false) {
28 is_convert_to_16 = convertTo16Bits;
29 max_block_size = maxBlockSize;
30 max_channels = maxChannels;
31 is_release_memory_on_end = releaseOnEnd;
40 size_t foxen_size = fx_flac_size(max_block_size, max_channels);
41 foxen_data.resize(foxen_size);
42 flac = fx_flac_init(foxen_data.data(), max_block_size, max_channels);
44 if (flac !=
nullptr) {
46 write_buffer.
resize(in_buffer_size);
47 out.resize(out_buffer_size);
49 LOGE(
"not enough memory");
50 if (is_stop_on_error)
stop();
59 if (flac !=
nullptr && is_release_memory_on_end) {
67 size_t write(
const uint8_t *data,
size_t len)
override {
68 LOGD(
"write: %d", len);
70 if (!is_active)
return 0;
72 size_t result = write_buffer.
writeArray(data, len);
73 LOGD(
"write_buffer availabe: %d", write_buffer.
available());
80 if (write_buffer.
available() == write_buffer.size()) {
81 LOGE(
"Decoder did not consume any data");
82 if (is_stop_on_error)
stop();
85 LOGD(
"write: %d -> %d", len, result);
89 void flush() { decode(); }
91 operator bool()
override {
return is_active; }
107 void set32Bit(
bool flag) { is_convert_to_16 = !flag; }
110 fx_flac_t *flac =
nullptr;
113 Vector<uint8_t> foxen_data{0};
114 bool is_active =
false;
115 bool is_convert_to_16 =
true;
116 bool is_stop_on_error =
true;
117 bool is_release_memory_on_end =
false;
119 int max_block_size = 5 * 1024;
120 int max_channels = 2;
121 int in_buffer_size = FOXEN_IN_BUFFER_SIZE;
122 int out_buffer_size = FOXEN_OUT_BUFFER_SIZE;
126 if (!is_active)
return false;
127 uint32_t out_len = out.size();
128 uint32_t buf_len = write_buffer.
available();
129 uint32_t buf_len_result = buf_len;
130 int rc = fx_flac_process(flac, write_buffer.
data(), &buf_len_result,
131 out.data(), &out_len);
135 case FLAC_END_OF_METADATA: {
140 LOGE(
"FLAC decoder in error state!");
141 if (is_stop_on_error)
stop();
146 LOGD(
"Providing data: %d samples", out_len);
147 if (is_convert_to_16) {
148 write16BitData(out_len);
150 write32BitData(out_len);
155 LOGD(
"processed: %d bytes of %d -> %d samples", buf_len_result, buf_len,
159 return buf_len_result > 0 || out_len > 0;
162 void write32BitData(
int out_len) {
165 writeBlocking(p_print, (uint8_t *)out.data(), out_len *
sizeof(int32_t));
168 void write16BitData(
int out_len) {
171 int16_t *out16 = (int16_t *)out.data();
172 for (
int j = 0; j < out_len; j++) {
173 out16[j] = out.data()[j] >> 16;
176 LOGI(
"writeBlocking: %d", out_len *
sizeof(int16_t));
177 writeBlocking(p_print, (uint8_t *)out.data(), out_len *
sizeof(int16_t));
180 void processMetadata() {
181 bits_eff = fx_flac_get_streaminfo(flac, FLAC_KEY_SAMPLE_SIZE);
182 int info_blocksize = fx_flac_get_streaminfo(flac, FLAC_KEY_MAX_BLOCK_SIZE);
184 LOGI(
"bits: %d", bits_eff);
185 LOGI(
"blocksize: %d", info_blocksize);
187 info.
sample_rate = fx_flac_get_streaminfo(flac, FLAC_KEY_SAMPLE_RATE);
188 info.
channels = fx_flac_get_streaminfo(flac, FLAC_KEY_N_CHANNELS);
192 LOGE(
"max channels too low: %d -> %d", max_channels, info.
channels);
193 if (is_stop_on_error)
stop();
195 if (info_blocksize > max_block_size) {
196 LOGE(
"max channels too low: %d -> %d", max_block_size, info_blocksize);
197 if (is_stop_on_error)
stop();
199 notifyAudioChange(info);