Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EnvelopeParams.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. EnvelopeParams.cpp - Parameters for Envelope
  4. Copyright (C) 2002-2005 Nasca Octavian Paul
  5. Author: Nasca Octavian Paul
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. */
  11. #include <cmath>
  12. #include <cstdlib>
  13. #include <cassert>
  14. #include <rtosc/ports.h>
  15. #include <rtosc/port-sugar.h>
  16. #include "EnvelopeParams.h"
  17. #include "../Misc/Util.h"
  18. #include "../Misc/Time.h"
  19. #define rObject EnvelopeParams
  20. using namespace rtosc;
  21. static const rtosc::Ports localPorts = {
  22. rSelf(EnvelopeParams),
  23. rPaste,
  24. #undef rChangeCb
  25. #define rChangeCb if(!obj->Pfreemode) obj->converttofree(); if (obj->time) { \
  26. obj->last_update_timestamp = obj->time->time(); }
  27. rToggle(Pfreemode, "Complex Envelope Definitions"),
  28. #undef rChangeCb
  29. #define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); }
  30. rParamZyn(Penvpoints, rProp(internal), "Number of points in complex definition"),
  31. rParamZyn(Penvsustain, rProp(internal), "Location of the sustain point"),
  32. rParams(Penvdt, MAX_ENVELOPE_POINTS, "Envelope Delay Times"),
  33. rParams(Penvval, MAX_ENVELOPE_POINTS, "Envelope Values"),
  34. rParamZyn(Penvstretch, "Stretch with respect to frequency"),
  35. rToggle(Pforcedrelease, "Force Envelope to fully evaluate"),
  36. rToggle(Plinearenvelope, "Linear or Logarithmic Envelopes"),
  37. rParamZyn(PA_dt, "Attack Time"),
  38. rParamZyn(PA_val, "Attack Value"),
  39. rParamZyn(PD_dt, "Decay Time"),
  40. rParamZyn(PD_val, "Decay Value"),
  41. rParamZyn(PS_val, "Sustain Value"),
  42. rParamZyn(PR_dt, "Release Time"),
  43. rParamZyn(PR_val, "Release Value"),
  44. {"addPoint:i", rProp(internal) rDoc("Add point to envelope"), NULL, [](const char *msg, RtData &d)
  45. {
  46. EnvelopeParams *env = (rObject*) d.obj;
  47. const int curpoint = rtosc_argument(msg, 0).i;
  48. //int curpoint=freeedit->lastpoint;
  49. if (curpoint<0 || curpoint>env->Penvpoints || env->Penvpoints>=MAX_ENVELOPE_POINTS)
  50. return;
  51. for (int i=env->Penvpoints; i>=curpoint+1; i--) {
  52. env->Penvdt[i]=env->Penvdt[i-1];
  53. env->Penvval[i]=env->Penvval[i-1];
  54. }
  55. if (curpoint==0) {
  56. env->Penvdt[1]=64;
  57. }
  58. env->Penvpoints++;
  59. if (curpoint<=env->Penvsustain) env->Penvsustain++;
  60. }},
  61. {"delPoint:i", rProp(internal) rDoc("Delete Envelope Point"), NULL, [](const char *msg, RtData &d)
  62. {
  63. EnvelopeParams *env = (rObject*) d.obj;
  64. const int curpoint=rtosc_argument(msg, 0).i;
  65. if(curpoint<1 || curpoint>=env->Penvpoints-1 || env->Penvpoints<=3)
  66. return;
  67. for (int i=curpoint+1;i<env->Penvpoints;i++){
  68. env->Penvdt[i-1]=env->Penvdt[i];
  69. env->Penvval[i-1]=env->Penvval[i];
  70. };
  71. env->Penvpoints--;
  72. if (curpoint<=env->Penvsustain)
  73. env->Penvsustain--;
  74. }},
  75. };
  76. #undef rChangeCb
  77. const rtosc::Ports &EnvelopeParams::ports = localPorts;
  78. EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_,
  79. unsigned char Pforcedrelease_,
  80. const AbsTime *time_):
  81. time(time_), last_update_timestamp(0)
  82. {
  83. PA_dt = 10;
  84. PD_dt = 10;
  85. PR_dt = 10;
  86. PA_val = 64;
  87. PD_val = 64;
  88. PS_val = 64;
  89. PR_val = 64;
  90. for(int i = 0; i < MAX_ENVELOPE_POINTS; ++i) {
  91. Penvdt[i] = 32;
  92. Penvval[i] = 64;
  93. }
  94. Penvdt[0] = 0; //no used
  95. Penvsustain = 1;
  96. Penvpoints = 1;
  97. Envmode = 1;
  98. Penvstretch = Penvstretch_;
  99. Pforcedrelease = Pforcedrelease_;
  100. Pfreemode = 1;
  101. Plinearenvelope = 0;
  102. store2defaults();
  103. }
  104. EnvelopeParams::~EnvelopeParams()
  105. {}
  106. #define COPY(y) this->y = ep.y
  107. void EnvelopeParams::paste(const EnvelopeParams &ep)
  108. {
  109. COPY(Pfreemode);
  110. COPY(Penvpoints);
  111. COPY(Penvsustain);
  112. for(int i=0; i<MAX_ENVELOPE_POINTS; ++i) {
  113. this->Penvdt[i] = ep.Penvdt[i];
  114. this->Penvval[i] = ep.Penvval[i];
  115. }
  116. COPY(Penvstretch);
  117. COPY(Pforcedrelease);
  118. COPY(Plinearenvelope);
  119. COPY(PA_dt);
  120. COPY(PD_dt);
  121. COPY(PR_dt);
  122. COPY(PA_val);
  123. COPY(PD_val);
  124. COPY(PS_val);
  125. COPY(PR_val);
  126. if ( time ) {
  127. last_update_timestamp = time->time();
  128. }
  129. }
  130. #undef COPY
  131. float EnvelopeParams::getdt(char i) const
  132. {
  133. return EnvelopeParams::dt(Penvdt[(int)i]);
  134. }
  135. float EnvelopeParams::dt(char val)
  136. {
  137. return (powf(2.0f, val / 127.0f * 12.0f) - 1.0f) * 10.0f; //miliseconds
  138. }
  139. /*
  140. * ADSR/ASR... initialisations
  141. */
  142. void EnvelopeParams::ADSRinit(char A_dt, char D_dt, char S_val, char R_dt)
  143. {
  144. setpresettype("Penvamplitude");
  145. Envmode = 1;
  146. PA_dt = A_dt;
  147. PD_dt = D_dt;
  148. PS_val = S_val;
  149. PR_dt = R_dt;
  150. Pfreemode = 0;
  151. converttofree();
  152. store2defaults();
  153. }
  154. void EnvelopeParams::ADSRinit_dB(char A_dt, char D_dt, char S_val, char R_dt)
  155. {
  156. setpresettype("Penvamplitude");
  157. Envmode = 2;
  158. PA_dt = A_dt;
  159. PD_dt = D_dt;
  160. PS_val = S_val;
  161. PR_dt = R_dt;
  162. Pfreemode = 0;
  163. converttofree();
  164. store2defaults();
  165. }
  166. void EnvelopeParams::ASRinit(char A_val, char A_dt, char R_val, char R_dt)
  167. {
  168. setpresettype("Penvfrequency");
  169. Envmode = 3;
  170. PA_val = A_val;
  171. PA_dt = A_dt;
  172. PR_val = R_val;
  173. PR_dt = R_dt;
  174. Pfreemode = 0;
  175. converttofree();
  176. store2defaults();
  177. }
  178. void EnvelopeParams::ADSRinit_filter(char A_val,
  179. char A_dt,
  180. char D_val,
  181. char D_dt,
  182. char R_dt,
  183. char R_val)
  184. {
  185. setpresettype("Penvfilter");
  186. Envmode = 4;
  187. PA_val = A_val;
  188. PA_dt = A_dt;
  189. PD_val = D_val;
  190. PD_dt = D_dt;
  191. PR_dt = R_dt;
  192. PR_val = R_val;
  193. Pfreemode = 0;
  194. converttofree();
  195. store2defaults();
  196. }
  197. void EnvelopeParams::ASRinit_bw(char A_val, char A_dt, char R_val, char R_dt)
  198. {
  199. setpresettype("Penvbandwidth");
  200. Envmode = 5;
  201. PA_val = A_val;
  202. PA_dt = A_dt;
  203. PR_val = R_val;
  204. PR_dt = R_dt;
  205. Pfreemode = 0;
  206. converttofree();
  207. store2defaults();
  208. }
  209. /*
  210. * Convert the Envelope to freemode
  211. */
  212. void EnvelopeParams::converttofree()
  213. {
  214. switch(Envmode) {
  215. case 1:
  216. Penvpoints = 4;
  217. Penvsustain = 2;
  218. Penvval[0] = 0;
  219. Penvdt[1] = PA_dt;
  220. Penvval[1] = 127;
  221. Penvdt[2] = PD_dt;
  222. Penvval[2] = PS_val;
  223. Penvdt[3] = PR_dt;
  224. Penvval[3] = 0;
  225. break;
  226. case 2:
  227. Penvpoints = 4;
  228. Penvsustain = 2;
  229. Penvval[0] = 0;
  230. Penvdt[1] = PA_dt;
  231. Penvval[1] = 127;
  232. Penvdt[2] = PD_dt;
  233. Penvval[2] = PS_val;
  234. Penvdt[3] = PR_dt;
  235. Penvval[3] = 0;
  236. break;
  237. case 3:
  238. Penvpoints = 3;
  239. Penvsustain = 1;
  240. Penvval[0] = PA_val;
  241. Penvdt[1] = PA_dt;
  242. Penvval[1] = 64;
  243. Penvdt[2] = PR_dt;
  244. Penvval[2] = PR_val;
  245. break;
  246. case 4:
  247. Penvpoints = 4;
  248. Penvsustain = 2;
  249. Penvval[0] = PA_val;
  250. Penvdt[1] = PA_dt;
  251. Penvval[1] = PD_val;
  252. Penvdt[2] = PD_dt;
  253. Penvval[2] = 64;
  254. Penvdt[3] = PR_dt;
  255. Penvval[3] = PR_val;
  256. break;
  257. case 5:
  258. Penvpoints = 3;
  259. Penvsustain = 1;
  260. Penvval[0] = PA_val;
  261. Penvdt[1] = PA_dt;
  262. Penvval[1] = 64;
  263. Penvdt[2] = PR_dt;
  264. Penvval[2] = PR_val;
  265. break;
  266. }
  267. }
  268. void EnvelopeParams::add2XML(XMLwrapper& xml)
  269. {
  270. xml.addparbool("free_mode", Pfreemode);
  271. xml.addpar("env_points", Penvpoints);
  272. xml.addpar("env_sustain", Penvsustain);
  273. xml.addpar("env_stretch", Penvstretch);
  274. xml.addparbool("forced_release", Pforcedrelease);
  275. xml.addparbool("linear_envelope", Plinearenvelope);
  276. xml.addpar("A_dt", PA_dt);
  277. xml.addpar("D_dt", PD_dt);
  278. xml.addpar("R_dt", PR_dt);
  279. xml.addpar("A_val", PA_val);
  280. xml.addpar("D_val", PD_val);
  281. xml.addpar("S_val", PS_val);
  282. xml.addpar("R_val", PR_val);
  283. if((Pfreemode != 0) || (!xml.minimal))
  284. for(int i = 0; i < Penvpoints; ++i) {
  285. xml.beginbranch("POINT", i);
  286. if(i != 0)
  287. xml.addpar("dt", Penvdt[i]);
  288. xml.addpar("val", Penvval[i]);
  289. xml.endbranch();
  290. }
  291. }
  292. void EnvelopeParams::getfromXML(XMLwrapper& xml)
  293. {
  294. Pfreemode = xml.getparbool("free_mode", Pfreemode);
  295. Penvpoints = xml.getpar127("env_points", Penvpoints);
  296. Penvsustain = xml.getpar127("env_sustain", Penvsustain);
  297. Penvstretch = xml.getpar127("env_stretch", Penvstretch);
  298. Pforcedrelease = xml.getparbool("forced_release", Pforcedrelease);
  299. Plinearenvelope = xml.getparbool("linear_envelope", Plinearenvelope);
  300. PA_dt = xml.getpar127("A_dt", PA_dt);
  301. PD_dt = xml.getpar127("D_dt", PD_dt);
  302. PR_dt = xml.getpar127("R_dt", PR_dt);
  303. PA_val = xml.getpar127("A_val", PA_val);
  304. PD_val = xml.getpar127("D_val", PD_val);
  305. PS_val = xml.getpar127("S_val", PS_val);
  306. PR_val = xml.getpar127("R_val", PR_val);
  307. for(int i = 0; i < Penvpoints; ++i) {
  308. if(xml.enterbranch("POINT", i) == 0)
  309. continue;
  310. if(i != 0)
  311. Penvdt[i] = xml.getpar127("dt", Penvdt[i]);
  312. Penvval[i] = xml.getpar127("val", Penvval[i]);
  313. xml.exitbranch();
  314. }
  315. if(!Pfreemode)
  316. converttofree();
  317. }
  318. void EnvelopeParams::defaults()
  319. {
  320. Penvstretch = Denvstretch;
  321. Pforcedrelease = Dforcedrelease;
  322. Plinearenvelope = Dlinearenvelope;
  323. PA_dt = DA_dt;
  324. PD_dt = DD_dt;
  325. PR_dt = DR_dt;
  326. PA_val = DA_val;
  327. PD_val = DD_val;
  328. PS_val = DS_val;
  329. PR_val = DR_val;
  330. Pfreemode = 0;
  331. converttofree();
  332. }
  333. void EnvelopeParams::store2defaults()
  334. {
  335. Denvstretch = Penvstretch;
  336. Dforcedrelease = Pforcedrelease;
  337. Dlinearenvelope = Plinearenvelope;
  338. DA_dt = PA_dt;
  339. DD_dt = PD_dt;
  340. DR_dt = PR_dt;
  341. DA_val = PA_val;
  342. DD_val = PD_val;
  343. DS_val = PS_val;
  344. DR_val = PR_val;
  345. }