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.

184 lines
4.8KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. LFO.cpp - LFO implementation
  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 modify
  7. it under the terms of version 2 of the GNU General Public License
  8. as published by the Free Software Foundation.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License (version 2 or later) for more details.
  13. You should have received a copy of the GNU General Public License (version 2)
  14. along with this program; if not, write to the Free Software Foundation,
  15. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. #include "LFO.h"
  18. #include "../Misc/Util.h"
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <math.h>
  22. LFO::LFO(LFOParams *lfopars, float basefreq)
  23. {
  24. if(lfopars->Pstretch == 0)
  25. lfopars->Pstretch = 1;
  26. float lfostretch = powf(basefreq / 440.0f,
  27. (lfopars->Pstretch - 64.0f) / 63.0f); //max 2x/octave
  28. float lfofreq =
  29. (powf(2, lfopars->Pfreq * 10.0f) - 1.0f) / 12.0f * lfostretch;
  30. incx = fabs(lfofreq) * synth->buffersize_f / synth->samplerate_f;
  31. if(lfopars->Pcontinous == 0) {
  32. if(lfopars->Pstartphase == 0)
  33. x = RND;
  34. else
  35. x = fmod((lfopars->Pstartphase - 64.0f) / 127.0f + 1.0f, 1.0f);
  36. }
  37. else {
  38. float tmp = fmod(lfopars->time * incx, 1.0f);
  39. x = fmod((lfopars->Pstartphase - 64.0f) / 127.0f + 1.0f + tmp, 1.0f);
  40. }
  41. //Limit the Frequency(or else...)
  42. if(incx > 0.49999999f)
  43. incx = 0.499999999f;
  44. lfornd = lfopars->Prandomness / 127.0f;
  45. if(lfornd < 0.0f)
  46. lfornd = 0.0f;
  47. else
  48. if(lfornd > 1.0f)
  49. lfornd = 1.0f;
  50. // lfofreqrnd=powf(lfopars->Pfreqrand/127.0f,2.0f)*2.0f*4.0f;
  51. lfofreqrnd = powf(lfopars->Pfreqrand / 127.0f, 2.0f) * 4.0f;
  52. switch(lfopars->fel) {
  53. case 1:
  54. lfointensity = lfopars->Pintensity / 127.0f;
  55. break;
  56. case 2:
  57. lfointensity = lfopars->Pintensity / 127.0f * 4.0f;
  58. break; //in octave
  59. default:
  60. lfointensity = powf(2, lfopars->Pintensity / 127.0f * 11.0f) - 1.0f; //in centi
  61. x -= 0.25f; //chance the starting phase
  62. break;
  63. }
  64. amp1 = (1 - lfornd) + lfornd * RND;
  65. amp2 = (1 - lfornd) + lfornd * RND;
  66. lfotype = lfopars->PLFOtype;
  67. lfodelay = lfopars->Pdelay / 127.0f * 4.0f; //0..4 sec
  68. incrnd = nextincrnd = 1.0f;
  69. freqrndenabled = (lfopars->Pfreqrand != 0);
  70. computenextincrnd();
  71. computenextincrnd(); //twice because I want incrnd & nextincrnd to be random
  72. }
  73. LFO::~LFO()
  74. {}
  75. /*
  76. * LFO out
  77. */
  78. float LFO::lfoout()
  79. {
  80. float out;
  81. switch(lfotype) {
  82. case 1: //LFO_TRIANGLE
  83. if((x >= 0.0f) && (x < 0.25f))
  84. out = 4.0f * x;
  85. else
  86. if((x > 0.25f) && (x < 0.75f))
  87. out = 2 - 4 * x;
  88. else
  89. out = 4.0f * x - 4.0f;
  90. break;
  91. case 2: //LFO_SQUARE
  92. if(x < 0.5f)
  93. out = -1;
  94. else
  95. out = 1;
  96. break;
  97. case 3: //LFO_RAMPUP
  98. out = (x - 0.5f) * 2.0f;
  99. break;
  100. case 4: //LFO_RAMPDOWN
  101. out = (0.5f - x) * 2.0f;
  102. break;
  103. case 5: //LFO_EXP_DOWN 1
  104. out = powf(0.05f, x) * 2.0f - 1.0f;
  105. break;
  106. case 6: //LFO_EXP_DOWN 2
  107. out = powf(0.001f, x) * 2.0f - 1.0f;
  108. break;
  109. default:
  110. out = cosf(x * 2.0f * PI); //LFO_SINE
  111. }
  112. if((lfotype == 0) || (lfotype == 1))
  113. out *= lfointensity * (amp1 + x * (amp2 - amp1));
  114. else
  115. out *= lfointensity * amp2;
  116. if(lfodelay < 0.00001f) {
  117. if(freqrndenabled == 0)
  118. x += incx;
  119. else {
  120. float tmp = (incrnd * (1.0f - x) + nextincrnd * x);
  121. if(tmp > 1.0f)
  122. tmp = 1.0f;
  123. else
  124. if(tmp < 0.0f)
  125. tmp = 0.0f;
  126. x += incx * tmp;
  127. }
  128. if(x >= 1) {
  129. x = fmod(x, 1.0f);
  130. amp1 = amp2;
  131. amp2 = (1 - lfornd) + lfornd * RND;
  132. computenextincrnd();
  133. }
  134. }
  135. else
  136. lfodelay -= synth->buffersize_f / synth->samplerate_f;
  137. return out;
  138. }
  139. /*
  140. * LFO out (for amplitude)
  141. */
  142. float LFO::amplfoout()
  143. {
  144. float out;
  145. out = 1.0f - lfointensity + lfoout();
  146. if(out < -1.0f)
  147. out = -1.0f;
  148. else
  149. if(out > 1.0f)
  150. out = 1.0f;
  151. return out;
  152. }
  153. void LFO::computenextincrnd()
  154. {
  155. if(freqrndenabled == 0)
  156. return;
  157. incrnd = nextincrnd;
  158. nextincrnd = powf(0.5f, lfofreqrnd) + RND * (powf(2.0f, lfofreqrnd) - 1.0f);
  159. }