/[svn]/linuxsampler/trunk/src/engines/common/LFOSineNumericComplexNr.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/common/LFOSineNumericComplexNr.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3625 - (show annotations) (download) (as text)
Thu Oct 3 13:37:25 2019 UTC (4 years, 6 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 7066 byte(s)
* gig format extension: Added support for different LFO wave forms
  (currently either sine [default], triangle, saw or square).

* gig format extension: Added support for LFO phase displacement
  (0°..360°).

* gig format extension: Added support for flipping LFO polarity on LFO 3
  (in the original gig format this was only available for LFO 1 and LFO 2).

* Bumped version (2.1.1.svn22).

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 #ifndef LS_LFOSINE_NUMERIC_COMPLEX_NR_H
11 #define LS_LFOSINE_NUMERIC_COMPLEX_NR_H
12
13 #include "LFOBase.h"
14
15 namespace LinuxSampler {
16
17 /** @brief Sine LFO (numeric, complex nr implementation)
18 *
19 * This is a Sinus Low Frequency Oscillator implementation using a complex
20 * number with numeric (descrete) math as basis for its oscillation.
21 */
22 template<LFO::range_type_t RANGE>
23 class LFOSineNumericComplexNr : public LFOBase<RANGE> {
24 public:
25
26 /**
27 * Constructor
28 *
29 * @param Max - maximum value of the output levels
30 */
31 LFOSineNumericComplexNr(float Max) : LFOBase<RANGE>::LFOBase(Max) {
32 //NOTE: DO NOT add any custom initialization here, since it would break LFOCluster construction !
33 }
34
35 /**
36 * Calculates exactly one sample point of the LFO wave.
37 *
38 * @returns next LFO level
39 */
40 inline float render() {
41 real -= c * imag;
42 imag += c * real;
43 if (RANGE == LFO::range_unsigned)
44 return real * normalizer + offset;
45 else /* signed range */
46 return real * normalizer;
47 }
48
49 /**
50 * Update LFO depth with a new external controller value.
51 *
52 * @param ExtControlValue - new external controller value
53 */
54 inline void updateByMIDICtrlValue(const uint16_t& ExtControlValue) {
55 this->ExtControlValue = ExtControlValue;
56
57 const float max = (this->InternalDepth + ExtControlValue * this->ExtControlDepthCoeff) * this->ScriptDepthFactor;
58 if (RANGE == LFO::range_unsigned) {
59 normalizer = max * 0.5f;
60 offset = normalizer;
61 } else { // signed range
62 normalizer = max;
63 }
64 }
65
66 /**
67 * Will be called by the voice when the key / voice was triggered.
68 *
69 * @param Frequency - frequency of the oscillator in Hz
70 * @param StartLevel - on which level the wave should start
71 * @param InternalDepth - firm, internal oscillator amplitude
72 * @param ExtControlDepth - defines how strong the external MIDI
73 * controller has influence on the
74 * oscillator amplitude
75 * @param FlipPhase - inverts the oscillator wave against
76 * a horizontal axis
77 * @param SampleRate - current sample rate of the engines
78 * audio output signal
79 */
80 void trigger(float Frequency, LFO::start_level_t StartLevel, uint16_t InternalDepth, uint16_t ExtControlDepth, bool FlipPhase, unsigned int SampleRate) {
81 this->Frequency = Frequency;
82 this->ScriptFrequencyFactor = this->ScriptDepthFactor = 1.f; // reset for new voice
83 this->InternalDepth = (InternalDepth / 1200.0f) * this->Max;
84 this->ExtControlDepthCoeff = (((float) ExtControlDepth / 1200.0f) / 127.0f) * this->Max;
85 this->pFinalDepth = NULL;
86 this->pFinalFrequency = NULL;
87
88 const float freq = Frequency * this->ScriptFrequencyFactor;
89 c = 2.0f * M_PI * freq / (float) SampleRate;
90
91 switch (StartLevel) {
92 case LFO::start_level_mid:
93 this->startPhase = (FlipPhase) ? 0.5 * M_PI : 1.5 * M_PI; // 90� or 270�
94 break;
95 case LFO::start_level_max:
96 this->startPhase = (FlipPhase) ? M_PI : 0.0; // 180� or 0�
97 break;
98 case LFO::start_level_min:
99 this->startPhase = (FlipPhase) ? 0.0 : M_PI; // 0� or 180�
100 break;
101 }
102 real = cos(this->startPhase);
103 imag = sin(this->startPhase);
104 }
105
106 /**
107 * Should be invoked after the LFO is triggered with StartLevel
108 * start_level_min.
109 * @param phase From 0 to 360 degrees.
110 */
111 void setPhase(float phase) {
112 if (phase < 0) phase = 0;
113 if (phase > 360) phase = 360;
114 phase = phase / 360.0f * 2 * M_PI;
115 real = cos(this->startPhase + phase);
116 imag = sin(this->startPhase + phase);
117 }
118
119 void setFrequency(float Frequency, unsigned int SampleRate) {
120 this->Frequency = Frequency;
121 const float freq = Frequency * this->ScriptFrequencyFactor;
122 c = 2.0f * M_PI * freq / (float) SampleRate;
123 }
124
125 void setScriptDepthFactor(float factor, bool isFinal) {
126 this->ScriptDepthFactor = factor;
127 // set or reset this script depth parameter to be the sole
128 // source for the LFO depth
129 if (isFinal && !this->pFinalDepth)
130 this->pFinalDepth = &this->ScriptDepthFactor;
131 else if (!isFinal && this->pFinalDepth == &this->ScriptDepthFactor)
132 this->pFinalDepth = NULL;
133 // recalculate upon new depth
134 updateByMIDICtrlValue(this->ExtControlValue);
135 }
136
137 void setScriptFrequencyFactor(float factor, unsigned int SampleRate) {
138 this->ScriptFrequencyFactor = factor;
139 // in case script frequency was set as "final" value before,
140 // reset it so that all sources are processed from now on
141 if (this->pFinalFrequency == &this->ScriptFrequencyFactor)
142 this->pFinalFrequency = NULL;
143 // recalculate upon new frequency
144 setFrequency(this->Frequency, SampleRate);
145 }
146
147 void setScriptFrequencyFinal(float hz, unsigned int SampleRate) {
148 this->ScriptFrequencyFactor = hz;
149 // assign script's given frequency as sole source for the LFO
150 // frequency, thus ignore all other sources
151 if (!this->pFinalFrequency)
152 this->pFinalFrequency = &this->ScriptFrequencyFactor;
153 // recalculate upon new frequency
154 setFrequency(this->Frequency, SampleRate);
155 }
156
157 private:
158 float c;
159 float real;
160 float imag;
161 float normalizer;
162 float offset;
163 double startPhase;
164 };
165
166 } // namespace LinuxSampler
167
168 #endif // LS_LFOSINE_NUMERIC_COMPLEX_NR_H

  ViewVC Help
Powered by ViewVC