File: Oscillator.h

package info (click to toggle)
lsp-plugins 1.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 91,856 kB
  • sloc: cpp: 427,831; xml: 57,779; makefile: 9,961; php: 1,005; sh: 18
file content (390 lines) | stat: -rw-r--r-- 17,643 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/*
 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
 *           (C) 2020 Stefano Tronci <stefano.tronci@protonmail.com>
 *
 * This file is part of lsp-dsp-units
 * Created on: 20 Mar 2017
 *
 * lsp-dsp-units is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * lsp-dsp-units is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with lsp-dsp-units. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef LSP_PLUG_IN_DSP_UNITS_UTIL_OSCILLATOR_H_
#define LSP_PLUG_IN_DSP_UNITS_UTIL_OSCILLATOR_H_

#include <lsp-plug.in/dsp-units/version.h>
#include <lsp-plug.in/dsp-units/iface/IStateDumper.h>
#include <lsp-plug.in/dsp-units/util/Oversampler.h>

namespace lsp
{
    namespace dspu
    {
        enum fg_function_t
        {
            FG_SINE,            // Pure Math waves          //0
            FG_COSINE,                                      //1
            FG_SQUARED_SINE,                                //2
            FG_SQUARED_COSINE,                              //3
            FG_RECTANGULAR,                                 //4
            FG_SAWTOOTH,                                    //5
            FG_TRAPEZOID,                                   //6
            FG_PULSETRAIN,                                  //7
            FG_PARABOLIC,                                   //8
            FG_BL_RECTANGULAR,  // Band limited waves       //9
            FG_BL_SAWTOOTH,                                 //10
            FG_BL_TRAPEZOID,                                //11
            FG_BL_PULSETRAIN,                               //12
            FG_BL_PARABOLIC,                                //13
            FG_MAX
        };

        enum dc_reference_t
        {
            DC_WAVEDC,                                      // DC Offset with respect wave's natural DC (0 fDCOffset <=> Wave DC)
            DC_ZERO,                                        // DC Offset with respect 0 DC (0 fDCOffset <=> 0 Overall DC)
            DC_MAX
        };

        class LSP_DSP_UNITS_PUBLIC Oscillator
        {
            private:
                Oscillator & operator = (const Oscillator &);
                Oscillator(const Oscillator &);

            protected:
                typedef uint32_t phacc_t;

                typedef struct squared_sinusoid_t
                {
                    bool            bInvert;                // If true, invert the sign (phase) of the wave.
                    float           fAmplitude;             // Signed amplitude of the wave.
                    float           fWaveDC;                // Natural DC value of the wave.
                } squared_sinusoud_t;

                typedef struct rectangular_t
                {
                    float           fDutyRatio;             // Fraction of the period over which the wave is positive
                    phacc_t         nDutyWord;              // Word expressing the phase interval in which the rectangular wave is positive.
                    float           fWaveDC;                // DC value of the wave.
                    float           fBLPeakAtten;           // Value of attenuation to bring peak of band limited wave to 1.0f.
                } rectangular_t;

                typedef struct sawtooth_t
                {
                    float           fWidth;                 // Fraction of the period at which the tooth peaks
                    phacc_t         nWidthWord;             // Word expressing the phase value in which the sawtooth wave peaks.
                    float           fCoeffs[4];             // Coefficients of the sawtooth waves lines - ascending: [0] * p + [1]; descending: [2] * p + [3]; with p value of the phase accumulator.
                    float           fWaveDC;                // Natural DC value of the wave.
                    float           fBLPeakAtten;           // Value of attenuation to bring peak of band limited wave to 1.0f.
                } sawtooth_t;

                typedef struct trapezoid_t
                {
                    float           fRaiseRatio;            // Fraction of half period at which the wave ramps up.
                    float           fFallRatio;             // Fraction of half period at which the wave ramps down.
                    phacc_t         nPoints[4];             // Points of the vertices of the trapezoids along the period, as phase accumulator words.
                    float           fCoeffs[4];             // Coefficients of the trapezoid waves lines - ascending: [0] * p; descending: [1] * p + [2]; ascending [1] * p + [3]; with p value of the phase accumulator.
                    float           fWaveDC;                // Natural DC value of the wave.
                    float           fBLPeakAtten;           // Value of attenuation to bring peak of band limited wave to 1.0f.
                } trapezoid_t;

                typedef struct pulse_t
                {
                    float           fPosWidthRatio;         // Fraction of half period in which the positive pulse is active.
                    float           fNegWidthRatio;         // Fraction of half period in which the negative pulse is active.
                    phacc_t         nTrainPoints[3];        // Points of the vertices of the pulses along the period.
                    float           fWaveDC;                // Natural DC value of the wave.
                    float           fBLPeakAtten;           // Value of attenuation to bring peak of band limited wave to 1.0f.
                } pulse_t;

                typedef struct parabolic_t
                {
                    bool            bInvert;                // If true, invert the sign (phase) of the wave.
                    float           fAmplitude;
                    float           fWidth;                 // For parabolic waves, fraction of the period in which the parabola is contained.
                    phacc_t         nWidthWord;             // The above expressed as a phase accumulator word
                    float           fWaveDC;                // Natural DC value of the wave.
                    float           fBLPeakAtten;           // Value of attenuation to bring peak of band limited wave to 1.0f.
                } parabolic_t;

            private:
                fg_function_t       enFunction;             // Function for the oscillator.
                float               fAmplitude;             // Amplitude of the oscillator. [ Gain ]
                float               fFrequency;             // Oscillator frequency. [Hz]
                float               fDCOffset;              // DC offset [ Gain ]
                dc_reference_t      enDCReference;          // Select DC Offset reference. If true, wave DC will be shifted to 0.
                float               fReferencedDC;          // DC offset with reference to the specified value.
                float               fInitPhase;             // Additional phase factor. [rad]

                size_t              nSampleRate;            // Sample Rate. [Hz]
                phacc_t             nPhaseAcc;              // Phase accumulator variable.
                uint8_t             nPhaseAccBits;          // Number of bits in the phase accumulator.
                uint8_t             nPhaseAccMaxBits;       // Maximum number of bits available for the phase accumulator.
                phacc_t             nPhaseAccMask;          // Bit mask for the phase accumulator.
                float               fAcc2Phase;             // Factor converting from phase accumulator values to [rad] phase values.

                phacc_t             nFreqCtrlWord;          // Frequency control word for the phase accumulator
                phacc_t             nInitPhaseWord;         // Word expressing the initial phase. Depends upon fInitPhase.

                squared_sinusoid_t  sSquaredSinusoid;
                rectangular_t       sRectangular;
                sawtooth_t          sSawtooth;
                trapezoid_t         sTrapezoid;
                pulse_t             sPulse;
                parabolic_t         sParabolic;

                float              *vProcessBuffer;         // Buffers
                float              *vSynthBuffer;
                uint8_t            *pData;

                Oversampler         sOver;                  // Oversampler for Band Limited synthesis.
                Oversampler         sOverGetPeriods;        // Oversampler for get_periods method.
                size_t              nOversampling;          // Hold oversampling factor. This assumes all the oversamples used here will have the same factor.
                over_mode_t         enOverMode;             // Oversampler mode.
                phacc_t             nFreqCtrlWord_Over;     // Frequency control word for the oversampled phase accumulator.

                bool                bSync;                  // Flag that indicates that generator needs update

            protected:
                /** Synthesize the required wave and write its sample to internal
                 * buffer.
                 *
                 * @param os oversampler to use for the processing
                 * @param count number of samples to process
                 */
                void do_process(Oversampler *os, float * dst, size_t count);

            public:
                explicit Oscillator();
                ~Oscillator();

                /**
                 * Construct the oscillator
                 */
                void construct();

                /** Initialise Oscillator
                 *
                 */
                bool init();

                /** Destroy Oscillator
                 *
                 */
                void destroy();

            public:

                /** Check that generator needs settings update
                 *
                 * @return true if generator needs settings update
                 */
                inline bool needs_update() const
                {
                    return bSync;
                }

                /** This method should be called if needs_update() returns true
                 * before calling process() methods
                 *
                 */
                void update_settings();

                /** Set number of bits of the phase accumulator
                 *
                 * @param nBits number of bits
                 */
                inline void set_phase_accumulator_bits(uint8_t nBits)
                {
                    if ((nPhaseAccBits == nBits) || (nBits > nPhaseAccMaxBits)) // It's just my preference to use brackets
                        return;

                    nPhaseAccBits   = nBits;
                    nPhaseAcc       = 0;
                    bSync           = true;
                }

                /** Set sample rate for the function generator
                 *
                 * @param sr sample rate
                 */
                inline void set_sample_rate(size_t sr)
                {
                    if (nSampleRate == sr)
                        return;

                    nSampleRate = sr;
                    nPhaseAcc   = 0;
                    bSync       = true;
                }

                /** Reset the samples counter
                 *
                 */
                inline void reset_phase_accumulator() { nPhaseAcc = 0; }

                /** Set the function of the oscillator:
                 *
                 * @param function output function of the generator
                 */
                inline void set_function(fg_function_t function)
                {
                    if ((function < FG_SINE) || (function >= FG_MAX))
                        return;

                    enFunction  = function;
                    bSync       = true;
                }

                /** Set the frequency of the oscillator:
                 *
                 * @param frequency of the oscilator. [Hz]
                 */
                inline void set_frequency(float frequency)
                {
                    if (fFrequency == frequency)
                        return;

                    fFrequency      = frequency;
                    bSync           = true;
                }

                /** Get the exact current frequency of the oscillator:
                 *
                 */
                inline float get_exact_frequency() const
                {
                    return nSampleRate * nFreqCtrlWord * (1.0f / (nPhaseAccMask + 1.0f));
                }

                /** Set the phase factor of the oscillator:
                 *
                 *  @ param phase phase factor of the oscillator [rad].
                 */
                void set_phase(float phase);

                /** Get the exact current phase factor:
                 *
                 */
                float get_exact_phase() const;

                /** Set the DC offset
                 *
                 * @param dcOffset DC offset of the wave
                 */
                void set_dc_offset(float dcOffset);

                /** Set the DC Reference
                 *
                 * @param dcReference
                 */
                void set_dc_reference(dc_reference_t dcReference);

                /** Set inversion value for squared sinusoids
                 *
                 * @param invert boolean expressing if inverted
                 */
                void set_squared_sinusoid_inversion(bool invert);

                void set_parabolic_inversion(bool invert);

                /** Set the duty ratio for rectangular waves
                 *
                 * @param dutyRatio duty ratio of the rectangular wave.
                 */
                void set_duty_ratio(float dutyRatio);

                /** Set the width for sawtooth waves
                 *
                 * @ param width width of sawtooth wave
                 */
                void set_width(float width);

                /** Set raise and fall ratios for the trapezoid wave
                 *
                 * @ param raise raise ratio of the trapezoid
                 * @ param fall fall ratio of the trepezoid
                 */
                void set_trapezoid_ratios(float raise, float fall);

                /** Set width ratios for pulse train
                 *
                 * @param posWidthRatio ratio of the positive amplitude pulse
                 * @param negWidthRatio ratio of the negative amplitude pulse
                 */
                void set_pulsetrain_ratios(float posWidthRatio, float negWidthRatio);

                /** Set parabolic wave width
                 *
                 * @param width width of parabolic wave
                 */
                void set_parabolic_width(float width);

                /** Set Oversampler mode
                 *
                 * @param mode oversampler mode
                 */
                void set_oversampler_mode(over_mode_t mode);

                /** Set the amplitude of the oscillator:
                 *
                 * @param amplitude amplitude of the oscillator.
                 */
                void set_amplitude(float amplitude);

                /** Return a given number of periods of the output waves.
                 *
                 * @param dst output wave destination
                 * @param periods number of periods in the wave
                 * @param periodsSkip number or initial periods to skip
                 * @param samples number of samples in the wave
                 */
                void get_periods(float *dst, size_t periods, size_t periodsSkip, size_t samples);

                /** Output wave to the destination buffer in
                 * additive mode
                 *
                 * @param dst output wave destination
                 * @param src input source, allowed to be NULL
                 * @param count number of samples to synthesise
                 */
                void process_add(float *dst, const float *src, size_t count);

                /** Output wave to the destination buffer in
                 * multiplicative mode
                 *
                 * @param dst output wave destination
                 * @param src input source, allowed to be NULL
                 * @param count number of samples to process
                 */
                void process_mul(float *dst, const float *src, size_t count);

                /** Output wave to a destination buffer overwriting its content
                 *
                 * @param dst output wave destination
                 * @param src input source, allowed to be NULLL
                 * @param count number of samples to process
                 */
                void process_overwrite(float *dst, size_t count);

                /**
                 * Dump the state
                 * @param dumper dumper
                 */
                void dump(IStateDumper *v) const;
        };
    }
}

#endif /* LSP_PLUG_IN_DSP_UNITS_UTIL_OSCILLATOR_H_ */