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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 717 - (hide annotations) (download) (as text)
Sun Jul 24 10:26:17 2005 UTC (18 years, 9 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 5587 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 schoenebeck 717 /***************************************************************************
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_LFOTRIANGLEDIHARMONIC_H__
22     #define __LS_LFOTRIANGLEDIHARMONIC_H__
23    
24     #include "LFOBase.h"
25    
26     // amplitue of 2nd harmonic (to approximate the triangular wave)
27     // TODO: this was just a quick head calculation, needs to be recalculated exactly (DFT)
28     #define AMP2 0.1f
29    
30     namespace LinuxSampler {
31    
32     /** @brief Triangle LFO (di-harmonic implementation)
33     *
34     * This is a triangle Low Frequency Oscillator implementation which uses
35     * a di-harmonic solution. This means it sums up two harmonics
36     * (sinusoids) to approximate a triangular wave.
37     */
38     template<range_type_t RANGE>
39     class LFOTriangleDiHarmonic : public LFOBase<RANGE> {
40     public:
41    
42     /**
43     * Constructor
44     *
45     * @param Max - maximum value of the output levels
46     */
47     LFOTriangleDiHarmonic(float Max) : LFOBase<RANGE>::LFOBase(Max) {
48     }
49    
50     /**
51     * Calculates exactly one sample point of the LFO wave.
52     *
53     * @returns next LFO level
54     */
55     inline float render() {
56     real1 -= c1 * imag1;
57     imag1 += c1 * real1;
58     real2 -= c2 * imag2;
59     imag2 += c2 * real2;
60     if (RANGE == range_unsigned)
61     return (real1 + real2 * AMP2) * normalizer + normalizer;
62     else /* signed range */
63     return (real1 + real2 * AMP2) * normalizer;
64     }
65    
66     /**
67     * Update LFO depth with a new external controller value.
68     *
69     * @param ExtControlValue - new external controller value
70     */
71     inline void update(const uint16_t& ExtControlValue) {
72     const float max = InternalDepth + ExtControlValue * ExtControlDepthCoeff;
73     if (RANGE == range_unsigned)
74     normalizer = max * 0.5f;
75     else /* signed range */
76     normalizer = max;
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 - on which level the wave should start
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 - inverts the oscillator wave
89     * @param SampleRate - current sample rate of the engines
90     * audio output signal
91     */
92     void trigger(float Frequency, start_level_t StartLevel, uint16_t InternalDepth, uint16_t ExtControlDepth, bool FlipPhase, unsigned int SampleRate) {
93     this->InternalDepth = (InternalDepth / 1200.0f) * Max;
94     this->ExtControlDepthCoeff = (((float) ExtControlDepth / 1200.0f) / 127.0f) * Max;
95    
96     c1 = 2.0f * M_PI * Frequency / (float) SampleRate;
97     c2 = 2.0f * M_PI * Frequency / (float) SampleRate * 3.0f;
98    
99     float phi; // phase displacement
100     switch (StartLevel) {
101     case start_level_max:
102     phi = 0.0f; // 0�
103     break;
104     case start_level_mid:
105     phi = (FlipPhase) ? 3.0f * M_PI : M_PI; // 270� or 90�
106     break;
107     case start_level_min:
108     phi = 2.0f * M_PI; // 180�
109     break;
110     }
111     real1 = real2 = cos(phi);
112     imag1 = imag2 = sin(phi);
113     }
114    
115     private:
116     float c1;
117     float c2;
118     float real1;
119     float imag1;
120     float real2;
121     float imag2;
122     float normalizer;
123     };
124    
125     } // namespace LinuxSampler
126    
127     #endif // __LS_LFOTRIANGLEDIHARMONIC_H__

  ViewVC Help
Powered by ViewVC