zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

OscilGen.h (9022B)


      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 #include "../DSP/FFTwrapper.h"
     21 
     22 namespace zyn {
     23 
     24 class NoCopyNoMove
     25 {
     26 public:
     27     NoCopyNoMove() = default;
     28     NoCopyNoMove(const NoCopyNoMove& other) = delete;
     29     NoCopyNoMove& operator=(const NoCopyNoMove& other) = delete;
     30     NoCopyNoMove(NoCopyNoMove&& other) = delete;
     31     NoCopyNoMove& operator=(NoCopyNoMove&& other) = delete;
     32 };
     33 
     34 //Temporary args to safely create OscilGenBuffers
     35 struct OscilGenBuffersCreator
     36 {
     37     FFTwrapper* const fft;
     38     const int oscilsize;
     39     OscilGenBuffersCreator(FFTwrapper* fft, int oscilsize) :
     40         fft(fft), oscilsize(oscilsize) {}
     41 };
     42 
     43 //All temporary variables and buffers for OscilGen computations
     44 class OscilGenBuffers : NoCopyNoMove
     45 {
     46 public:
     47     OscilGenBuffers(OscilGenBuffersCreator creator);
     48     ~OscilGenBuffers();
     49     void defaults();
     50 
     51 private:
     52     // OscilGen needs to work with this data
     53     // Anyone else should not touch these
     54     friend class OscilGen;
     55 
     56     const int oscilsize;
     57 
     58     FFTfreqBuffer oscilFFTfreqs;
     59     fft_t *pendingfreqs;
     60 
     61     //This array stores some temporary data and it has OSCIL_SIZE elements
     62     FFTsampleBuffer tmpsmps;
     63     FFTfreqBuffer outoscilFFTfreqs;
     64     FFTsampleBuffer cachedbasefunc;
     65     bool cachedbasevalid;
     66 
     67     FFTfreqBuffer basefuncFFTfreqs; //Base function frequencies
     68     FFTfreqBuffer scratchFreqs; //Yet another tmp buffer
     69 
     70     //Internal Data
     71     unsigned char oldbasefunc, oldbasepar, oldhmagtype,
     72                   oldwaveshapingfunction, oldwaveshaping;
     73     int oldfilterpars, oldsapars, oldbasefuncmodulation,
     74         oldbasefuncmodulationpar1, oldbasefuncmodulationpar2,
     75         oldbasefuncmodulationpar3, oldharmonicshift;
     76     int oldmodulation, oldmodulationpar1, oldmodulationpar2,
     77         oldmodulationpar3;
     78 
     79     int    oscilprepared;   //1 if the oscil is prepared, 0 if it is not prepared and is need to call ::prepare() before ::get()
     80 
     81     float hmag[MAX_AD_HARMONICS], hphase[MAX_AD_HARMONICS]; //the magnituides and the phases of the sine/nonsine harmonics
     82 };
     83 
     84 class OscilGen:public Presets, NoCopyNoMove
     85 {
     86     public:
     87         OscilGen(const SYNTH_T &synth, FFTwrapper *fft_, const Resonance *res_);
     88 
     89         //You need to call this func if you need your own buffers for get() etc.
     90         OscilGenBuffersCreator createOscilGenBuffers() const;
     91 
     92         /**computes the full spectrum of oscil from harmonics,phases and basefunc*/
     93         void prepare(OscilGenBuffers& bfrs) const;
     94         void prepare() { return prepare(myBuffers()); }
     95 
     96         void prepare(OscilGenBuffers& bfrs, FFTfreqBuffer data) const;
     97 
     98         /**do the antialiasing(cut off higher freqs.),apply randomness and do a IFFT*/
     99         //returns where should I start getting samples, used in block type randomness
    100         short get(OscilGenBuffers& bfrs, float *smps, float freqHz, int resonance = 0) const;
    101         short get(float *smps, float freqHz, int resonance = 0) {
    102             return get(myBuffers(), smps, freqHz, resonance);
    103         }
    104         //if freqHz is smaller than 0, return the "un-randomized" sample for UI
    105 
    106         void getbasefunction(OscilGenBuffers& bfrs, FFTsampleBuffer smps) const;
    107 
    108         //called by UI
    109         void getspectrum(int n, float *spc, int what); //what=0 pt. oscil,1 pt. basefunc
    110         void getcurrentbasefunction(FFTsampleBuffer smps);
    111         /**convert oscil to base function*/
    112         void useasbase();
    113 
    114         void paste(OscilGen &o);
    115         void add2XML(XMLwrapper& xml) override;
    116         void defaults();
    117         void getfromXML(XMLwrapper& xml);
    118 
    119         void convert2sine();
    120 
    121         //Parameters
    122 
    123         /**
    124          * The hmag and hphase starts counting from 0, so the first harmonic(1) has the index 0,
    125          * 2-nd harmonic has index 1, ..the 128 harminic has index 127
    126          */
    127         unsigned char Phmag[MAX_AD_HARMONICS], Phphase[MAX_AD_HARMONICS]; //the MIDI parameters for mag. and phases
    128 
    129 
    130         /**The Type of magnitude:
    131          *   0 - Linear
    132          *   1 - dB scale (-40)
    133          *   2 - dB scale (-60)
    134          *   3 - dB scale (-80)
    135          *   4 - dB scale (-100)*/
    136         unsigned char Phmagtype;
    137 
    138         unsigned char Pcurrentbasefunc; //The base function used - 0=sin, 1=...
    139         unsigned char Pbasefuncpar; //the parameter of the base function
    140 
    141         unsigned char Pbasefuncmodulation; //what modulation is applied to the basefunc
    142         unsigned char Pbasefuncmodulationpar1, Pbasefuncmodulationpar2,
    143                       Pbasefuncmodulationpar3; //the parameter of the base function modulation
    144 
    145         unsigned char Pwaveshaping, Pwaveshapingfunction;
    146         unsigned char Pfiltertype, Pfilterpar1, Pfilterpar2;
    147         bool          Pfilterbeforews;
    148         unsigned char Psatype, Psapar; //spectrum adjust
    149 
    150         int Pharmonicshift; //how the harmonics are shifted
    151         int Pharmonicshiftfirst; //if the harmonic shift is done before waveshaping and filter
    152 
    153         unsigned char Pmodulation; //what modulation is applied to the oscil
    154         unsigned char Pmodulationpar1, Pmodulationpar2, Pmodulationpar3; //the parameter of the parameters
    155 
    156         /**Realtime parameters for ADnote*/
    157 
    158         /*the Randomness:
    159           64=no randomness
    160           63..0 - block type randomness - 0 is maximum
    161           65..127 - each harmonic randomness - 127 is maximum*/
    162         unsigned char Prand;
    163         unsigned char Pamprandpower, Pamprandtype; //amplitude randomness
    164         unsigned char Padaptiveharmonics; //the adaptive harmonics status (off=0,on=1,etc..)
    165         unsigned char Padaptiveharmonicsbasefreq; //the base frequency of the adaptive harmonic (30..3000Hz)
    166         unsigned char Padaptiveharmonicspower; //the strength of the effect (0=off,100=full)
    167         unsigned char Padaptiveharmonicspar; //the parameters in 2,3,4.. modes of adaptive harmonics
    168 
    169 
    170 
    171         //makes a new random seed for Amplitude Randomness
    172         //this should be called every note on event
    173         void newrandseed(unsigned int randseed);
    174 
    175         bool ADvsPAD; //!< true if it is used by PADsynth instead of ADsynth
    176 
    177         static const rtosc::MergePorts ports;
    178         static const rtosc::Ports      non_realtime_ports;
    179         static const rtosc::Ports      realtime_ports;
    180 
    181         /* Oscillator Frequencies -
    182          *  this is different than the harmonics set-up by the user,
    183          *  it may contain time-domain data if the antialiasing is turned off*/
    184 
    185         //Access m_myBuffers. Should be avoided.
    186         OscilGenBuffers& myBuffers() { return m_myBuffers; }
    187 
    188     private:
    189 
    190         //This has the advantage that it is the "old", "stable" code, and that
    191         //prepare can be re-used. The disadvantage is that, if multiple threads
    192         //work on this variable in parallel, race conditions would be possible.
    193         //So this might vanish, soon
    194         OscilGenBuffers m_myBuffers;
    195 
    196         FFTwrapper *fft;
    197         //computes the basefunction and make the FFT; newbasefunc<0  = same basefunc
    198         void changebasefunction(OscilGenBuffers& bfrs) const;
    199         //Waveshaping
    200         void waveshape(OscilGenBuffers& bfrs, FFTfreqBuffer freqs) const;
    201 
    202         //Filter the oscillator accotding to Pfiltertype and Pfilterpar
    203         void oscilfilter(fft_t *freqs) const;
    204 
    205         //Adjust the spectrum
    206         void spectrumadjust(fft_t *freqs) const;
    207 
    208         //Shift the harmonics
    209         void shiftharmonics(fft_t *freqs) const;
    210 
    211         //Do the oscil modulation stuff
    212         void modulation(OscilGenBuffers& bfrs, FFTfreqBuffer freqs) const;
    213 
    214         float userfunc(OscilGenBuffers& bfrs, float x) const;
    215 
    216     public:
    217         //Check system for needed updates
    218         bool needPrepare(OscilGenBuffers& bfrs) const;
    219         bool needPrepare() { return needPrepare(myBuffers()); }
    220     private:
    221 
    222         //Do the adaptive harmonic stuff
    223         void adaptiveharmonic(fft_t *f, float freq) const;
    224 
    225         //Do the adaptive harmonic postprocessing (2n+1,2xS,2xA,etc..)
    226         //this function is called even for the user interface
    227         //this can be called for the sine and components, and for the spectrum
    228         //(that's why the sine and cosine components should be processed with a separate call)
    229         void adaptiveharmonicpostprocess(fft_t *f, int size) const;
    230 
    231         const Resonance *res;
    232 
    233         unsigned int randseed;
    234     public:
    235         const SYNTH_T &synth;
    236 };
    237 
    238 typedef float filter_func_t(unsigned int, float, float);
    239 filter_func_t *getFilter(unsigned char func);
    240 typedef float base_func_t(float, float);
    241 base_func_t *getBaseFunction(unsigned char func);
    242 
    243 }
    244 
    245 #endif