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

Annotation of /linuxsampler/trunk/src/engines/common/LFOSawIntMathOld.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3561 - (hide annotations) (download) (as text)
Fri Aug 23 11:44:00 2019 UTC (4 years, 8 months ago) by schoenebeck
Original Path: linuxsampler/trunk/src/engines/common/SawLFO.h
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 iliev 2223 /***************************************************************************
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 schoenebeck 3118 inline void updateByMIDICtrlValue(const uint16_t& ExtControlValue) {
67     this->ExtControlValue = ExtControlValue;
68    
69 iliev 2223 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
70 schoenebeck 3118 const float max = (this->InternalDepth + ExtControlValue * this->ExtControlDepthCoeff) * this->ScriptDepthFactor;
71 iliev 2223 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 schoenebeck 3118 this->Frequency = Frequency;
94 iliev 2223 this->InternalDepth = (InternalDepth / 1200.0f) * this->Max;
95     this->ExtControlDepthCoeff = (((float) ExtControlDepth / 1200.0f) / 127.0f) * this->Max;
96 schoenebeck 3118 this->ScriptFrequencyFactor = this->ScriptDepthFactor = 1.f; // reset for new voice
97 schoenebeck 3561 this->pFinalDepth = NULL;
98     this->pFinalFrequency = NULL;
99 iliev 2223
100     const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
101 schoenebeck 3118 const float freq = Frequency * this->ScriptFrequencyFactor;
102     const float r = freq / (float) SampleRate; // frequency alteration quotient
103 iliev 2223 c = (int) (intLimit * r);
104    
105     uiLevel = 0;
106     }
107 iliev 2225
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 iliev 2227
120     void setFrequency(float Frequency, unsigned int SampleRate) {
121 schoenebeck 3118 this->Frequency = Frequency;
122     const float freq = Frequency * this->ScriptFrequencyFactor;
123 iliev 2227 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
124 schoenebeck 3118 float r = freq / (float) SampleRate; // frequency alteration quotient
125 iliev 2227 c = (int) (intLimit * r);
126     }
127 iliev 2223
128 schoenebeck 3561 void setScriptDepthFactor(float factor, bool isFinal) {
129 schoenebeck 3118 this->ScriptDepthFactor = factor;
130 schoenebeck 3561 // 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 schoenebeck 3118 updateByMIDICtrlValue(this->ExtControlValue);
138     }
139    
140     void setScriptFrequencyFactor(float factor, unsigned int SampleRate) {
141     this->ScriptFrequencyFactor = factor;
142 schoenebeck 3561 // 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 schoenebeck 3118 setFrequency(this->Frequency, SampleRate);
148     }
149    
150 schoenebeck 3561 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 iliev 2223 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