arduino-audio-tools
Loading...
Searching...
No Matches
CodecFLACFoxen.h
Go to the documentation of this file.
1#pragma once
2
5#include "foxen-flac.h"
6
7namespace audio_tools {
8
9#define FOXEN_IN_BUFFER_SIZE 1024 * 2
10#define FOXEN_OUT_BUFFER_SIZE 1024 * 4
11
22 public:
23 FLACDecoderFoxen() = default;
24
26 FLACDecoderFoxen(int maxBlockSize, int maxChannels,
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;
32 };
33
36
37 const char *mime() override { return "audio/flac"; }
38
39 bool begin() {
40 TRACEI();
41 is_active = false;
42 size_t foxen_size = fx_flac_size(max_block_size, max_channels);
43 foxen_data.resize(foxen_size);
45
46 if (flac != nullptr) {
47 is_active = true;
50 } else {
51 LOGE("not enough memory");
53 }
54
55 return is_active;
56 }
57
58 void end() {
59 TRACEI();
60 flush();
61 if (flac != nullptr && is_release_memory_on_end) {
64 out.resize(0);
65 }
66 is_active = false;
67 }
68
69 size_t write(const uint8_t *data, size_t len) override {
70 LOGD("write: %d", len);
71 // no processing if not active
72 if (!is_active) return 0;
73
74 size_t result = write_buffer.writeArray(data, len);
75 LOGD("write_buffer availabe: %d", write_buffer.available());
76
77 while (write_buffer.available() > 0) {
78 if (!decode()) break;
79 }
80
81 // if the buffer is full we could not decode anything
83 LOGE("Decoder did not consume any data");
85 }
86
87 LOGD("write: %d -> %d", len, result);
88 return result;
89 }
90
91 void flush() { decode(); }
92
93 operator bool() override { return is_active; }
94
96 void setInBufferSize(int size) { in_buffer_size = size; }
97
100 void setOutBufferSize(int size) { out_buffer_size = size; }
101
103 void setMaxBlockSize(int size) { max_block_size = size; }
104
106 void setMaxChannels(int ch) { max_channels = ch; }
107
109 void set32Bit(bool flag) { is_convert_to_16 = !flag; }
110
111 protected:
112 fx_flac_t *flac = nullptr;
116 bool is_active = false;
117 bool is_convert_to_16 = true;
118 bool is_stop_on_error = true;
120 int bits_eff = 0;
121 int max_block_size = 5 * 1024;
125
126 bool decode() {
127 TRACED();
128 if (!is_active) return false;
129 uint32_t out_len = out.size();
130 uint32_t buf_len = write_buffer.available();
131 uint32_t buf_len_result = buf_len;
132 int rc = fx_flac_process(flac, write_buffer.data(), &buf_len_result,
133 out.data(), &out_len);
134 // assert(out_len <= FOXEN_OUT_BUFFER_SIZE);
135
136 switch (rc) {
137 case FLAC_END_OF_METADATA: {
139 } break;
140
141 case FLAC_ERR: {
142 LOGE("FLAC decoder in error state!");
143 if (is_stop_on_error) stop();
144 } break;
145
146 default: {
147 if (out_len > 0) {
148 LOGD("Providing data: %d samples", out_len);
149 if (is_convert_to_16) {
150 write16BitData(out_len);
151 } else {
152 write32BitData(out_len);
153 }
154 }
155 } break;
156 }
157 LOGD("processed: %d bytes of %d -> %d samples", buf_len_result, buf_len,
158 out_len);
159 // removed processed bytes from buffer
160 write_buffer.clearArray(buf_len_result);
161 return buf_len_result > 0 || out_len > 0;
162 }
163
164 void write32BitData(int out_len) {
165 TRACED();
166 // write the result to the output destination
167 writeBlocking(p_print, (uint8_t *)out.data(), out_len * sizeof(int32_t));
168 }
169
170 void write16BitData(int out_len) {
171 TRACED();
172 // in place convert to 16 bits
173 int16_t *out16 = (int16_t *)out.data();
174 for (int j = 0; j < out_len; j++) {
175 out16[j] = out.data()[j] >> 16; // 65538;
176 }
177 // write the result to the output destination
178 LOGI("writeBlocking: %d", out_len * sizeof(int16_t));
179 writeBlocking(p_print, (uint8_t *)out.data(), out_len * sizeof(int16_t));
180 }
181
183 bits_eff = fx_flac_get_streaminfo(flac, FLAC_KEY_SAMPLE_SIZE);
184 int info_blocksize = fx_flac_get_streaminfo(flac, FLAC_KEY_MAX_BLOCK_SIZE);
185
186 LOGI("bits: %d", bits_eff);
187 LOGI("blocksize: %d", info_blocksize);
188 // assert(bits_eff == 32);
189 info.sample_rate = fx_flac_get_streaminfo(flac, FLAC_KEY_SAMPLE_RATE);
190 info.channels = fx_flac_get_streaminfo(flac, FLAC_KEY_N_CHANNELS);
192 info.logInfo();
193 if (info.channels > max_channels) {
194 LOGE("max channels too low: %d -> %d", max_channels, info.channels);
195 if (is_stop_on_error) stop();
196 }
197 if (info_blocksize > max_block_size) {
198 LOGE("max channels too low: %d -> %d", max_block_size, info_blocksize);
199 if (is_stop_on_error) stop();
200 }
202 }
203};
204
205} // namespace audio_tools
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define FOXEN_OUT_BUFFER_SIZE
Definition CodecFLACFoxen.h:10
#define FOXEN_IN_BUFFER_SIZE
Definition CodecFLACFoxen.h:9
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:19
AudioInfo info
Definition AudioCodecsBase.h:80
Print * p_print
Definition AudioCodecsBase.h:79
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:175
void writeBlocking(Print *out, uint8_t *data, size_t len)
Definition AudioTypes.h:220
Foxen FLAC Decoder using https://github.com/astoeckel/libfoxenflac Unlike FLACDecoder which is a stre...
Definition CodecFLACFoxen.h:21
SingleBuffer< uint8_t > write_buffer
Definition CodecFLACFoxen.h:113
int max_block_size
Definition CodecFLACFoxen.h:121
bool is_stop_on_error
Definition CodecFLACFoxen.h:118
bool is_release_memory_on_end
Definition CodecFLACFoxen.h:119
bool is_active
Definition CodecFLACFoxen.h:116
FLACDecoderFoxen(int maxBlockSize, int maxChannels, bool convertTo16Bits=true, bool releaseOnEnd=false)
Default Constructor.
Definition CodecFLACFoxen.h:26
void set32Bit(bool flag)
Select between 16 and 32 bit output: the default is 16 bits.
Definition CodecFLACFoxen.h:109
void write16BitData(int out_len)
Definition CodecFLACFoxen.h:170
void setMaxChannels(int ch)
Defines the maximum number of channels: drives the buffer allocation.
Definition CodecFLACFoxen.h:106
Vector< uint8_t > foxen_data
Definition CodecFLACFoxen.h:115
Vector< int32_t > out
Definition CodecFLACFoxen.h:114
bool begin()
Definition CodecFLACFoxen.h:39
void setOutBufferSize(int size)
Definition CodecFLACFoxen.h:100
~FLACDecoderFoxen()
Destructor - calls end();.
Definition CodecFLACFoxen.h:35
void setMaxBlockSize(int size)
Defines the maximum FLAC blocksize: drives the buffer allocation.
Definition CodecFLACFoxen.h:103
bool decode()
Definition CodecFLACFoxen.h:126
size_t write(const uint8_t *data, size_t len) override
Definition CodecFLACFoxen.h:69
int in_buffer_size
Definition CodecFLACFoxen.h:123
void write32BitData(int out_len)
Definition CodecFLACFoxen.h:164
int out_buffer_size
Definition CodecFLACFoxen.h:124
void setInBufferSize(int size)
Defines the input buffer size (default is 2k)
Definition CodecFLACFoxen.h:96
void end()
Definition CodecFLACFoxen.h:58
const char * mime() override
Provides the mime type of the data that is expected by this decoder.
Definition CodecFLACFoxen.h:37
bool is_convert_to_16
Definition CodecFLACFoxen.h:117
void processMetadata()
Definition CodecFLACFoxen.h:182
void flush()
Definition CodecFLACFoxen.h:91
int max_channels
Definition CodecFLACFoxen.h:122
int bits_eff
Definition CodecFLACFoxen.h:120
fx_flac_t * flac
Definition CodecFLACFoxen.h:112
A simple Buffer implementation which just uses a (dynamically sized) array.
Definition Buffers.h:194
size_t size() override
Definition Buffers.h:325
int available() override
provides the number of entries that are available to read
Definition Buffers.h:255
int writeArray(const T data[], int len) override
Fills the buffer data.
Definition Buffers.h:223
T * data()
Provides address of actual data.
Definition Buffers.h:306
bool resize(size_t size)
Resizes the buffer if supported: returns false if not supported.
Definition Buffers.h:327
int clearArray(int len) override
consumes len bytes and moves current data to the beginning
Definition Buffers.h:274
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
void stop()
stops any further processing by spinning in an endless loop
Definition AudioRuntime.h:71
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
virtual void logInfo(const char *source="")
Definition AudioTypes.h:122