External plugins for 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.

166 lines
3.9KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. ModFilter.cpp - Modulated Filter
  4. Copyright (C) 2016 Mark McCurry
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. */
  10. #include "ModFilter.h"
  11. #include "Envelope.h"
  12. #include "LFO.h"
  13. #include "../Misc/Util.h"
  14. #include "../Misc/Allocator.h"
  15. #include "../Params/FilterParams.h"
  16. #include "../DSP/Filter.h"
  17. #include "../DSP/SVFilter.h"
  18. #include "../DSP/AnalogFilter.h"
  19. #include "../DSP/FormantFilter.h"
  20. #include <cassert>
  21. namespace zyncarla {
  22. ModFilter::ModFilter(const FilterParams &pars_,
  23. const SYNTH_T &synth_,
  24. const AbsTime &time_,
  25. Allocator &alloc_,
  26. bool stereo,
  27. float notefreq)
  28. :pars(pars_), synth(synth_), time(time_), alloc(alloc_),
  29. baseQ(pars.getq()), baseFreq(pars.getfreq()),
  30. noteFreq(notefreq),
  31. left(nullptr),
  32. right(nullptr),
  33. env(nullptr),
  34. lfo(nullptr)
  35. {
  36. tracking = pars.getfreqtracking(notefreq);
  37. baseQ = pars.getq();
  38. baseFreq = pars.getfreq();
  39. left = Filter::generate(alloc, &pars,
  40. synth.samplerate, synth.buffersize);
  41. if(stereo)
  42. right = Filter::generate(alloc, &pars,
  43. synth.samplerate, synth.buffersize);
  44. }
  45. ModFilter::~ModFilter(void)
  46. {
  47. alloc.dealloc(left);
  48. alloc.dealloc(right);
  49. }
  50. void ModFilter::addMod(LFO &lfo_)
  51. {
  52. lfo = &lfo_;
  53. }
  54. void ModFilter::addMod(Envelope &env_)
  55. {
  56. env = &env_;
  57. }
  58. //Recompute Filter Parameters
  59. void ModFilter::update(float relfreq, float relq)
  60. {
  61. if(pars.last_update_timestamp == time.time()) {
  62. paramUpdate(left);
  63. if(right)
  64. paramUpdate(right);
  65. baseFreq = pars.getfreq();
  66. baseQ = pars.getq();
  67. tracking = pars.getfreqtracking(noteFreq);
  68. }
  69. //Controller Free Center Frequency
  70. const float Fc = baseFreq
  71. + sense
  72. + (env ? env->envout() : 0)
  73. + (lfo ? lfo->lfoout() : 0);
  74. const float Fc_mod = Fc + relfreq + tracking;
  75. //Convert into Hz
  76. const float Fc_Hz = Filter::getrealfreq(Fc_mod);
  77. const float q = baseQ * relq;
  78. left->setfreq_and_q(Fc_Hz, q);
  79. if(right)
  80. right->setfreq_and_q(Fc_Hz, q);
  81. }
  82. void ModFilter::updateNoteFreq(float noteFreq_)
  83. {
  84. noteFreq = noteFreq_;
  85. tracking = pars.getfreqtracking(noteFreq);
  86. }
  87. void ModFilter::updateSense(float velocity, uint8_t scale,
  88. uint8_t func)
  89. {
  90. const float velScale = scale / 127.0f;
  91. sense = velScale * 6.0f * (VelF(velocity, func) - 1);
  92. }
  93. void ModFilter::filter(float *l, float *r)
  94. {
  95. if(left && l)
  96. left->filterout(l);
  97. if(right && r)
  98. right->filterout(r);
  99. }
  100. static int current_category(Filter *f)
  101. {
  102. if(dynamic_cast<AnalogFilter*>(f))
  103. return 0;
  104. else if(dynamic_cast<FormantFilter*>(f))
  105. return 1;
  106. else if(dynamic_cast<SVFilter*>(f))
  107. return 2;
  108. assert(false);
  109. return -1;
  110. }
  111. void ModFilter::paramUpdate(Filter *&f)
  112. {
  113. //Common parameters
  114. baseQ = pars.getq();
  115. baseFreq = pars.getfreq();
  116. if(current_category(f) != pars.Pcategory) {
  117. alloc.dealloc(f);
  118. f = Filter::generate(alloc, &pars,
  119. synth.samplerate, synth.buffersize);
  120. return;
  121. }
  122. if(auto *sv = dynamic_cast<SVFilter*>(f))
  123. svParamUpdate(*sv);
  124. else if(auto *an = dynamic_cast<AnalogFilter*>(f))
  125. anParamUpdate(*an);
  126. }
  127. void ModFilter::svParamUpdate(SVFilter &sv)
  128. {
  129. sv.settype(pars.Ptype);
  130. sv.setstages(pars.Pstages);
  131. }
  132. void ModFilter::anParamUpdate(AnalogFilter &an)
  133. {
  134. an.settype(pars.Ptype);
  135. an.setstages(pars.Pstages);
  136. an.setgain(pars.getgain());
  137. }
  138. }