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.

188 lines
5.3KB

  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
  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 "LFO.h"
  12. #include "../Params/LFOParams.h"
  13. #include "../Misc/Util.h"
  14. #include <cstdlib>
  15. #include <cstdio>
  16. #include <cmath>
  17. LFO::LFO(const LFOParams &lfopars, float basefreq, const AbsTime &t)
  18. :first_half(-1),
  19. delayTime(t, lfopars.Pdelay / 127.0f * 4.0f), //0..4 sec
  20. waveShape(lfopars.PLFOtype),
  21. deterministic(!lfopars.Pfreqrand),
  22. dt_(t.dt()),
  23. lfopars_(lfopars), basefreq_(basefreq)
  24. {
  25. int stretch = lfopars.Pstretch;
  26. if(stretch == 0)
  27. stretch = 1;
  28. //max 2x/octave
  29. const float lfostretch = powf(basefreq / 440.0f, (stretch - 64.0f) / 63.0f);
  30. const float lfofreq =
  31. (powf(2, lfopars.Pfreq * 10.0f) - 1.0f) / 12.0f * lfostretch;
  32. phaseInc = fabs(lfofreq) * t.dt();
  33. if(!lfopars.Pcontinous) {
  34. if(lfopars.Pstartphase == 0)
  35. phase = RND;
  36. else
  37. phase = fmod((lfopars.Pstartphase - 64.0f) / 127.0f + 1.0f, 1.0f);
  38. }
  39. else {
  40. const float tmp = fmod(t.time() * phaseInc, 1.0f);
  41. phase = fmod((lfopars.Pstartphase - 64.0f) / 127.0f + 1.0f + tmp, 1.0f);
  42. }
  43. //Limit the Frequency(or else...)
  44. if(phaseInc > 0.49999999f)
  45. phaseInc = 0.499999999f;
  46. lfornd = limit(lfopars.Prandomness / 127.0f, 0.0f, 1.0f);
  47. lfofreqrnd = powf(lfopars.Pfreqrand / 127.0f, 2.0f) * 4.0f;
  48. switch(lfopars.fel) {
  49. case 1:
  50. lfointensity = lfopars.Pintensity / 127.0f;
  51. break;
  52. case 2:
  53. lfointensity = lfopars.Pintensity / 127.0f * 4.0f;
  54. break; //in octave
  55. default:
  56. lfointensity = powf(2, lfopars.Pintensity / 127.0f * 11.0f) - 1.0f; //in centi
  57. phase -= 0.25f; //chance the starting phase
  58. break;
  59. }
  60. amp1 = (1 - lfornd) + lfornd * RND;
  61. amp2 = (1 - lfornd) + lfornd * RND;
  62. incrnd = nextincrnd = 1.0f;
  63. computeNextFreqRnd();
  64. computeNextFreqRnd(); //twice because I want incrnd & nextincrnd to be random
  65. }
  66. LFO::~LFO()
  67. {}
  68. float LFO::baseOut(const char waveShape, const float phase)
  69. {
  70. switch(waveShape) {
  71. case LFO_TRIANGLE:
  72. if(phase >= 0.0f && phase < 0.25f)
  73. return 4.0f * phase;
  74. else if(phase > 0.25f && phase < 0.75f)
  75. return 2 - 4 * phase;
  76. else
  77. return 4.0f * phase - 4.0f;
  78. break;
  79. case LFO_SQUARE:
  80. if(phase < 0.5f)
  81. return -1;
  82. else
  83. return 1;
  84. break;
  85. case LFO_RAMPUP: return (phase - 0.5f) * 2.0f;
  86. case LFO_RAMPDOWN: return (0.5f - phase) * 2.0f;
  87. case LFO_EXP_DOWN1: return powf(0.05f, phase) * 2.0f - 1.0f;
  88. case LFO_EXP_DOWN2: return powf(0.001f, phase) * 2.0f - 1.0f;
  89. case LFO_RANDOM:
  90. if ((phase < 0.5) != first_half) {
  91. first_half = phase < 0.5;
  92. last_random = 2*RND-1;
  93. }
  94. return last_random;
  95. default: return cosf(phase * 2.0f * PI); //LFO_SINE
  96. }
  97. }
  98. float LFO::lfoout()
  99. {
  100. //update internals XXX TODO cleanup
  101. if ( ! lfopars_.time || lfopars_.last_update_timestamp == lfopars_.time->time())
  102. {
  103. waveShape = lfopars_.PLFOtype;
  104. int stretch = lfopars_.Pstretch;
  105. if(stretch == 0)
  106. stretch = 1;
  107. const float lfostretch = powf(basefreq_ / 440.0f, (stretch - 64.0f) / 63.0f);
  108. float lfofreq =
  109. (powf(2, lfopars_.Pfreq * 10.0f) - 1.0f) / 12.0f * lfostretch;
  110. phaseInc = fabs(lfofreq) * dt_;
  111. switch(lfopars_.fel) {
  112. case 1:
  113. lfointensity = lfopars_.Pintensity / 127.0f;
  114. break;
  115. case 2:
  116. lfointensity = lfopars_.Pintensity / 127.0f * 4.0f;
  117. break; //in octave
  118. default:
  119. lfointensity = powf(2, lfopars_.Pintensity / 127.0f * 11.0f) - 1.0f; //in centi
  120. //x -= 0.25f; //chance the starting phase
  121. break;
  122. }
  123. }
  124. float out = baseOut(waveShape, phase);
  125. if(waveShape == LFO_SINE || waveShape == LFO_TRIANGLE)
  126. out *= lfointensity * (amp1 + phase * (amp2 - amp1));
  127. else
  128. out *= lfointensity * amp2;
  129. if(delayTime.inFuture())
  130. return out;
  131. //Start oscillating
  132. if(deterministic)
  133. phase += phaseInc;
  134. else {
  135. const float tmp = (incrnd * (1.0f - phase) + nextincrnd * phase);
  136. phase += phaseInc * limit(tmp, 0.0f, 1.0f);
  137. }
  138. if(phase >= 1) {
  139. phase = fmod(phase, 1.0f);
  140. amp1 = amp2;
  141. amp2 = (1 - lfornd) + lfornd * RND;
  142. computeNextFreqRnd();
  143. }
  144. return out;
  145. }
  146. /*
  147. * LFO out (for amplitude)
  148. */
  149. float LFO::amplfoout()
  150. {
  151. return limit(1.0f - lfointensity + lfoout(), -1.0f, 1.0f);
  152. }
  153. void LFO::computeNextFreqRnd()
  154. {
  155. if(deterministic)
  156. return;
  157. incrnd = nextincrnd;
  158. nextincrnd = powf(0.5f, lfofreqrnd) + RND * (powf(2.0f, lfofreqrnd) - 1.0f);
  159. }