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"
5
6namespace audio_tools {
7
17class Fade {
18public:
19 void setFadeInActive(bool flag) {
21 if (is_fade_in) {
22 volume = 0.0;
23 is_fade_out = false;
24 is_done = false;
25 }
26 }
27
28 bool isFadeInActive() { return is_fade_in; }
29
32 if (is_fade_out) {
33 volume = 1.0;
34 is_fade_in = false;
35 is_done = false;
36 }
37 }
38
39 bool isFadeOutActive() { return is_fade_out; }
40
47 void convert(uint8_t *data, int bytes, int channels, int bitsPerSample) {
48 this->channels = channels;
49 int bytes_per_sample = bitsPerSample / 8;
50 switch (bitsPerSample) {
51 case 16:
53 bytes / bytes_per_sample / channels, channels);
54 break;
55 case 24:
57 bytes / bytes_per_sample / channels, channels);
58 break;
59 case 32:
61 bytes / bytes_per_sample / channels, channels);
62 break;
63 default:
64 LOGE("%s", "Unsupported bitsPerSample");
65 break;
66 }
67 }
68
70 bool isFadeComplete() { return is_done; }
71
72protected:
73 bool is_fade_in = false;
74 bool is_fade_out = false;
75 int channels = 2;
76 float volume = 1.0;
77 bool is_done = false;
78
79 template <typename T> void convertFrames(T *data, int frames, int channels) {
80 float delta = 1.0 / frames;
81 // handle fade out
82 if (is_fade_in) {
83 fadeIn<T>(data, frames, channels, delta);
84 is_fade_in = false;
85 } else if (is_fade_out) {
86 fadeOut<T>(data, frames, channels, delta);
87 }
88 if (frames > 0) {
89 is_done = true;
90 }
91 }
92
93 template <typename T>
94 void fadeOut(T *data, int frames, int channels, float delta) {
95 for (int j = 0; j < frames; j++) {
96 for (int ch = 0; ch < channels; ch++) {
97 data[j * channels + ch] = data[j * channels + ch] * volume;
98 if (volume > 0) {
99 volume -= delta;
100 if (volume < 0) {
101 volume = 0;
102 }
103 }
104 }
105 }
106 is_fade_out = false;
107 LOGI("faded out %d frames to volume %f",frames, volume);
108 }
109
110 template <typename T>
111 void fadeIn(T *data, int frames, int channels, float delta) {
112 LOGI("fade in %d frames from volume %f",frames, volume);
113 for (int j = 0; j < frames; j++) {
114 for (int ch = 0; ch < channels; ch++) {
115 data[j * channels + ch] = data[j * channels + ch] * volume;
116 volume += delta;
117 if (volume > 1.0f) {
118 volume = 1.0f;
119 }
120 }
121 }
122 volume = 1.0f;
123 is_fade_in = false;
124 }
125};
126
133template <typename T>
135public:
136 void setChannels(int ch) { channels = ch; last.resize(ch); }
137 size_t write(uint8_t *src, size_t size) {
138 if (channels == 0){
139 LOGE("channels=0");
140 return 0;
141 }
142 int frames = size / sizeof(T) / channels;
143 storeLastSamples(frames, src);
144 return size;
145 };
146
149 void end(Print &print, int steps = 200) {
150 T out[channels];
151 for (int j = 0; j < steps; j++) {
152 for (int ch = 0; ch < channels; ch++) {
153 float factor =
154 static_cast<float>(steps - j) / static_cast<float>(steps);
155 out[ch] = last[ch] * factor;
156 }
157 print.write((uint8_t *)out, channels * sizeof(T));
158 }
159 }
160
161protected:
162 int channels = 0;
164
165 void storeLastSamples(int frames, uint8_t *src) {
166 T *data = (T *)src;
167 for (int ch = 0; ch < channels; ch++) {
168 last[ch] = data[frames - 2 * channels + ch];
169 }
170 }
171};
172
178public:
179 void setChannels(int ch) {
181 f24.setChannels(ch);
183 }
184
185 void setBitsPerSample(int bits){
186 bits_per_sample = bits;
187 }
188
193
194 size_t write(uint8_t *src, size_t size) {
195 switch(bits_per_sample){
196 case 16:
197 return f16.write(src, size);
198 case 24:
199 return f24.write(src, size);
200 case 32:
201 return f32.write(src, size);
202 default:
203 LOGE("bits_per_sample is 0");
204 }
205 return 0;
206 };
207
210 void end(Print &print, int steps = 200) {
211 switch(bits_per_sample){
212 case 16:
213 f16.end(print, steps);
214 break;
215 case 24:
216 f24.end(print, steps);
217 break;
218 case 32:
219 f32.end(print, steps);
220 break;
221 }
222 }
223
224protected:
229};
230
231
242public:
243 FadeStream() = default;
244 FadeStream(Print &out) { setOutput(out); }
246
247 void setStream(Stream &io) override {
248 p_io = &io;
249 p_out = &io;
250 }
251
252 void setOutput(Print &out) override { p_out = &out; }
253
255 void setOutput(Stream &io) {
256 p_io = &io;
257 p_out = &io;
258 }
259
261 void setStream(Print &out) { p_out = &out; }
262
265 return AudioStream::begin();
266 }
267
273
274 size_t readBytes(uint8_t *data, size_t len) override {
275 if (!active) {
276 LOGE("%s", error_msg);
277 return 0;
278 }
280 fade_last.write(data, len);
281 return p_io->readBytes(data, len);
282 }
283
284 int available() override { return p_io == nullptr ? 0 : p_io->available(); }
285
286 size_t write(const uint8_t *data, size_t len) override {
287 if (p_out==nullptr) return 0;
288 if (!active) {
289 LOGE("%s", error_msg);
290 return 0;
291 }
294 }
295 // update last information
296 fade_last.write((uint8_t *)data, len);
297 // write faded data
298 return p_out->write(data, len);
299 }
300
301 int availableForWrite() override {
302 return p_out == nullptr ? 0 : p_out->availableForWrite();
303 }
304
306
307 bool isFadeInActive() { return fade.isFadeInActive(); }
308
310
312
313 bool isFadeComplete() { return fade.isFadeComplete(); }
314
316 void writeEnd(Print &print, int steps = 200) {
317 fade_last.end(print, steps);
318 }
319
320protected:
321 bool active = false;
324 Print *p_out = nullptr;
325 Stream *p_io = nullptr;
326 const char *error_msg = "setAudioInfo not called";
327};
328
334template <typename T> class FadeConverter : public BaseConverter{
335public:
337
338 void setChannels(int ch) { channels = ch; }
339
341
342 bool isFadeInActive() { return fade.isFadeInActive(); }
343
345
347
348 bool isFadeComplete() { return fade.isFadeComplete(); }
349
350 virtual size_t convert(uint8_t *src, size_t size) {
351 int frames = size / sizeof(T) / channels;
352 fade.convertFrames<T>(src, frames, channels);
353 return size;
354 };
355
356protected:
357 int channels = 0;
359};
360
361} // namespace audio_tools
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Definition Arduino.h:56
virtual int availableForWrite()
Definition Arduino.h:128
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
Definition Arduino.h:136
virtual size_t readBytes(uint8_t *data, size_t len)
Definition Arduino.h:140
virtual int available()
Definition Arduino.h:139
AudioInfo info
Definition BaseStream.h:171
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:128
Abstract Base class for Converters A converter is processing the data in the indicated array.
Definition BaseConverter.h:25
virtual bool begin()
Definition BaseStream.h:40
converter which does a fade out or fade in.
Definition Fade.h:334
FadeConverter(int channels)
Definition Fade.h:336
int channels
Definition Fade.h:357
bool isFadeOutActive()
Definition Fade.h:346
Fade fade
Definition Fade.h:358
virtual size_t convert(uint8_t *src, size_t size)
Definition Fade.h:350
void setChannels(int ch)
Definition Fade.h:338
bool isFadeInActive()
Definition Fade.h:342
bool isFadeComplete()
Definition Fade.h:348
void setFadeOutActive(bool flag)
Definition Fade.h:344
void setFadeInActive(bool flag)
Definition Fade.h:340
Fade In and Fade out in order to prevent popping sound when the audio is started or stopped....
Definition Fade.h:17
float volume
Definition Fade.h:76
int channels
Definition Fade.h:75
void fadeOut(T *data, int frames, int channels, float delta)
Definition Fade.h:94
void fadeIn(T *data, int frames, int channels, float delta)
Definition Fade.h:111
bool is_done
Definition Fade.h:77
void convertFrames(T *data, int frames, int channels)
Definition Fade.h:79
bool isFadeOutActive()
Definition Fade.h:39
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:47
bool is_fade_in
Definition Fade.h:73
bool isFadeInActive()
Definition Fade.h:28
bool isFadeComplete()
Returns true if the conversion has been executed with any data.
Definition Fade.h:70
void setFadeOutActive(bool flag)
Definition Fade.h:30
bool is_fade_out
Definition Fade.h:74
void setFadeInActive(bool flag)
Definition Fade.h:19
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:241
bool active
Definition Fade.h:321
void setOutput(Print &out) override
Defines/Changes the output target.
Definition Fade.h:252
bool isFadeOutActive()
Definition Fade.h:311
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:316
size_t readBytes(uint8_t *data, size_t len) override
Definition Fade.h:274
Fade fade
Definition Fade.h:322
int available() override
Definition Fade.h:284
const char * error_msg
Definition Fade.h:326
void setStream(Print &out)
same as setOutput
Definition Fade.h:261
LastSampleFader fade_last
Definition Fade.h:323
size_t write(const uint8_t *data, size_t len) override
Definition Fade.h:286
int availableForWrite() override
Definition Fade.h:301
Print * p_out
Definition Fade.h:324
bool isFadeInActive()
Definition Fade.h:307
bool isFadeComplete()
Definition Fade.h:313
void setAudioInfo(AudioInfo info) override
Defines the input AudioInfo.
Definition Fade.h:268
void setStream(Stream &io) override
Defines/Changes the input & output.
Definition Fade.h:247
void setFadeOutActive(bool flag)
Definition Fade.h:309
FadeStream(Print &out)
Definition Fade.h:244
void setFadeInActive(bool flag)
Definition Fade.h:305
FadeStream(Stream &io)
Definition Fade.h:245
bool begin(AudioInfo info)
Definition Fade.h:263
void setOutput(Stream &io)
same as setStream
Definition Fade.h:255
Stream * p_io
Definition Fade.h:325
If we end audio and the last sample is not close to 0 we can hear a popping noise....
Definition Fade.h:177
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:210
int bits_per_sample
Definition Fade.h:225
LastSampleFaderT< int24_t > f24
Definition Fade.h:227
void setBitsPerSample(int bits)
Definition Fade.h:185
void setAudioInfo(AudioInfo info)
Definition Fade.h:189
size_t write(uint8_t *src, size_t size)
Definition Fade.h:194
LastSampleFaderT< int32_t > f32
Definition Fade.h:228
void setChannels(int ch)
Definition Fade.h:179
LastSampleFaderT< int16_t > f16
Definition Fade.h:226
If we end audio and the last sample is not close to 0 we can hear a popping noise....
Definition Fade.h:134
int channels
Definition Fade.h:162
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:149
void storeLastSamples(int frames, uint8_t *src)
Definition Fade.h:165
size_t write(uint8_t *src, size_t size)
Definition Fade.h:137
void setChannels(int ch)
Definition Fade.h:136
Vector< T > last
Definition Fade.h:163
Abstract class: Objects can be put into a pipleline.
Definition AudioStreams.h:68
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:22
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:508
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
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