2 ZynAddSubFX - a software synthesizer
4 LFOParams.cpp - Parameters for LFO
5 Copyright (C) 2002-2005 Nasca Octavian Paul
6 Author: Nasca Octavian Paul
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.
16 #include "../globals.h"
17 #include "../Misc/Util.h"
18 #include "../Misc/XMLwrapper.h"
19 #include "../Misc/Time.h"
20 #include "LFOParams.h"
22 #include <rtosc/port-sugar.h>
23 #include <rtosc/ports.h>
24 using namespace rtosc
;
28 #define rObject LFOParams
30 #define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); }
31 #define rBegin [](const char *msg, rtosc::RtData &d) {
34 static const rtosc::Ports _ports
= {
37 rOption(loc
, rProp(internal
),
38 rOptions(ad_global_amp
, ad_global_freq
, ad_global_filter
,
39 ad_voice_amp
, ad_voice_freq
, ad_voice_filter
, unspecified
),
40 "location of the filter"),
41 rParamF(freq
, rShort("freq"), rUnit(HZ
), rLog(0.0775679,85.25),
43 rPreset(ad_global_amp
, 6.49), // 80
44 rPreset(ad_global_freq
, 3.71), // 70
45 rPreset(ad_global_filter
, 6.49),
46 rPreset(ad_voice_amp
, 11.25), // 90
47 rPreset(ad_voice_freq
, 1.19), // 50
48 rPreset(ad_voice_filter
, 1.19),
50 "lfo frequency = Pfreq * stretch\n"
51 "true frequency is [0,85.25] Hz"),
52 {"Pfreq::f", rShort("freq.") rLinear(0, 1.0) rDoc("frequency of LFO "
53 "lfo frequency = Pfreq * stretch "
54 "true frequency is [0,85.25] Hz"), NULL
,
55 [](const char *msg
, RtData
&d
)
57 rObject
*obj
= (rObject
*)d
.obj
;
58 if (!rtosc_narguments(msg
)) {
59 d
.reply(d
.loc
, "f", log2f(12.0f
* obj
->freq
+ 1.0f
) / 10.0f
);
61 obj
->freq
= (powf(2, 10.0f
* rtosc_argument(msg
, 0).f
) - 1.0f
) / 12.0f
;
64 rParamZyn(Pintensity
, rShort("depth"),
66 rDefault(0), rPreset(ad_voice_amp
, 32),
67 rPreset(ad_voice_freq
, 40), rPreset(ad_voice_filter
, 20),
69 rParamZyn(Pstartphase
, rShort("start"), rSpecial(random
),
70 rDefaultDepends(loc
), rDefault(64), rPreset(ad_voice_freq
, 0),
72 rParamZyn(Pcutoff
, rShort("lp"), rDefault(127),
73 "RND/SQR lp-filter freq"),
74 rOption(PLFOtype
, rShort("type"), rOptions(sine
, triangle
, square
, up
, down
,
75 exp1
, exp2
, random
), rLinear(0,127), rDefault(sine
), "Shape of LFO"),
76 rParamZyn(Prandomness
, rShort("a.r."), rSpecial(disable
), rDefault(0),
77 "Amplitude Randomness (calculated uniformly at each cycle)"),
78 rParamZyn(Pfreqrand
, rShort("f.r."), rSpecial(disable
), rDefault(0),
79 "Frequency Randomness (calculated uniformly at each cycle)"),
80 rParamF(delay
, rShort("delay"), rSpecial(disable
), rUnit(S
),
81 rLinear(0.0, 4.0), rDefaultDepends(loc
), rDefault(0),
82 rPreset(ad_voice_amp
, 0.94),
83 "Delay before LFO start\n0..4 second delay"),
84 rParamF(fadein
, rShort("f.in"), rSpecial(disable
), rUnit(S
),
85 rLinear(0.0, 10.0f
), rDefault(0.0f
),
86 "Time to ramp up LFO amplitude\n \
88 rParamF(fadeout
, rShort("f.out"), rSpecial(disable
), rUnit(S
),
89 rLinear(0.001, 10.0f
), rDefault(10.0f
),
90 "Time to ramp down LFO amplitude on key release\n \
91 0..10 seconds, 10=off (default)"),
92 {"Pdelay::i", rShort("delay") rLinear(0,127)
93 rDoc("Delay before LFO start\n0..4 second delay"), NULL
,
94 [](const char *msg
, RtData
&d
)
96 rObject
*obj
= (rObject
*)d
.obj
;
97 if (!rtosc_narguments(msg
)) {
98 d
.reply(d
.loc
, "i", (int)roundf(127.0f
* obj
->delay
/ 4.0f
));
100 obj
->delay
= 4.0f
* rtosc_argument(msg
, 0).i
/ 127.0f
;
104 rToggle(Pcontinous
, rShort("c"), rDefault(false),
105 "Enable for global operation"),
106 rParamZyn(Pstretch
, rShort("str"), rCentered
, rDefault(64),
107 "Note frequency stretch"),
108 rParamZyn(numerator
, rShort("num"), rLinear(0,99), rDefault(0),
109 "Numerator of ratio to bpm"),
110 rParamZyn(denominator
, rShort("dem"), rLinear(0,99), rDefault(4),
111 "Denominator of ratio to bpm"),
112 // these are currently not yet implemented and must be hidden therefore
114 //Float valued aliases
115 {"delay::f", rProp(parameter
) rMap(units
, ms
) rLog(0,4000), 0,
119 #define rPseudoLog(a,b) rLog(a,b)
120 {"period::f", rProp(parameter
) rMap(units
, ms
) rPseudoLog(0.10, 1500.0), 0,
130 const rtosc::Ports
&LFOParams::ports
= _ports
;
132 void LFOParams::setup()
135 case loc_unspecified
:
136 fel
= consumer_location_type_t::unspecified
;
140 fel
= consumer_location_type_t::freq
;
141 setpresettype("Plfofrequency");
145 fel
= consumer_location_type_t::amp
;
146 setpresettype("Plfoamplitude");
148 case ad_global_filter
:
149 case ad_voice_filter
:
150 fel
= consumer_location_type_t::filter
;
151 setpresettype("Plfofilter");
154 throw std::logic_error("Invalid lfo consumer location");
161 LFOParams::LFOParams(const AbsTime
*time_
) :
162 LFOParams(2.65, 0, 0, 127, 0, 0, 0.0, 0.0, 10.0, 0, loc_unspecified
, time_
)
166 LFOParams::LFOParams(float freq_
,
176 consumer_location_t loc
,
177 const AbsTime
*time_
) : loc(loc
),
179 last_update_timestamp(0) {
181 Dintensity
= Pintensity_
;
182 Dstartphase
= Pstartphase_
;
184 DLFOtype
= PLFOtype_
;
185 Drandomness
= Prandomness_
;
189 Dcontinous
= Pcontinous_
;
194 LFOParams::LFOParams(consumer_location_t loc
,
195 const AbsTime
*time_
) : loc(loc
),
197 last_update_timestamp(0) {
200 [&](float freq_
, char Pintensity_
, char Pstartphase_
, float delay_
)
203 Dintensity
= Pintensity_
;
204 Dstartphase
= Pstartphase_
;
217 case ad_global_amp
: init(6.49, 0, 64, 0.0f
); break;
218 case ad_global_freq
: init(3.71, 0, 64, 0.0f
); break;
219 case ad_global_filter
: init(6.49, 0, 64, 0.0f
); break;
220 case ad_voice_amp
: init(11.25, 32, 64, 0.94f
); break;
221 case ad_voice_freq
: init(1.19, 40, 0, 0.0f
); break;
222 case ad_voice_filter
: init(1.19, 20, 64, 0.0f
); break;
223 default: throw std::logic_error("Invalid LFO consumer location");
229 LFOParams::~LFOParams()
232 void LFOParams::defaults()
235 Pintensity
= Dintensity
;
236 Pstartphase
= Dstartphase
;
239 Prandomness
= Drandomness
;
243 Pcontinous
= Dcontinous
;
251 void LFOParams::add2XML(XMLwrapper
& xml
)
253 xml
.addparreal("freq", freq
);
254 xml
.addpar("intensity", Pintensity
);
255 xml
.addpar("start_phase", Pstartphase
);
256 xml
.addpar("cutoff", Pcutoff
);
257 xml
.addpar("lfo_type", PLFOtype
);
258 xml
.addpar("randomness_amplitude", Prandomness
);
259 xml
.addpar("randomness_frequency", Pfreqrand
);
260 xml
.addparreal("delay", delay
);
261 xml
.addparreal("fadein", fadein
);
262 xml
.addparreal("fadeout", fadeout
);
263 xml
.addpar("stretch", Pstretch
);
264 xml
.addparbool("continous", Pcontinous
);
265 xml
.addpar("numerator", numerator
);
266 xml
.addpar("denominator", denominator
);
269 void LFOParams::getfromXML(XMLwrapper
& xml
)
271 if (xml
.fileversion() < version_type(3, 0, 4)) {
272 freq
= (powf(2.0f
, 10.0f
* xml
.getparreal("freq", freq
, 0.0f
, 1.0f
)) -1) / 12.0;
274 freq
= xml
.getparreal("freq", freq
);
276 Pintensity
= xml
.getpar127("intensity", Pintensity
);
277 Pstartphase
= xml
.getpar127("start_phase", Pstartphase
);
278 Pcutoff
= xml
.getpar127("cutoff", Pcutoff
);
279 PLFOtype
= xml
.getpar127("lfo_type", PLFOtype
);
280 Prandomness
= xml
.getpar127("randomness_amplitude", Prandomness
);
281 Pfreqrand
= xml
.getpar127("randomness_frequency", Pfreqrand
);
282 if (xml
.hasparreal("delay")) {
283 delay
= xml
.getparreal("delay", delay
);
285 delay
= 4.0f
* xml
.getpar127("delay", (int)delay
*127.0f
/4.0f
)
288 if (xml
.hasparreal("fadein")) {
289 fadein
= xml
.getparreal("fadein", fadein
);
291 if (xml
.hasparreal("fadeout")) {
292 fadeout
= xml
.getparreal("fadeout", fadeout
);
294 Pstretch
= xml
.getpar127("stretch", Pstretch
);
295 Pcontinous
= xml
.getparbool("continous", Pcontinous
);
297 numerator
= xml
.getpar("numerator", numerator
, 0, 99);
298 denominator
= xml
.getpar("denominator", denominator
, 0, 99);
301 #define COPY(y) this->y=x.y
302 void LFOParams::paste(LFOParams
&x
)
320 last_update_timestamp
= time
->time();