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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 717 - (show annotations) (download) (as text)
Sun Jul 24 10:26:17 2005 UTC (18 years, 8 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 6059 byte(s)
Added "real" implementations of the triangle LFOs. Unfortunately
I introduced some bugs - the output results don't look like they should.
This has to be fixed.

1 /***************************************************************************
2 * *
3 * Copyright (C) 2005 Christian Schoenebeck *
4 * *
5 * This library is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This library is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this library; if not, write to the Free Software *
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
18 * MA 02111-1307 USA *
19 ***************************************************************************/
20
21 #ifndef __LS_LFOTRIANGLEINTMATH_H__
22 #define __LS_LFOTRIANGLEINTMATH_H__
23
24 #include "LFOBase.h"
25
26 namespace LinuxSampler {
27
28 /** @brief Triangle LFO (int math implementation)
29 *
30 * This is a triangle Low Frequency Oscillator which uses pure integer
31 * math (without branches) to synthesize the triangular wave.
32 */
33 template<range_type_t RANGE>
34 class LFOTriangleIntMath : public LFOBase<RANGE> {
35 public:
36
37 /**
38 * Constructor
39 *
40 * @param Max - maximum value of the output levels
41 */
42 LFOTriangleIntMath(float Max) : LFOBase<RANGE>::LFOBase(Max) {
43 }
44
45 /**
46 * Calculates exactly one sample point of the LFO wave.
47 *
48 * @returns next LFO level
49 */
50 inline float render() {
51 const int signshifts = (sizeof(int) * 8) - 1;
52 iLevel += c;
53 const int iSign = (iLevel >> signshifts) | 1;
54 if (RANGE == range_unsigned)
55 return normalizer * (float) (iSign * iLevel);
56 else /* signed range */
57 return normalizer * (float) (iSign * iLevel) + offset;
58 }
59
60 /**
61 * Update LFO depth with a new external controller value.
62 *
63 * @param ExtControlValue - new external controller value
64 */
65 inline void update(const uint16_t& ExtControlValue) {
66 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
67 const float max = InternalDepth + ExtControlValue * ExtControlDepthCoeff;
68 if (RANGE == range_unsigned) {
69 normalizer = max / (float) intLimit * 0.5f;
70 } else { // signed range
71 normalizer = max / (float) intLimit * 0.25f;
72 offset = -max;
73 }
74 }
75
76 /**
77 * Will be called by the voice when the key / voice was triggered.
78 *
79 * @param Frequency - frequency of the oscillator in Hz
80 * @param StartLevel - on which level the wave should start
81 * @param InternalDepth - firm, internal oscillator amplitude
82 * @param ExtControlDepth - defines how strong the external MIDI
83 * controller has influence on the
84 * oscillator amplitude
85 * @param FlipPhase - inverts the oscillator wave
86 * @param SampleRate - current sample rate of the engines
87 * audio output signal
88 */
89 void trigger(float Frequency, start_level_t StartLevel, uint16_t InternalDepth, uint16_t ExtControlDepth, bool FlipPhase, unsigned int SampleRate) {
90 this->InternalDepth = (InternalDepth / 1200.0f) * Max;
91 this->ExtControlDepthCoeff = (((float) ExtControlDepth / 1200.0f) / 127.0f) * Max;
92
93 const unsigned int intLimit = (unsigned int) -1; // all 0xFFFF...
94 const float r = Frequency / (float) SampleRate; // frequency alteration quotient
95 c = (int) (intLimit * r);
96
97 switch (StartLevel) {
98 case start_level_max: {
99 c = -c; // wave should go down
100 if (RANGE == range_unsigned)
101 iLevel = intLimit;
102 else /* signed range */
103 iLevel = intLimit >> 1;
104 break;
105 }
106 case start_level_mid: {
107 if (FlipPhase) c = -c; // wave should go down
108 if (RANGE == range_unsigned)
109 iLevel = intLimit >> 1;
110 else /* signed range */
111 iLevel = 0;
112 break;
113 }
114 case start_level_min: {
115 if (RANGE == range_unsigned)
116 iLevel = 0;
117 else /* signed range */
118 iLevel = -(intLimit >> 1);
119 break;
120 }
121 }
122 }
123
124 private:
125 int iLevel;
126 int c;
127 float offset; ///< only needed for signed range
128 float normalizer;
129 };
130
131 } // namespace LinuxSampler
132
133 #endif // __LS_LFOTRIANGLEINTMATH_H__

  ViewVC Help
Powered by ViewVC