1 /*
2   ZynAddSubFX - a software synthesizer
3 
4   Effect.h - this class is inherited by all effects (Reverb, Echo, ...)
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 EFFECT_H
15 #define EFFECT_H
16 
17 #include "../Misc/Util.h"
18 #include "../globals.h"
19 #include "../Params/FilterParams.h"
20 #include "../Misc/Stereo.h"
21 
22 // effect parameters differing between single effects
23 #ifndef rEffPar
24 #define rEffPar(name, idx, ...) \
25   {STRINGIFY(name) "::i",  rProp(parameter) rDefaultDepends(preset) \
26       rLinear(0,127) DOC(__VA_ARGS__), NULL, rEffParCb(idx)}
27 #define rEffParOpt(name, idx, ...) \
28   {STRINGIFY(name) "::i:c:S",  rProp(parameter) rDefaultDepends(preset) \
29    rProp(enumerated) DOC(__VA_ARGS__), NULL, \
30        rBOIL_BEGIN \
31        rCOptionCb_(obj->getpar(idx), obj->changepar(idx, var)) \
32        rBOIL_END }
33 #define rEffParTF(name, idx, ...) \
34   {STRINGIFY(name) "::T:F",  rProp(parameter) rDefaultDepends(preset) \
35    DOC(__VA_ARGS__), NULL, rEffParTFCb(idx)}
36 #define rEffParCb(idx) \
37     [](const char *msg, rtosc::RtData &d) {\
38         rObject &obj = *(rObject*)d.obj; \
39         if(rtosc_narguments(msg)) { \
40             obj.changepar(idx, rtosc_argument(msg, 0).i); \
41             d.broadcast(d.loc, "i", obj.getpar(idx)); \
42         } \
43         else \
44             d.reply(d.loc, "i", obj.getpar(idx));}
45 #define rEffParTFCb(idx) \
46     [](const char *msg, rtosc::RtData &d) {\
47         rObject &obj = *(rObject*)d.obj; \
48         if(rtosc_narguments(msg)) { \
49             obj.changepar(idx, rtosc_argument(msg, 0).T*127); \
50             d.broadcast(d.loc, obj.getpar(idx)?"T":"F"); \
51         } \
52         else \
53             d.reply(d.loc, obj.getpar(idx)?"T":"F");}
54 #endif
55 
56 // effect parameters common to all effects
57 #define rEffParCommon(pname, rshort, rdoc, idx, ...) \
58 {STRINGIFY(pname) "::i", rProp(parameter) rLinear(0,127) \
59     rShort(rshort) DOC(__VA_ARGS__, rdoc), \
60     0, \
61     [](const char *msg, rtosc::RtData &d) \
62     { \
63         rObject& eff = *(rObject*)d.obj; \
64         if(!rtosc_narguments(msg)) \
65             d.reply(d.loc, "i", eff.getpar(idx)); \
66         else { \
67             eff.changepar(0, rtosc_argument(msg, 0).i); \
68             d.broadcast(d.loc, "i", eff.getpar(idx)); \
69         } \
70     }}
71 #define rEffParVol(...) rEffParCommon(Pvolume, "amt", "amount of effect", 0, \
72     __VA_ARGS__)
73 #define rEffParPan(...) rEffParCommon(Ppanning, "pan", "panning", 1, \
74     __VA_ARGS__)
75 
76 
77 namespace zyn {
78 
79 class FilterParams;
80 class Allocator;
81 
82 struct EffectParams
83 {
84     /**
85      * Effect Parameter Constructor
86      * @param alloc        Realtime Memory Allocator
87      * @param insertion_   1 when it is an insertion Effect
88      * @param efxoutl_     Effect output buffer Left channel
89      * @param efxoutr_     Effect output buffer Right channel
90      * @param filterpars_  pointer to FilterParams array
91      * @param Ppreset_     chosen preset
92      * @return Initialized Effect Parameter object*/
93     EffectParams(Allocator &alloc_, bool insertion_, float *efxoutl_, float *efxoutr_,
94             unsigned char Ppreset_, unsigned int srate, int bufsize, FilterParams *filterpars_,
95             bool filterprotect=false);
96 
97 
98     Allocator &alloc;
99     bool insertion;
100     float *efxoutl;
101     float *efxoutr;
102     unsigned char Ppreset;
103     unsigned int srate;
104     int bufsize;
105     FilterParams *filterpars;
106     bool filterprotect;
107 };
108 
109 /**this class is inherited by the all effects(Reverb, Echo, ..)*/
110 class Effect
111 {
112     public:
113         Effect(EffectParams pars);
~Effect()114         virtual ~Effect() {}
115         /**
116          * Get default preset parameter value
117          * @param npreset chosen preset
118          * @param npar chosen parameter
119          * @return the default parameter value
120          **/
121         virtual unsigned char getpresetpar(unsigned char npreset, unsigned int npar) = 0;
122         /**
123          * Choose a preset
124          * @param npreset number of chosen preset*/
125         virtual void setpreset(unsigned char npreset) = 0;
126         /**Change parameter npar to value
127          * @param npar chosen parameter
128          * @param value chosen new value*/
129         virtual void changepar(int npar, unsigned char value) = 0;
130         /**Get the value of parameter npar
131          * @param npar chosen parameter
132          * @return the value of the parameter in an unsigned char or 0 if it
133          * does not exist*/
134         virtual unsigned char getpar(int npar) const = 0;
135         /**Output result of effect based on the given buffers
136          *
137          * This method should result in the effect generating its results
138          * and placing them into the efxoutl and efxoutr buffers.
139          * Every Effect should override this method.
140          *
141          * @param smpsl Input buffer for the Left channel
142          * @param smpsr Input buffer for the Right channel
143          */
144         void out(float *const smpsl, float *const smpsr);
145         virtual void out(const Stereo<float *> &smp) = 0;
146         /**Reset the state of the effect*/
cleanup(void)147         virtual void cleanup(void) {}
getfreqresponse(float freq)148         virtual float getfreqresponse(float freq) { return freq; }
149 
150         unsigned char Ppreset;   /**<Currently used preset*/
151         float *const  efxoutl; /**<Effect out Left Channel*/
152         float *const  efxoutr; /**<Effect out Right Channel*/
153         float outvolume; /**<This is the volume of effect and is public because
154                           * it is needed in system effects.
155                           * The out volume of such effects are always 1.0f, so
156                           * this setting tells me how is the volume to the
157                           * Master Output only.*/
158 
159         float volume;
160 
161         FilterParams *filterpars; /**<Parameters for filters used by Effect*/
162 
163         //Perform L/R crossover
164         static void crossover(float &a, float &b, float crossover);
165 
166     protected:
167         void setpanning(char Ppanning_);
168         void setlrcross(char Plrcross_);
169 
170         const bool insertion;
171         //panning parameters
172         char  Ppanning;
173         float pangainL;
174         float pangainR;
175         char  Plrcross; // L/R mix
176         float lrcross;
177 
178         //Allocator
179         Allocator &memory;
180 
181         // current setup
182         unsigned int samplerate;
183         int buffersize;
184 
185         // alias for above terms
186         float samplerate_f;
187         float halfsamplerate_f;
188         float buffersize_f;
189         int   bufferbytes;
190 
alias()191         inline void alias()
192         {
193             samplerate_f     = samplerate;
194             halfsamplerate_f = samplerate_f / 2.0f;
195             buffersize_f     = buffersize;
196             bufferbytes      = buffersize * sizeof(float);
197         }
198 };
199 
200 }
201 
202 #endif
203