forked from jniemann66/ReSampler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fadeeffect.h
131 lines (107 loc) · 2.92 KB
/
fadeeffect.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Copyright (C) 2020 Judd Niemann - All Rights Reserved.
* You may use, distribute and modify this code under the
* terms of the GNU Lesser General Public License, version 2.1
*
* You should have received a copy of GNU Lesser General Public License v2.1
* with this file. If not, please refer to: https://github.com/jniemann66/ReSampler
*/
// fadeeffect.h : defines FadeEffect Class
// provides a basic fade-in at the start of the audio, or fade-out at the end of the audio
#ifndef FADEEFFECT_H
#define FADEEFFECT_H
#include "effect.h"
#include <cmath>
namespace ReSampler {
enum FadeType {
FadeTypeNone = 0,
FadeTypeFadeIn = 1,
FadeTypeFadeOut = 2
};
template <typename FloatType>
class FadeEffect : public Effect<FloatType>
{
public:
virtual const FloatType* process(const FloatType* inputBuffer, int sampleCount)
{
FloatType* p = Effect<FloatType>::outputBuffer.get();
if(fadeType == FadeTypeNone) {
// bypass
return inputBuffer;
}
for(int i = 0; i < sampleCount; i += Effect<FloatType>::channelCount) {
for(int ch = 0; ch < Effect<FloatType>::channelCount; ch++) {
p[i + ch] = inputBuffer[i + ch] * gain;
}
if(fadeType & FadeTypeFadeIn) {
if(gain < 1.0) {
gain *= gainIncreaseRate;
if(gain >= 1.0) {
gain = 1.0;
fadeType ^= FadeTypeFadeIn; // fade-in completed; switch it off
}
}
}
if(fadeType & FadeTypeFadeOut) {
if(position >= fadeOutStartPosition) {
gain *= gainDecreaseRate;
}
}
position++;
}
return p;
}
int getFadeType() const
{
return fadeType;
}
int64_t getTotalFrames() const
{
return totalFrames;
}
double getQuietDb() const
{
return quietDb;
}
void setFadeType(int value)
{
fadeType = value;
}
void setFadeIn(double seconds)
{
fadeInStopPosition = std::min(std::max((int64_t)0, static_cast<int64_t>(seconds * Effect<FloatType>::sampleRate)), totalFrames - 1); // 0 <= fadeInStopPosition < totalFrames
if(fadeInStopPosition > 0) {
gain = pow(10, quietDb / 20.0);
gainIncreaseRate = pow(10, -quietDb / fadeInStopPosition / 20);
fadeType |= FadeTypeFadeIn;
}
}
void setFadeOut(double seconds)
{
fadeOutStartPosition = std::max(fadeInStopPosition, static_cast<int64_t>(totalFrames - 1 - seconds * Effect<FloatType>::sampleRate));
if(fadeOutStartPosition < totalFrames - 1) {
gainDecreaseRate = pow(10, quietDb / (totalFrames - fadeOutStartPosition) / 20);
fadeType |= FadeTypeFadeOut;
}
}
void setTotalFrames(const int64_t &value)
{
totalFrames = value;
}
void setQuietDb(double value)
{
quietDb = value;
}
private:
FloatType gain{1.0};
FloatType gainIncreaseRate{1.0};
FloatType gainDecreaseRate{1.0};
double quietDb{-80.0};
int fadeType{0};
int64_t position{0};
int64_t totalFrames{0};
int64_t fadeInStopPosition{0};
int64_t fadeOutStartPosition{0};
};
}
#endif // FADEEFFECT_H