/[svn]/linuxsampler/trunk/src/engines/LFO.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/LFO.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3612 - (show annotations) (download)
Mon Sep 30 18:03:43 2019 UTC (4 years, 6 months ago) by schoenebeck
File size: 5757 byte(s)
Added new LFO implementations:

* Added int math square LFO implementation.

* Added int math saw LFO implementation.

* Added numeric complex nr sine LFO implementation.

* Added public API C++ class "LFO", which is a cluster class
  encapsulating all the sampler's LFO implementations to be used by
  3rd party applications (e.g. by Gigedit).

* Marked class LFOTriangleDiHarmonic as deprecated
  (will be removed in future).

* Added LFOAll.h which includes all LFO implementation's header files.

* Fixed benchmarks/triang.cpp falsely having favoured "int math abs"
  algorithm (since result of 2nd run was not accumulated).

* Added benchmark for saw wave (benchmarks/saw.cpp).

* Added benchmark for sine wave (benchmarks/sine.cpp).

* Added benchmark for square wave (benchmarks/square.cpp).

* Increased amount of benchmarks runs by factor 6 to achieve benchmark
  times which are large enough on modern systems.

* Cleanup of LFO APIs.

* Bumped version (2.1.1.svn18).

1 /*
2 * Copyright (c) 2019 Christian Schoenebeck
3 *
4 * http://www.linuxsampler.org
5 *
6 * This file is part of LinuxSampler and released under the same terms.
7 * See README file for details.
8 */
9
10 #include "LFO.h"
11 #include "common/LFOAll.h"
12 #include <type_traits> // for std::is_same
13
14 namespace LinuxSampler {
15
16 enum lfo_class_t {
17 lfo_class_sine_signed,
18 lfo_class_sine_unsigned,
19 lfo_class_triangle_signed,
20 lfo_class_triangle_unsigned,
21 lfo_class_saw_signed,
22 lfo_class_saw_unsigned,
23 lfo_class_square_signed,
24 lfo_class_square_unsigned,
25 };
26
27 struct LFOPriv {
28 LFOPOD* lfo = NULL;
29 lfo_class_t lfoClass = (lfo_class_t) -1; // some invalid value
30
31 virtual ~LFOPriv() {
32 if (lfo) delete lfo;
33 }
34 };
35
36 LFO::LFO() {
37 SELF = new LFOPriv;
38 }
39
40 LFO::~LFO() {
41 if (SELF) delete SELF;
42 }
43
44 template<class T>
45 static T* createLFO(LFOPriv* SELF, const LFO::SetupOpt& opt) {
46 if (SELF->lfo) {
47 delete SELF->lfo;
48 SELF->lfo = NULL;
49 }
50
51 const bool flipPolarity = (opt.flipPolarity) ? *opt.flipPolarity : false;
52 const float maxValue = (opt.maxValue) ? *opt.maxValue : 1.0;
53 const float frequency = (opt.frequency) ? *opt.frequency : 1.0;
54 const LFO::start_level_t startLevel = (opt.startLevel) ? *opt.startLevel : LFO::start_level_mid;
55 const uint16_t internalDepth = (opt.internalDepth) ? *opt.internalDepth : 0;
56 const uint16_t midiCtrlDepth = (opt.midiControllerDepth) ? *opt.midiControllerDepth : 0;
57 const float samplerate = (opt.samplerate) ? *opt.samplerate : 44100;
58
59 T* lfo = new T(maxValue);
60 SELF->lfo = lfo;
61
62 lfo->trigger(frequency, startLevel, internalDepth, midiCtrlDepth, flipPolarity, samplerate);
63 if (opt.phase)
64 lfo->setPhase( *opt.phase );
65 lfo->updateByMIDICtrlValue(0);
66
67 if (std::is_same<T,LFOSineSigned>::value)
68 SELF->lfoClass = lfo_class_sine_signed;
69 else if (std::is_same<T,LFOSineUnsigned>::value)
70 SELF->lfoClass = lfo_class_sine_unsigned;
71 else if (std::is_same<T,LFOSigned>::value)
72 SELF->lfoClass = lfo_class_triangle_signed;
73 else if (std::is_same<T,LFOUnsigned>::value)
74 SELF->lfoClass = lfo_class_triangle_unsigned;
75 else if (std::is_same<T,LFOSawSigned>::value)
76 SELF->lfoClass = lfo_class_saw_signed;
77 else if (std::is_same<T,LFOSawUnsigned>::value)
78 SELF->lfoClass = lfo_class_saw_unsigned;
79 else if (std::is_same<T,LFOSquareSigned>::value)
80 SELF->lfoClass = lfo_class_square_signed;
81 else if (std::is_same<T,LFOSquareUnsigned>::value)
82 SELF->lfoClass = lfo_class_square_unsigned;
83 else
84 assert(false);
85
86 return lfo;
87 }
88
89 void LFO::setup(const SetupOpt& opt) {
90 const wave_t wave = (opt.waveType) ? *opt.waveType : wave_sine;
91 const bool isSigned = (opt.rangeType) ? (*opt.rangeType == range_signed) : false;
92
93 switch (wave) {
94 case wave_sine:
95 if (isSigned)
96 createLFO<LFOSineSigned>(SELF, opt);
97 else
98 createLFO<LFOSineUnsigned>(SELF, opt);
99 break;
100 case wave_triangle:
101 if (isSigned)
102 createLFO<LFOSigned>(SELF, opt);
103 else
104 createLFO<LFOUnsigned>(SELF, opt);
105 break;
106 case wave_saw:
107 if (isSigned)
108 createLFO<LFOSawSigned>(SELF, opt);
109 else
110 createLFO<LFOSawUnsigned>(SELF, opt);
111 break;
112 case wave_square:
113 if (isSigned)
114 createLFO<LFOSquareSigned>(SELF, opt);
115 else
116 createLFO<LFOSquareUnsigned>(SELF, opt);
117 break;
118 default:
119 assert(false);
120 }
121 }
122
123 template<class T>
124 inline float renderLFO(LFOPriv* SELF) {
125 return static_cast<T*>(SELF->lfo)->render();
126 }
127
128 float LFO::render() {
129 switch (SELF->lfoClass) {
130 case lfo_class_sine_signed:
131 return renderLFO<LFOSineSigned>(SELF);
132 case lfo_class_sine_unsigned:
133 return renderLFO<LFOSineUnsigned>(SELF);
134 case lfo_class_triangle_signed:
135 return renderLFO<LFOSigned>(SELF);
136 case lfo_class_triangle_unsigned:
137 return renderLFO<LFOUnsigned>(SELF);
138 case lfo_class_saw_signed:
139 return renderLFO<LFOSawSigned>(SELF);
140 case lfo_class_saw_unsigned:
141 return renderLFO<LFOSawUnsigned>(SELF);
142 case lfo_class_square_signed:
143 return renderLFO<LFOSquareSigned>(SELF);
144 case lfo_class_square_unsigned:
145 return renderLFO<LFOSquareUnsigned>(SELF);
146 }
147 return 0;
148 }
149
150 template<class T>
151 inline void setLFOMidiCtrlValue(LFOPriv* SELF, uint16_t value) {
152 return static_cast<T*>(SELF->lfo)->updateByMIDICtrlValue(value);
153 }
154
155 void LFO::setMIDICtrlValue(uint8_t midiCCValue) {
156 switch (SELF->lfoClass) {
157 case lfo_class_sine_signed:
158 return setLFOMidiCtrlValue<LFOSineSigned>(SELF, midiCCValue);
159 case lfo_class_sine_unsigned:
160 return setLFOMidiCtrlValue<LFOSineUnsigned>(SELF, midiCCValue);
161 case lfo_class_triangle_signed:
162 return setLFOMidiCtrlValue<LFOSigned>(SELF, midiCCValue);
163 case lfo_class_triangle_unsigned:
164 return setLFOMidiCtrlValue<LFOUnsigned>(SELF, midiCCValue);
165 case lfo_class_saw_signed:
166 return setLFOMidiCtrlValue<LFOSawSigned>(SELF, midiCCValue);
167 case lfo_class_saw_unsigned:
168 return setLFOMidiCtrlValue<LFOSawUnsigned>(SELF, midiCCValue);
169 case lfo_class_square_signed:
170 return setLFOMidiCtrlValue<LFOSquareSigned>(SELF, midiCCValue);
171 case lfo_class_square_unsigned:
172 return setLFOMidiCtrlValue<LFOSquareUnsigned>(SELF, midiCCValue);
173 }
174 }
175
176 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC