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.

72 lines
1.5KB

  1. #pragma once
  2. #include "../utils/meta.hpp"
  3. #include "../common/constants.hpp"
  4. /*
  5. http://recherche.ircam.fr/pub/dafx11/Papers/66_e.pdf
  6. */
  7. namespace rack_plugin_JE {
  8. class Diode
  9. {
  10. public:
  11. inline float operator() (float v)
  12. {
  13. float av = fabs(v);
  14. if (av <= m_vb)
  15. return 0.f;
  16. if (av <= m_vl)
  17. {
  18. const float v_minus_vb = av - m_vb;
  19. return m_h * v_minus_vb * v_minus_vb / m_vl_vb_denom;
  20. }
  21. return m_h * av - m_h_vl + m_vl_add;
  22. }
  23. inline void setVb(float newVb)
  24. {
  25. if (meta::updateIfDifferent(m_vb, newVb))
  26. {
  27. m_vl = m_vl_minus_vb + m_vb;
  28. m_vl_vb_denom = 2.f * (m_vl_minus_vb);
  29. m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  30. }
  31. }
  32. inline void setVlMinusVb(float newVlMinusVb)
  33. {
  34. if (meta::updateIfDifferent(m_vl_minus_vb, newVlMinusVb))
  35. {
  36. m_vl = m_vl_minus_vb + m_vb;
  37. m_vl_vb_denom = 2.f * (m_vl_minus_vb);
  38. m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  39. m_h_vl = m_h * m_vl;
  40. }
  41. }
  42. inline void setH(float newH)
  43. {
  44. if (meta::updateIfDifferent(m_h, newH))
  45. {
  46. m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  47. m_h_vl = m_h * m_vl;
  48. }
  49. }
  50. private:
  51. float m_vb = 0.2f; // diode forward-bias voltage
  52. float m_vl = 0.4f; // voltage beyond which the function is linear
  53. float m_h = 1.f; // slope of the linear section
  54. float m_vl_minus_vb = m_vl - m_vb;
  55. float m_vl_vb_denom = 2.f * (m_vl_minus_vb);
  56. float m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  57. float m_h_vl = m_h * m_vl;
  58. };
  59. } // namespace rack_plugin_JE