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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3561 - (show annotations) (download) (as text)
Fri Aug 23 11:44:00 2019 UTC (4 years, 7 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 8405 byte(s)
NKSP: Added standard units support for numbers and final "!" operator:

* NKSP strictness: Variable names, function names and preprocessor condition
  names must start with a regular character (a-z or A-Z); starting them with
  a digit or underscore is no longer allowed.

* NKSP parser fix: equal comparison operator "=" and not equal comparison
  operator "#" must only accept integer operands.

* NKSP language: Implemented support for standard units like Hertz, seconds,
  Bel including support for metric unit prefixes; so one can now e.g.
  conveniently use numbers in scripts like "5us" meaning "5 microseconds",
  or e.g. "12kHz" meaning "12 kilo Hertz", or e.g. "-14mdB" meaning
  "minus 14 Millidecibel", or e.g. "28c" meaning "28 cents" (for tuning).

* NKSP language: Introduced "final" operator "!" which is specifically
  intended for synthesis parameter values to denote that the synthesis
  parameter value is intended to be the "final" value for that synthesis
  parameter that should explicitly be used by the engine and thus causing
  the sampler engine to ignore all other modulation sources for the same
  synthesis parameter (like e.g. LFO, EG); by simply prefixing a value,
  variable or formula with this new "!" operator the expression is marked as
  being "final".

* Bumped version (2.1.1.svn4).

1 /***************************************************************************
2 * *
3 * Copyright (C) 2005 Christian Schoenebeck *
4 * Copyright (C) 2011 Christian Schoenebeck and Grigor Iliev *
5 * *
6 * This library is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This library is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this library; if not, write to the Free Software *
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
19 * MA 02111-1307 USA *
20 ***************************************************************************/
21
22 #ifndef __LS_SAWLFO_H__
23 #define __LS_SAWLFO_H__
24
25 #include "LFOBase.h"
26
27 namespace LinuxSampler {
28
29 /** @brief Saw LFO (int math implementation)
30 *
31 * This is a saw Low Frequency Oscillator which uses pure integer
32 * math (without branches) to synthesize the saw wave.
33 */
34 template<range_type_t RANGE, bool SAWUP>
35 class SawLFO : public LFOBase<RANGE> {
36 public:
37
38 /**
39 * Constructor
40 *
41 * @param Max - maximum value of the output levels
42 */
43 SawLFO(float Max) : LFOBase<RANGE>::LFOBase(Max) {
44 }
45
46 /**
47 * Calculates exactly one sample point of the LFO wave.
48 *
49 * @returns next LFO level
50 */
51 inline float render() {
52 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
53
54 uiLevel += c;
55 if (RANGE == range_unsigned)
56 return normalizer * (float) (SAWUP ? uiLevel : intLimit - uiLevel);
57 else /* signed range */
58 return normalizer * (float) (SAWUP ? uiLevel : intLimit - uiLevel) + offset;
59 }
60
61 /**
62 * Update LFO depth with a new external controller value.
63 *
64 * @param ExtControlValue - new external controller value
65 */
66 inline void updateByMIDICtrlValue(const uint16_t& ExtControlValue) {
67 this->ExtControlValue = ExtControlValue;
68
69 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
70 const float max = (this->InternalDepth + ExtControlValue * this->ExtControlDepthCoeff) * this->ScriptDepthFactor;
71 if (RANGE == range_unsigned) {
72 normalizer = max / (float) intLimit;
73 } else { // signed range
74 normalizer = max / (float) intLimit * 2.0f;
75 offset = -max;
76 }
77 }
78
79 /**
80 * Will be called by the voice when the key / voice was triggered.
81 *
82 * @param Frequency - frequency of the oscillator in Hz
83 * @param StartLevel - not implemented
84 * @param InternalDepth - firm, internal oscillator amplitude
85 * @param ExtControlDepth - defines how strong the external MIDI
86 * controller has influence on the
87 * oscillator amplitude
88 * @param FlipPhase - not implemented
89 * @param SampleRate - current sample rate of the engines
90 * audio output signal
91 */
92 virtual void trigger(float Frequency, start_level_t StartLevel, uint16_t InternalDepth, uint16_t ExtControlDepth, bool FlipPhase, unsigned int SampleRate) {
93 this->Frequency = Frequency;
94 this->InternalDepth = (InternalDepth / 1200.0f) * this->Max;
95 this->ExtControlDepthCoeff = (((float) ExtControlDepth / 1200.0f) / 127.0f) * this->Max;
96 this->ScriptFrequencyFactor = this->ScriptDepthFactor = 1.f; // reset for new voice
97 this->pFinalDepth = NULL;
98 this->pFinalFrequency = NULL;
99
100 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
101 const float freq = Frequency * this->ScriptFrequencyFactor;
102 const float r = freq / (float) SampleRate; // frequency alteration quotient
103 c = (int) (intLimit * r);
104
105 uiLevel = 0;
106 }
107
108 /**
109 * Should be invoked after the LFO is triggered.
110 * @param phase From 0 to 360 degrees.
111 */
112 void setPhase(float phase) {
113 if (phase < 0) phase = 0;
114 if (phase > 360) phase = 360;
115 phase /= 360.0f;
116 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
117 uiLevel = intLimit * phase;
118 }
119
120 void setFrequency(float Frequency, unsigned int SampleRate) {
121 this->Frequency = Frequency;
122 const float freq = Frequency * this->ScriptFrequencyFactor;
123 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
124 float r = freq / (float) SampleRate; // frequency alteration quotient
125 c = (int) (intLimit * r);
126 }
127
128 void setScriptDepthFactor(float factor, bool isFinal) {
129 this->ScriptDepthFactor = factor;
130 // set or reset this script depth parameter to be the sole
131 // source for the LFO depth
132 if (isFinal && !this->pFinalDepth)
133 this->pFinalDepth = &this->ScriptDepthFactor;
134 else if (!isFinal && this->pFinalDepth == &this->ScriptDepthFactor)
135 this->pFinalDepth = NULL;
136 // recalculate upon new depth
137 updateByMIDICtrlValue(this->ExtControlValue);
138 }
139
140 void setScriptFrequencyFactor(float factor, unsigned int SampleRate) {
141 this->ScriptFrequencyFactor = factor;
142 // in case script frequency was set as "final" value before,
143 // reset it so that all sources are processed from now on
144 if (this->pFinalFrequency == &this->ScriptFrequencyFactor)
145 this->pFinalFrequency = NULL;
146 // recalculate upon new frequency
147 setFrequency(this->Frequency, SampleRate);
148 }
149
150 void setScriptFrequencyFinal(float hz, unsigned int SampleRate) {
151 this->ScriptFrequencyFactor = hz;
152 // assign script's given frequency as sole source for the LFO
153 // frequency, thus ignore all other sources
154 if (!this->pFinalFrequency)
155 this->pFinalFrequency = &this->ScriptFrequencyFactor;
156 // recalculate upon new frequency
157 setFrequency(this->Frequency, SampleRate);
158 }
159
160 protected:
161 unsigned int uiLevel;
162 int c;
163 float offset; ///< only needed for signed range
164 float normalizer;
165 };
166
167
168 template<range_type_t RANGE>
169 class SawUpLFO : public SawLFO<RANGE, true> {
170 public:
171 SawUpLFO(float Max) : SawLFO<RANGE, true>::SawLFO(Max) { }
172 };
173
174 template<range_type_t RANGE>
175 class SawDownLFO : public SawLFO<RANGE, false> {
176 public:
177 SawDownLFO(float Max) : SawLFO<RANGE, false>::SawLFO(Max) { }
178 };
179
180 } // namespace LinuxSampler
181
182 #endif // __LS_SAWLFO_H__

  ViewVC Help
Powered by ViewVC