1 /*
2   ZynAddSubFX - a software synthesizer
3 
4   OscilGen.h - Waveform generator for ADnote
5   Copyright (C) 2002-2005 Nasca Octavian Paul
6   Author: Nasca Octavian Paul
7 
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License
10   as published by the Free Software Foundation; either version 2
11   of the License, or (at your option) any later version.
12 */
13 
14 #ifndef OSCIL_GEN_H
15 #define OSCIL_GEN_H
16 
17 #include "../globals.h"
18 #include <rtosc/ports.h>
19 #include "../Params/Presets.h"
20 
21 namespace zyn {
22 
23 class OscilGen:public Presets
24 {
25     public:
26         OscilGen(const SYNTH_T &synth, FFTwrapper *fft_, Resonance *res_);
27         ~OscilGen() override;
28 
29         /**computes the full spectrum of oscil from harmonics,phases and basefunc*/
30         void prepare();
31 
32         void prepare(fft_t *data);
33 
34         /**do the antialiasing(cut off higher freqs.),apply randomness and do a IFFT*/
35         //returns where should I start getting samples, used in block type randomness
36         short get(float *smps, float freqHz, int resonance = 0);
37         //if freqHz is smaller than 0, return the "un-randomized" sample for UI
38 
39         void getbasefunction(float *smps);
40 
41         //called by UI
42         void getspectrum(int n, float *spc, int what); //what=0 pt. oscil,1 pt. basefunc
43         void getcurrentbasefunction(float *smps);
44         /**convert oscil to base function*/
45         void useasbase();
46 
47         void paste(OscilGen &o);
48         void add2XML(XMLwrapper& xml) override;
49         void defaults();
50         void getfromXML(XMLwrapper& xml);
51 
52         void convert2sine();
53 
54         //Parameters
55 
56         /**
57          * The hmag and hphase starts counting from 0, so the first harmonic(1) has the index 0,
58          * 2-nd harmonic has index 1, ..the 128 harminic has index 127
59          */
60         unsigned char Phmag[MAX_AD_HARMONICS], Phphase[MAX_AD_HARMONICS]; //the MIDI parameters for mag. and phases
61 
62 
63         /**The Type of magnitude:
64          *   0 - Linear
65          *   1 - dB scale (-40)
66          *   2 - dB scale (-60)
67          *   3 - dB scale (-80)
68          *   4 - dB scale (-100)*/
69         unsigned char Phmagtype;
70 
71         unsigned char Pcurrentbasefunc; //The base function used - 0=sin, 1=...
72         unsigned char Pbasefuncpar; //the parameter of the base function
73 
74         unsigned char Pbasefuncmodulation; //what modulation is applied to the basefunc
75         unsigned char Pbasefuncmodulationpar1, Pbasefuncmodulationpar2,
76                       Pbasefuncmodulationpar3; //the parameter of the base function modulation
77 
78         unsigned char Pwaveshaping, Pwaveshapingfunction;
79         unsigned char Pfiltertype, Pfilterpar1, Pfilterpar2;
80         bool          Pfilterbeforews;
81         unsigned char Psatype, Psapar; //spectrum adjust
82 
83         int Pharmonicshift; //how the harmonics are shifted
84         int Pharmonicshiftfirst; //if the harmonic shift is done before waveshaping and filter
85 
86         unsigned char Pmodulation; //what modulation is applied to the oscil
87         unsigned char Pmodulationpar1, Pmodulationpar2, Pmodulationpar3; //the parameter of the parameters
88 
89         /**Realtime parameters for ADnote*/
90 
91         /*the Randomness:
92           64=no randomness
93           63..0 - block type randomness - 0 is maximum
94           65..127 - each harmonic randomness - 127 is maximum*/
95         unsigned char Prand;
96         unsigned char Pamprandpower, Pamprandtype; //amplitude randomness
97         unsigned char Padaptiveharmonics; //the adaptive harmonics status (off=0,on=1,etc..)
98         unsigned char Padaptiveharmonicsbasefreq; //the base frequency of the adaptive harmonic (30..3000Hz)
99         unsigned char Padaptiveharmonicspower; //the strength of the effect (0=off,100=full)
100         unsigned char Padaptiveharmonicspar; //the parameters in 2,3,4.. modes of adaptive harmonics
101 
102 
103 
104         //makes a new random seed for Amplitude Randomness
105         //this should be called every note on event
106         void newrandseed(unsigned int randseed);
107 
108         bool ADvsPAD; //!< true if it is used by PADsynth instead of ADsynth
109 
110         static const rtosc::MergePorts ports;
111         static const rtosc::Ports      non_realtime_ports;
112         static const rtosc::Ports      realtime_ports;
113 
114         /* Oscillator Frequencies -
115          *  this is different than the harmonics set-up by the user,
116          *  it may contains time-domain data if the antialiasing is turned off*/
117         fft_t *oscilFFTfreqs;
118 
119         fft_t *pendingfreqs;
120     private:
121         //This array stores some temporary data and it has OSCIL_SIZE elements
122         float *tmpsmps;
123         fft_t *outoscilFFTfreqs;
124         float *cachedbasefunc;
125         bool cachedbasevalid;
126 
127         float hmag[MAX_AD_HARMONICS], hphase[MAX_AD_HARMONICS]; //the magnituides and the phases of the sine/nonsine harmonics
128 
129         FFTwrapper *fft;
130         //computes the basefunction and make the FFT; newbasefunc<0  = same basefunc
131         void changebasefunction(void);
132         //Waveshaping
133         void waveshape(fft_t *freqs);
134 
135         //Filter the oscillator accotding to Pfiltertype and Pfilterpar
136         void oscilfilter(fft_t *freqs);
137 
138         //Adjust the spectrum
139         void spectrumadjust(fft_t *freqs);
140 
141         //Shift the harmonics
142         void shiftharmonics(fft_t *freqs);
143 
144         //Do the oscil modulation stuff
145         void modulation(fft_t *freqs);
146 
147         float userfunc(float x);
148 
149     public:
150         //Check system for needed updates
151         bool needPrepare(void);
152     private:
153 
154         //Do the adaptive harmonic stuff
155         void adaptiveharmonic(fft_t *f, float freq);
156 
157         //Do the adaptive harmonic postprocessing (2n+1,2xS,2xA,etc..)
158         //this function is called even for the user interface
159         //this can be called for the sine and components, and for the spectrum
160         //(that's why the sine and cosine components should be processed with a separate call)
161         void adaptiveharmonicpostprocess(fft_t *f, int size);
162 
163         //Internal Data
164         unsigned char oldbasefunc, oldbasepar, oldhmagtype,
165                       oldwaveshapingfunction, oldwaveshaping;
166         int oldfilterpars, oldsapars, oldbasefuncmodulation,
167             oldbasefuncmodulationpar1, oldbasefuncmodulationpar2,
168             oldbasefuncmodulationpar3, oldharmonicshift;
169         int oldmodulation, oldmodulationpar1, oldmodulationpar2,
170             oldmodulationpar3;
171 
172 
173         fft_t *basefuncFFTfreqs; //Base Function Frequencies
174         int    oscilprepared;   //1 if the oscil is prepared, 0 if it is not prepared and is need to call ::prepare() before ::get()
175 
176         Resonance *res;
177 
178         unsigned int randseed;
179     public:
180         const SYNTH_T &synth;
181 };
182 
183 typedef float filter_func_t(unsigned int, float, float);
184 filter_func_t *getFilter(unsigned char func);
185 typedef float base_func_t(float, float);
186 base_func_t *getBaseFunction(unsigned char func);
187 
188 }
189 
190 #endif
191