2 #include "AudioConfig.h"
3 #include "AudioStreams.h"
18 void setFadeInActive(
bool flag) {
27 bool isFadeInActive() {
return is_fade_in; }
29 void setFadeOutActive(
bool flag) {
38 bool isFadeOutActive() {
return is_fade_out; }
46 void convert(uint8_t *data,
int bytes,
int channels,
int bitsPerSample) {
47 this->channels = channels;
48 int bytes_per_sample = bitsPerSample / 8;
49 switch (bitsPerSample) {
51 convertFrames<int16_t>((int16_t *)data,
52 bytes / bytes_per_sample / channels, channels);
55 convertFrames<int24_t>((
int24_t *)data,
56 bytes / bytes_per_sample / channels, channels);
59 convertFrames<int32_t>((int32_t *)data,
60 bytes / bytes_per_sample / channels, channels);
63 LOGE(
"%s",
"Unsupported bitsPerSample");
72 bool is_fade_in =
false;
73 bool is_fade_out =
false;
78 template <
typename T>
void convertFrames(T *data,
int frames,
int channels) {
79 float delta = 1.0 / frames;
82 fadeIn<T>(data, frames, channels, delta);
84 }
else if (is_fade_out) {
85 fadeOut<T>(data, frames, channels, delta);
93 void fadeOut(T *data,
int frames,
int channels,
float delta) {
94 for (
int j = 0; j < frames; j++) {
95 for (
int ch = 0; ch < channels; ch++) {
96 data[j * channels + ch] = data[j * channels + ch] * volume;
106 LOGI(
"faded out %d frames to volume %f",frames, volume);
109 template <
typename T>
110 void fadeIn(T *data,
int frames,
int channels,
float delta) {
111 LOGI(
"fade in %d frames from volume %f",frames, volume);
112 for (
int j = 0; j < frames; j++) {
113 for (
int ch = 0; ch < channels; ch++) {
114 data[j * channels + ch] = data[j * channels + ch] * volume;
132 template <
typename T>
135 void setChannels(
int ch) { channels = ch; last.resize(ch); }
136 size_t write(uint8_t *src,
size_t size) {
141 int frames = size /
sizeof(T) / channels;
142 storeLastSamples(frames, src);
150 for (
int j = 0; j < steps; j++) {
151 for (
int ch = 0; ch < channels; ch++) {
153 static_cast<float>(steps - j) /
static_cast<float>(steps);
154 out[ch] = last[ch] * factor;
156 print.write((uint8_t *)out, channels *
sizeof(T));
164 void storeLastSamples(
int frames, uint8_t *src) {
166 for (
int ch = 0; ch < channels; ch++) {
167 last[ch] = data[frames - 2 * channels + ch];
178 void setChannels(
int ch) {
184 void setBitsPerSample(
int bits){
185 bits_per_sample = bits;
193 size_t write(uint8_t *src,
size_t size) {
194 switch(bits_per_sample){
196 return f16.write(src, size);
198 return f24.write(src, size);
200 return f32.write(src, size);
202 LOGE(
"bits_per_sample is 0");
210 switch(bits_per_sample){
212 f16.
end(print, steps);
215 f24.end(print, steps);
218 f32.
end(print, steps);
224 int bits_per_sample = 0;
264 return AudioStream::begin();
269 fade_last.setAudioInfo(info);
273 size_t readBytes(uint8_t *data,
size_t len)
override {
275 LOGE(
"%s", error_msg);
279 fade_last.write(data, len);
280 return p_io->readBytes(data, len);
283 int available()
override {
return p_io ==
nullptr ? 0 : p_io->available(); }
285 size_t write(
const uint8_t *data,
size_t len)
override {
286 if (p_out==
nullptr)
return 0;
288 LOGE(
"%s", error_msg);
291 if (fade.isFadeInActive() || fade.isFadeOutActive()){
295 fade_last.write((uint8_t *)data, len);
297 return p_out->write(data, len);
300 int availableForWrite()
override {
301 return p_out ==
nullptr ? 0 : p_out->availableForWrite();
304 void setFadeInActive(
bool flag) { fade.setFadeInActive(flag); }
306 bool isFadeInActive() {
return fade.isFadeInActive(); }
308 void setFadeOutActive(
bool flag) { fade.setFadeOutActive(flag); }
310 bool isFadeOutActive() {
return fade.isFadeOutActive(); }
315 void writeEnd(Print &print,
int steps = 200) {
316 fade_last.
end(print, steps);
322 LastSampleFader fade_last;
323 Print *p_out =
nullptr;
324 Stream *p_io =
nullptr;
325 const char *error_msg =
"setAudioInfo not called";
337 void setChannels(
int ch) { channels = ch; }
339 void setFadeInActive(
bool flag) { fade.setFadeInActive(flag); }
341 bool isFadeInActive() {
return fade.isFadeInActive(); }
343 void setFadeOutActive(
bool flag) { fade.setFadeOutActive(flag); }
345 bool isFadeOutActive() {
return fade.isFadeOutActive(); }
349 virtual size_t convert(uint8_t *src,
size_t size) {
350 int frames = size /
sizeof(T) / channels;
351 fade.convertFrames<T>(src, frames, channels);