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.

SynthNote.cpp 4.5KB

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