arduino-audio-tools
Loading...
Searching...
No Matches
Fade.h
Go to the documentation of this file.
1#pragma once
2#include "AudioToolsConfig.h"
3#include "AudioStreams.h"
4
5namespace audio_tools {
6
16class Fade {
17public:
18 void setFadeInActive(bool flag) {
20 if (is_fade_in) {
21 volume = 0.0;
22 is_fade_out = false;
23 is_done = false;
24 }
25 }
26
27 bool isFadeInActive() { return is_fade_in; }
28
31 if (is_fade_out) {
32 volume = 1.0;
33 is_fade_in = false;
34 is_done = false;
35 }
36 }
37
38 bool isFadeOutActive() { return is_fade_out; }
39
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) {
50 case 16:
52 bytes / bytes_per_sample / channels, channels);
53 break;
54 case 24:
56 bytes / bytes_per_sample / channels, channels);
57 break;
58 case 32:
60 bytes / bytes_per_sample / channels, channels);
61 break;
62 default:
63 LOGE("%s", "Unsupported bitsPerSample");
64 break;
65 }
66 }
67
69 bool isFadeComplete() { return is_done; }
70
71protected:
72 bool is_fade_in = false;
73 bool is_fade_out = false;
74 int channels = 2;
75 float volume = 1.0;
76 bool is_done = false;
77
78 template <typename T> void convertFrames(T *data, int frames, int channels) {
79 float delta = 1.0 / frames;
80 // handle fade out
81 if (is_fade_in) {
82 fadeIn<T>(data, frames, channels, delta);
83 is_fade_in = false;
84 } else if (is_fade_out) {
85 fadeOut<T>(data, frames, channels, delta);
86 }
87 if (frames > 0) {
88 is_done = true;
89 }
90 }
91
92 template <typename T>
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;
97 if (volume > 0) {
98 volume -= delta;
99 if (volume < 0) {
100 volume = 0;
101 }
102 }
103 }
104 }
105 is_fade_out = false;
106 LOGI("faded out %d frames to volume %f",frames, volume);
107 }
108
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;
115 volume += delta;
116 if (volume > 1.0f) {
117 volume = 1.0f;
118 }
119 }
120 }
121 volume = 1.0f;
122 is_fade_in = false;
123 }
124};
125
132template <typename T>
134public:
135 void setChannels(int ch) { channels = ch; last.resize(ch); }
136 size_t write(uint8_t *src, size_t size) {
137 if (channels == 0){
138 LOGE("channels=0");
139 return 0;
140 }
141 int frames = size / sizeof(T) / channels;
142 storeLastSamples(frames, src);
143 return size;
144 };
145
148 void end(Print &print, int steps = 200) {
149 T out[channels];
150 for (int j = 0; j < steps; j++) {
151 for (int ch = 0; ch < channels; ch++) {
152 float factor =
153 static_cast<float>(steps - j) / static_cast<float>(steps);
154 out[ch] = last[ch] * factor;
155 }
156 print.write((uint8_t *)out, channels * sizeof(T));
157 }
158 }
159
160protected:
161 int channels = 0;
163
164 void storeLastSamples(int frames, uint8_t *src) {
165 T *data = (T *)src;
166 for (int ch = 0; ch < channels; ch++) {
167 last[ch] = data[frames - 2 * channels + ch];
168 }
169 }
170};
171
177public:
178 void setChannels(int ch) {
180 f24.setChannels(ch);
182 }
183
184 void setBitsPerSample(int bits){
185 bits_per_sample = bits;
186 }
187
192
193 size_t write(uint8_t *src, size_t size) {
194 switch(bits_per_sample){
195 case 16:
196 return f16.write(src, size);
197 case 24:
198 return f24.write(src, size);
199 case 32:
200 return f32.write(src, size);
201 default:
202 LOGE("bits_per_sample is 0");
203 }
204 return 0;
205 };
206
209 void end(Print &print, int steps = 200) {
210 switch(bits_per_sample){
211 case 16:
212 f16.end(print, steps);
213 break;
214 case 24:
215 f24.end(print, steps);
216 break;
217 case 32:
218 f32.end(print, steps);
219 break;
220 }
221 }
222
223protected:
228};
229
230
241public:
242 FadeStream() = default;
243 FadeStream(Print &out) { setOutput(out); }
245
246 void setStream(Stream &io) override {
247 p_io = &io;
248 p_out = &io;
249 }
250
251 void setOutput(Print &out) override { p_out = &out; }
252
254 void setOutput(Stream &io) {
255 p_io = &io;
256 p_out = &io;
257 }
258
260 void setStream(Print &out) { p_out = &out; }
261
264 return AudioStream::begin();
265 }
266
272
273 size_t readBytes(uint8_t *data, size_t len) override {
274 if (!active) {
275 LOGE("%s", error_msg);
276 return 0;
277 }
279 fade_last.write(data, len);
280 return p_io->readBytes(data, len);
281 }
282
283 int available() override { return p_io == nullptr ? 0 : p_io->available(); }
284
285 size_t write(const uint8_t *data, size_t len) override {
286 if (p_out==nullptr) return 0;
287 if (!active) {
288 LOGE("%s", error_msg);
289 return 0;
290 }
293 }
294 // update last information
295 fade_last.write((uint8_t *)data, len);
296 // write faded data
297 return p_out->write(data, len);
298 }
299
300 int availableForWrite() override {
301 return p_out == nullptr ? 0 : p_out->availableForWrite();
302 }
303
305
306 bool isFadeInActive() { return fade.isFadeInActive(); }
307
309
311
312 bool isFadeComplete() { return fade.isFadeComplete(); }
313
315 void writeEnd(Print &print, int steps = 200) {
316 fade_last.end(print, steps);
317 }
318
319protected:
320 bool active = false;
323 Print *p_out = nullptr;
324 Stream *p_io = nullptr;
325 const char *error_msg = "setAudioInfo not called";
326};
327
333template <typename T> class FadeConverter : public BaseConverter{
334public:
336
337 void setChannels(int ch) { channels = ch; }
338
340
341 bool isFadeInActive() { return fade.isFadeInActive(); }
342
344
346
347 bool isFadeComplete() { return fade.isFadeComplete(); }
348
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);
352 return size;
353 };
354
355protected:
356 int channels = 0;
358};
359
360} // namespace audio_tools
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
AudioInfo info
Definition BaseStream.h:174
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:131
Abstract Base class for Converters A converter is processing the data in the indicated array.
Definition BaseConverter.h:24
virtual bool begin()
Definition BaseStream.h:43
converter which does a fade out or fade in.
Definition Fade.h:333
FadeConverter(int channels)
Definition Fade.h:335
int channels
Definition Fade.h:356
bool isFadeOutActive()
Definition Fade.h:345
Fade fade
Definition Fade.h:357
virtual size_t convert(uint8_t *src, size_t size)
Definition Fade.h:349
void setChannels(int ch)
Definition Fade.h:337
bool isFadeInActive()
Definition Fade.h:341
bool isFadeComplete()
Definition Fade.h:347
void setFadeOutActive(bool flag)
Definition Fade.h:343
void setFadeInActive(bool flag)
Definition Fade.h:339
Fade In and Fade out in order to prevent popping sound when the audio is started or stopped....
Definition Fade.h:16
float volume
Definition Fade.h:75
int channels
Definition Fade.h:74
void fadeOut(T *data, int frames, int channels, float delta)
Definition Fade.h:93
void fadeIn(T *data, int frames, int channels, float delta)
Definition Fade.h:110
bool is_done
Definition Fade.h:76
void convertFrames(T *data, int frames, int channels)
Definition Fade.h:78
bool isFadeOutActive()
Definition Fade.h:38
void convert(uint8_t *data, int bytes, int channels, int bitsPerSample)
Updates the amplitude of the data when a fade in or fade out has been requested.
Definition Fade.h:46
bool is_fade_in
Definition Fade.h:72
bool isFadeInActive()
Definition Fade.h:27
bool isFadeComplete()
Returns true if the conversion has been executed with any data.
Definition Fade.h:69
void setFadeOutActive(bool flag)
Definition Fade.h:29
bool is_fade_out
Definition Fade.h:73
void setFadeInActive(bool flag)
Definition Fade.h:18
Stream which can be used to manage fade in and fade out. Before you read or write data you need to ca...
Definition Fade.h:240
bool active
Definition Fade.h:320
void setOutput(Print &out) override
Defines/Changes the output target.
Definition Fade.h:251
bool isFadeOutActive()
Definition Fade.h:310
void writeEnd(Print &print, int steps=200)
If you can not provide any more samples we bring the last sample slowy back to 0.
Definition Fade.h:315
size_t readBytes(uint8_t *data, size_t len) override
Definition Fade.h:273
Fade fade
Definition Fade.h:321
int available() override
Definition Fade.h:283
const char * error_msg
Definition Fade.h:325
void setStream(Print &out)
same as setOutput
Definition Fade.h:260
LastSampleFader fade_last
Definition Fade.h:322
size_t write(const uint8_t *data, size_t len) override
Definition Fade.h:285
int availableForWrite() override
Definition Fade.h:300
Print * p_out
Definition Fade.h:323
bool isFadeInActive()
Definition Fade.h:306
bool isFadeComplete()
Definition Fade.h:312
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition Fade.h:267
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition Fade.h:246
void setFadeOutActive(bool flag)
Definition Fade.h:308
FadeStream(Print &out)
Definition Fade.h:243
void setFadeInActive(bool flag)
Definition Fade.h:304
FadeStream(Stream &io)
Definition Fade.h:244
bool begin(AudioInfo info)
Definition Fade.h:262
void setOutput(Stream &io)
same as setStream
Definition Fade.h:254
Stream * p_io
Definition Fade.h:324
If we end audio and the last sample is not close to 0 we can hear a popping noise....
Definition Fade.h:176
void end(Print &print, int steps=200)
When we do not have any data any more to fade out we try to bring the last sample slowly to 0.
Definition Fade.h:209
int bits_per_sample
Definition Fade.h:224
LastSampleFaderT< int24_t > f24
Definition Fade.h:226
void setBitsPerSample(int bits)
Definition Fade.h:184
void setAudioInfo(AudioInfo info)
Definition Fade.h:188
size_t write(uint8_t *src, size_t size)
Definition Fade.h:193
LastSampleFaderT< int32_t > f32
Definition Fade.h:227
void setChannels(int ch)
Definition Fade.h:178
LastSampleFaderT< int16_t > f16
Definition Fade.h:225
If we end audio and the last sample is not close to 0 we can hear a popping noise....
Definition Fade.h:133
int channels
Definition Fade.h:161
void end(Print &print, int steps=200)
When we do not have any data any more to fade out we try to bring the last sample slowly to 0.
Definition Fade.h:148
void storeLastSamples(int frames, uint8_t *src)
Definition Fade.h:164
size_t write(uint8_t *src, size_t size)
Definition Fade.h:136
void setChannels(int ch)
Definition Fade.h:135
Vector< T > last
Definition Fade.h:162
Abstract class: Objects can be put into a pipleline.
Definition AudioStreams.h:68
Definition NoArduino.h:62
virtual int availableForWrite()
Definition NoArduino.h:134
virtual size_t write(const uint8_t *data, size_t len)
Definition NoArduino.h:126
Definition NoArduino.h:142
virtual size_t readBytes(uint8_t *data, size_t len)
Definition NoArduino.h:147
virtual int available()
Definition NoArduino.h:146
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
24bit integer which is used for I2S sound processing. The values are represented as int32_t,...
Definition Int24_4bytes_t.h:16
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61