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.

140 lines
4.6KB

  1. #include "SynthNote.h"
  2. #include "../globals.h"
  3. #include <cstring>
  4. SynthNote::SynthNote(SynthParams &pars)
  5. :memory(pars.memory),
  6. legato(pars.synth, pars.frequency, pars.velocity, pars.portamento,
  7. pars.note, pars.quiet), ctl(pars.ctl), synth(pars.synth), time(pars.time)
  8. {}
  9. SynthNote::Legato::Legato(const SYNTH_T &synth_, float freq, float vel, int port,
  10. int note, bool quiet)
  11. :synth(synth_)
  12. {
  13. // Initialise some legato-specific vars
  14. msg = LM_Norm;
  15. fade.length = (int)(synth.samplerate_f * 0.005f); // 0.005f seems ok.
  16. if(fade.length < 1)
  17. fade.length = 1; // (if something's fishy)
  18. fade.step = (1.0f / fade.length);
  19. decounter = -10;
  20. param.freq = freq;
  21. param.vel = vel;
  22. param.portamento = port;
  23. param.midinote = note;
  24. lastfreq = 0.0f;
  25. silent = quiet;
  26. }
  27. int SynthNote::Legato::update(LegatoParams pars)
  28. {
  29. if(pars.externcall)
  30. msg = LM_Norm;
  31. if(msg != LM_CatchUp) {
  32. lastfreq = param.freq;
  33. param.freq = pars.frequency;
  34. param.vel = pars.velocity;
  35. param.portamento = pars.portamento;
  36. param.midinote = pars.midinote;
  37. if(msg == LM_Norm) {
  38. if(silent) {
  39. fade.m = 0.0f;
  40. msg = LM_FadeIn;
  41. }
  42. else {
  43. fade.m = 1.0f;
  44. msg = LM_FadeOut;
  45. return 1;
  46. }
  47. }
  48. if(msg == LM_ToNorm)
  49. msg = LM_Norm;
  50. }
  51. return 0;
  52. }
  53. void SynthNote::Legato::apply(SynthNote &note, float *outl, float *outr)
  54. {
  55. if(silent) // Silencer
  56. if(msg != LM_FadeIn) {
  57. memset(outl, 0, synth.bufferbytes);
  58. memset(outr, 0, synth.bufferbytes);
  59. }
  60. switch(msg) {
  61. case LM_CatchUp: // Continue the catch-up...
  62. if(decounter == -10)
  63. decounter = fade.length;
  64. //Yea, could be done without the loop...
  65. for(int i = 0; i < synth.buffersize; ++i) {
  66. decounter--;
  67. if(decounter < 1) {
  68. // Catching-up done, we can finally set
  69. // the note to the actual parameters.
  70. decounter = -10;
  71. msg = LM_ToNorm;
  72. LegatoParams pars{param.freq, param.vel, param.portamento,
  73. param.midinote, false};
  74. note.legatonote(pars);
  75. break;
  76. }
  77. }
  78. break;
  79. case LM_FadeIn: // Fade-in
  80. if(decounter == -10)
  81. decounter = fade.length;
  82. silent = false;
  83. for(int i = 0; i < synth.buffersize; ++i) {
  84. decounter--;
  85. if(decounter < 1) {
  86. decounter = -10;
  87. msg = LM_Norm;
  88. break;
  89. }
  90. fade.m += fade.step;
  91. outl[i] *= fade.m;
  92. outr[i] *= fade.m;
  93. }
  94. break;
  95. case LM_FadeOut: // Fade-out, then set the catch-up
  96. if(decounter == -10)
  97. decounter = fade.length;
  98. for(int i = 0; i < synth.buffersize; ++i) {
  99. decounter--;
  100. if(decounter < 1) {
  101. for(int j = i; j < synth.buffersize; ++j) {
  102. outl[j] = 0.0f;
  103. outr[j] = 0.0f;
  104. }
  105. decounter = -10;
  106. silent = true;
  107. // Fading-out done, now set the catch-up :
  108. decounter = fade.length;
  109. msg = LM_CatchUp;
  110. //This freq should make this now silent note to catch-up/resync
  111. //with the heard note for the same length it stayed at the
  112. //previous freq during the fadeout.
  113. float catchupfreq = param.freq * (param.freq / lastfreq);
  114. LegatoParams pars{catchupfreq, param.vel, param.portamento,
  115. param.midinote, false};
  116. note.legatonote(pars);
  117. break;
  118. }
  119. fade.m -= fade.step;
  120. outl[i] *= fade.m;
  121. outr[i] *= fade.m;
  122. }
  123. break;
  124. default:
  125. break;
  126. }
  127. }
  128. void SynthNote::setVelocity(float velocity_) {
  129. legato.setSilent(true); //Let legato.update(...) returns 0.
  130. LegatoParams pars{legato.getFreq(), velocity_,
  131. legato.getPortamento(), legato.getMidinote(), true};
  132. legatonote(pars);
  133. legato.setDecounter(0); //avoid chopping sound due fade-in
  134. }