LMMS
Loading...
Searching...
No Matches
DspEffectLibrary.h
Go to the documentation of this file.
1/*
2 * DspEffectLibrary.h - library with template-based inline-effects
3 *
4 * Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
5 *
6 * This file is part of LMMS - https://lmms.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
22 *
23 */
24
25#ifndef LMMS_DSPEFFECTLIBRARY_H
26#define LMMS_DSPEFFECTLIBRARY_H
27
28#include <numbers>
29
30#include "lmms_math.h"
31#include "LmmsTypes.h"
32#include "SampleFrame.h"
33
35{
36
37 template<typename T>
39 {
40 public:
41 using bypassType = class MonoBypass;
42
43 static void process( sample_t * * _buf, const f_cnt_t _frames )
44 {
45 for( f_cnt_t f = 0; f < _frames; ++f )
46 {
47 _buf[f][0] = T::nextSample( _buf[f][0] );
48 }
49 }
50 } ;
51
52 template<typename T>
54 {
55 public:
56 using bypassType = class StereoBypass;
57
58 static void process( sample_t * * _buf, const f_cnt_t _frames )
59 {
60 for( f_cnt_t f = 0; f < _frames; ++f )
61 {
62 T::nextSample( _buf[f][0], _buf[f][1] );
63 }
64 }
65 } ;
66
67
68 template<class FXL, class FXR = FXL>
69 class MonoToStereoAdaptor : public StereoBase<MonoToStereoAdaptor<FXL, FXR> >
70 {
71 public:
72 MonoToStereoAdaptor( const FXL& monoFX ) :
73 m_leftFX( monoFX ),
74 m_rightFX( monoFX )
75 {
76 }
77
78 MonoToStereoAdaptor( const FXL& leftFX, const FXR& rightFX ) :
81 {
82 }
83
84 void setGain(float gain)
85 {
86 leftFX().setGain(gain);
87 rightFX().setGain(gain);
88 }
89
91 {
92 nextSample(in.left(), in.right());
93 }
94
95 void nextSample( sample_t& inLeft, sample_t& inRight )
96 {
97 inLeft = m_leftFX.nextSample( inLeft );
98 inRight = m_rightFX.nextSample( inRight );
99 }
100
101 FXL& leftFX()
102 {
103 return( m_leftFX );
104 }
105
106 FXR& rightFX()
107 {
108 return( m_rightFX );
109 }
110
111 private:
114 } ;
115
116
117 template<class FX>
118 class StereoToMonoAdaptor : public MonoBase<StereoToMonoAdaptor<FX> >
119 {
120 public:
121 StereoToMonoAdaptor( const FX& fx ) :
122 m_FX( fx )
123 {
124 }
125
127 {
128 sample_t s[2] = { in, in };
129 m_FX.nextSample( s[0], s[1] );
130
131 return ( s[0] + s[1] ) / 2.0f;
132 }
133
134 private:
136
137 } ;
138
139 class MonoBypass : public MonoBase<MonoBypass>
140 {
141 public:
143 {
144 return in;
145 }
146 } ;
147
148
149 class StereoBypass : public StereoBase<StereoBypass>
150 {
151 public:
153 {
154 }
155 } ;
156
157 /* convenient class to build up static FX chains, for example
158
159 using namespace DspEffectLib;
160 chain<MonoToStereoAdaptor<bassBoost<> >,
161 chain<StereoEnhancer<>,
162 MonoToStereoAdaptor<FoldbackDistortion<> > > >
163 fxchain( bassBoost<>( 60.0, 1.0, 4.0f ),
164 chain<StereoEnhancer<>,
165 MonoToStereoAdaptor<FoldbackDistortion<> > >(
166 StereoEnhancer<>( 1.0 ),
167 FoldbackDistortion<>( 1.0f, 1.0f ) ) );
168
169 // now you can do simple calls such as which will process a bass-boost-,
170 // stereo enhancer- and foldback distortion effect on your buffer
171 fx_chain.process( (sample_t * *) buf, frames );
172*/
173
174 template<class FX0, class FX1 = typename FX0::bypassType>
175 class Chain : public FX0::bypassType
176 {
177 public:
178 using sample_t = typename FX0::sample_t;
179 Chain( const FX0& fx0, const FX1& fx1 = FX1() ) :
180 m_FX0( fx0 ),
181 m_FX1( fx1 )
182 {
183 }
184
185 void process( sample_t** buf, const f_cnt_t frames )
186 {
187 m_FX0.process( buf, frames );
188 m_FX1.process( buf, frames );
189 }
190
191 private:
192 FX0 m_FX0;
193 FX1 m_FX1;
194
195 } ;
196
197
198
199 template<typename sample_t>
201 {
202 return std::min<sample_t>(std::max<sample_t>(-1.0f, x), 1.0f);
203 }
204
205
206 class FastBassBoost : public MonoBase<FastBassBoost>
207 {
208 public:
209 FastBassBoost( const sample_t _frequency,
210 const sample_t _gain,
211 const sample_t _ratio,
212 const FastBassBoost & _orig = FastBassBoost() ) :
213 m_frequency(std::max<sample_t>(_frequency, 10.0)),
214 m_gain1( 1.0 / ( m_frequency + 1.0 ) ),
215 m_gain2( _gain ),
216 m_ratio( _ratio ),
217 m_cap( _orig.m_cap )
218 {
219 }
220
222 {
223 // TODO: somehow remove these horrible aliases...
224 m_cap = ( _in + m_cap*m_frequency ) * m_gain1;
225 return( ( _in + m_cap*m_ratio ) * m_gain2 );
226 }
227
228 void setFrequency( const sample_t _frequency )
229 {
230 m_frequency = _frequency;
231 m_gain1 = 1.0 / ( m_frequency + 1.0 );
232 }
233
234 void setGain( const sample_t _gain )
235 {
236 m_gain2 = _gain;
237 }
238
239 void setRatio( const sample_t _ratio )
240 {
241 m_ratio = _ratio;
242 }
243
244 private:
246 m_cap( 0.0 )
247 {
248 }
249
255 } ;
256
257
258 template<class T>
259 class DistortionBase : public MonoBase<T>
260 {
261 public:
262 DistortionBase( float threshold, float gain ) :
263 m_threshold( threshold ),
264 m_gain( gain )
265 {
266 }
267
268 void setThreshold( float threshold )
269 {
270 m_threshold = threshold;
271 }
272
273 void setGain( float gain )
274 {
275 m_gain = gain;
276 }
277
278 protected:
280 float m_gain;
281 };
282
283
284 class FoldbackDistortion : public DistortionBase<FoldbackDistortion>
285 {
286 public:
288
290 {
291 if( in >= m_threshold || in < -m_threshold )
292 {
293 return (std::abs(std::abs(std::fmod(in - m_threshold, m_threshold * 4)) - m_threshold * 2) - m_threshold) * m_gain;
294 }
295 return in * m_gain;
296 }
297 } ;
298
299
300 class Distortion : public DistortionBase<Distortion>
301 {
302 public:
304
306 {
307 return m_gain * (in * (std::abs(in) + m_threshold) / (in * in + (m_threshold - 1) * std::abs(in) + 1));
308 }
309 } ;
310
311
312 class StereoEnhancer : public StereoBase<StereoEnhancer>
313 {
314 public:
317 {
318 }
319
321 {
323 }
324
325 float wideCoeff()
326 {
327 return m_wideCoeff;
328 }
329
330 void nextSample( sample_t& inLeft, sample_t& inRight )
331 {
332 constexpr float toRad = std::numbers::pi_v<float> / 180.f;
333 const sample_t tmp = inLeft;
334 inLeft += inRight * std::sin(m_wideCoeff * toRad * .5f);
335 inRight -= tmp * std::sin(m_wideCoeff * toRad * .5f);
336 }
337
338 private:
340
341 } ;
342
343} // namespace lmms::DspEffectLibrary
344
345#endif // LMMS_DSPEFFECTLIBRARY_H
#define saturate(x)
Definition add.c:20
Chain(const FX0 &fx0, const FX1 &fx1=FX1())
Definition DspEffectLibrary.h:179
typename FX0::sample_t sample_t
Definition DspEffectLibrary.h:178
FX1 m_FX1
Definition DspEffectLibrary.h:193
FX0 m_FX0
Definition DspEffectLibrary.h:192
void process(sample_t **buf, const f_cnt_t frames)
Definition DspEffectLibrary.h:185
float m_threshold
Definition DspEffectLibrary.h:279
void setThreshold(float threshold)
Definition DspEffectLibrary.h:268
float m_gain
Definition DspEffectLibrary.h:280
void setGain(float gain)
Definition DspEffectLibrary.h:273
DistortionBase(float threshold, float gain)
Definition DspEffectLibrary.h:262
Definition DspEffectLibrary.h:301
sample_t nextSample(sample_t in)
Definition DspEffectLibrary.h:305
void setFrequency(const sample_t _frequency)
Definition DspEffectLibrary.h:228
void setRatio(const sample_t _ratio)
Definition DspEffectLibrary.h:239
sample_t m_gain1
Definition DspEffectLibrary.h:251
sample_t m_frequency
Definition DspEffectLibrary.h:250
sample_t nextSample(sample_t _in)
Definition DspEffectLibrary.h:221
FastBassBoost()
Definition DspEffectLibrary.h:245
void setGain(const sample_t _gain)
Definition DspEffectLibrary.h:234
FastBassBoost(const sample_t _frequency, const sample_t _gain, const sample_t _ratio, const FastBassBoost &_orig=FastBassBoost())
Definition DspEffectLibrary.h:209
sample_t m_ratio
Definition DspEffectLibrary.h:253
sample_t m_gain2
Definition DspEffectLibrary.h:252
sample_t m_cap
Definition DspEffectLibrary.h:254
Definition DspEffectLibrary.h:285
sample_t nextSample(sample_t in)
Definition DspEffectLibrary.h:289
Definition DspEffectLibrary.h:39
class MonoBypass bypassType
Definition DspEffectLibrary.h:41
static void process(sample_t **_buf, const f_cnt_t _frames)
Definition DspEffectLibrary.h:43
Definition DspEffectLibrary.h:140
sample_t nextSample(sample_t in)
Definition DspEffectLibrary.h:142
void nextSample(SampleFrame &in)
Definition DspEffectLibrary.h:90
MonoToStereoAdaptor(const FXL &leftFX, const FXR &rightFX)
Definition DspEffectLibrary.h:78
FXR & rightFX()
Definition DspEffectLibrary.h:106
MonoToStereoAdaptor(const FXL &monoFX)
Definition DspEffectLibrary.h:72
FXL & leftFX()
Definition DspEffectLibrary.h:101
void nextSample(sample_t &inLeft, sample_t &inRight)
Definition DspEffectLibrary.h:95
FXL m_leftFX
Definition DspEffectLibrary.h:112
FXR m_rightFX
Definition DspEffectLibrary.h:113
void setGain(float gain)
Definition DspEffectLibrary.h:84
Definition DspEffectLibrary.h:54
static void process(sample_t **_buf, const f_cnt_t _frames)
Definition DspEffectLibrary.h:58
class StereoBypass bypassType
Definition DspEffectLibrary.h:56
Definition DspEffectLibrary.h:150
void nextSample(sample_t &, sample_t &)
Definition DspEffectLibrary.h:152
StereoEnhancer(float wideCoeff)
Definition DspEffectLibrary.h:315
float m_wideCoeff
Definition DspEffectLibrary.h:339
float wideCoeff()
Definition DspEffectLibrary.h:325
void setWideCoeff(float wideCoeff)
Definition DspEffectLibrary.h:320
void nextSample(sample_t &inLeft, sample_t &inRight)
Definition DspEffectLibrary.h:330
FX m_FX
Definition DspEffectLibrary.h:135
sample_t nextSample(sample_t in)
Definition DspEffectLibrary.h:126
StereoToMonoAdaptor(const FX &fx)
Definition DspEffectLibrary.h:121
Definition SampleFrame.h:41
unsigned s
Definition inflate.c:1555
unsigned x[BMAX+1]
Definition inflate.c:1586
unsigned f
Definition inflate.c:1572
float in
Definition lilv_test.c:1460
Definition DspEffectLibrary.h:35
float sample_t
Definition LmmsTypes.h:39
std::uint64_t f_cnt_t
Definition LmmsTypes.h:43
Definition juce_Uuid.h:141
#define max(x, y)
Definition os.h:78