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.

68 lines
1.4KB

  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. class Diode
  8. {
  9. public:
  10. inline float operator() (float v)
  11. {
  12. float av = fabs(v);
  13. if (av <= m_vb)
  14. return 0.f;
  15. if (av <= m_vl)
  16. {
  17. const float v_minus_vb = av - m_vb;
  18. return m_h * v_minus_vb * v_minus_vb / m_vl_vb_denom;
  19. }
  20. return m_h * av - m_h_vl + m_vl_add;
  21. }
  22. inline void setVb(float newVb)
  23. {
  24. if (meta::updateIfDifferent(m_vb, newVb))
  25. {
  26. m_vl = m_vl_minus_vb + m_vb;
  27. m_vl_vb_denom = 2.f * (m_vl_minus_vb);
  28. m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  29. }
  30. }
  31. inline void setVlMinusVb(float newVlMinusVb)
  32. {
  33. if (meta::updateIfDifferent(m_vl_minus_vb, newVlMinusVb))
  34. {
  35. m_vl = m_vl_minus_vb + m_vb;
  36. m_vl_vb_denom = 2.f * (m_vl_minus_vb);
  37. m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  38. m_h_vl = m_h * m_vl;
  39. }
  40. }
  41. inline void setH(float newH)
  42. {
  43. if (meta::updateIfDifferent(m_h, newH))
  44. {
  45. m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  46. m_h_vl = m_h * m_vl;
  47. }
  48. }
  49. private:
  50. float m_vb = 0.2f; // diode forward-bias voltage
  51. float m_vl = 0.4f; // voltage beyond which the function is linear
  52. float m_h = 1.f; // slope of the linear section
  53. float m_vl_minus_vb = m_vl - m_vb;
  54. float m_vl_vb_denom = 2.f * (m_vl_minus_vb);
  55. float m_vl_add = m_h * m_vl_minus_vb * m_vl_minus_vb / m_vl_vb_denom;
  56. float m_h_vl = m_h * m_vl;
  57. };