-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathEffect.h
More file actions
222 lines (170 loc) · 4.74 KB
/
Effect.h
File metadata and controls
222 lines (170 loc) · 4.74 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*
* Effect.h - base class for effects
*
* Copyright (c) 2006-2007 Danny McRae <khjklujn/at/users.sourceforge.net>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef LMMS_EFFECT_H
#define LMMS_EFFECT_H
#include <span>
#include "AudioEngine.h"
#include "AutomatableModel.h"
#include "Engine.h"
#include "Plugin.h"
#include "TempoSyncKnobModel.h"
namespace lmms
{
class AudioBuffer;
class EffectChain;
class EffectControls;
namespace gui
{
class EffectView;
} // namespace gui
class LMMS_EXPORT Effect : public Plugin
{
Q_OBJECT
public:
Effect(const Plugin::Descriptor* _desc,
Model* _parent,
const Descriptor::SubPluginFeatures::Key* _key);
void saveSettings(QDomDocument& _doc, QDomElement& _parent) override;
void loadSettings(const QDomElement& _this) override;
inline QString nodeName() const override
{
return "effect";
}
//! Returns true if audio was processed and should continue being processed
bool processAudioBuffer(AudioBuffer& inOut);
inline bool isOkay() const
{
return m_okay;
}
inline void setOkay( bool _state )
{
m_okay = _state;
}
//! "Awake" means the effect has not been put to sleep by auto-quit
bool isAwake() const
{
return m_awake;
}
inline bool isEnabled() const
{
return m_enabledModel.value();
}
inline f_cnt_t timeout() const
{
const float samples = Engine::audioEngine()->outputSampleRate() * m_autoQuitModel.value() / 1000.0f;
return 1 + ( static_cast<int>( samples ) / Engine::audioEngine()->framesPerPeriod() );
}
inline float wetLevel() const
{
return m_wetDryModel.value();
}
inline float dryLevel() const
{
return 1.0f - m_wetDryModel.value();
}
inline bool dontRun() const
{
return m_noRun;
}
inline void setDontRun( bool _state )
{
m_noRun = _state;
}
bool isProcessingAudio() const
{
return isEnabled() && isAwake() && isOkay() && !dontRun();
}
inline TempoSyncKnobModel* autoQuitModel()
{
return &m_autoQuitModel;
}
bool autoQuitEnabled() const
{
return m_autoQuitEnabled;
}
EffectChain* effectChain() const
{
return m_parent;
}
virtual EffectControls* controls() = 0;
static Effect* instantiate(const QString & _plugin_name,
Model* _parent,
Descriptor::SubPluginFeatures::Key* _key);
static Effect* createFromPreset(const QString& filePath, Model* parent);
protected:
enum class ProcessStatus
{
//! Unconditionally continue processing
Continue,
//! Calculate the RMS out sum and call `checkGate` to determine whether to stop processing
ContinueIfNotQuiet,
//! Do not continue processing
Sleep
};
/**
* The main audio processing method that runs when plugin is awake and running
*/
virtual ProcessStatus processImpl(SampleFrame* buf, const fpp_t frames) = 0;
/**
* Optional method that runs instead of `processImpl` when an effect
* is awake but not running.
*/
virtual void processBypassedImpl() {}
gui::PluginView* instantiateView(QWidget*) override;
void goToSleep()
{
m_quietBufferCount = 0;
m_awake = false;
}
void wakeUp()
{
m_quietBufferCount = 0;
m_awake = true;
}
virtual void onEnabledChanged() {}
private:
/**
* If auto-quit is enabled ("Keep effects running even without input" setting is disabled),
* after "decay" ms of the output buffer remaining below the silence threshold, the effect is
* turned off and won't be processed again until it receives new audio input.
*/
void handleAutoQuit(bool silentOutput);
EffectChain* m_parent;
bool m_okay;
bool m_noRun;
bool m_awake;
//! The number of consecutive periods where output buffers remain below the silence threshold
f_cnt_t m_quietBufferCount = 0;
BoolModel m_enabledModel;
FloatModel m_wetDryModel;
TempoSyncKnobModel m_autoQuitModel;
bool m_autoQuitEnabled = false;
friend class gui::EffectView;
friend class EffectChain;
} ;
using EffectKey = Effect::Descriptor::SubPluginFeatures::Key;
using EffectKeyList = Effect::Descriptor::SubPluginFeatures::KeyList;
} // namespace lmms
#endif // LMMS_EFFECT_H