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.

144 lines
3.7KB

  1. /* Copyright 2016, Ableton AG, Berlin. All rights reserved.
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * If you would like to incorporate Link into a proprietary software application,
  17. * please contact <link-devs@ableton.com>.
  18. */
  19. #pragma once
  20. #include <array>
  21. #include <cfloat>
  22. #include <cmath>
  23. namespace ableton
  24. {
  25. namespace link
  26. {
  27. template <std::size_t n>
  28. struct Kalman
  29. {
  30. Kalman()
  31. : mValue(0)
  32. , mCoVariance(1)
  33. , mVarianceLength(n)
  34. , mCounter(mVarianceLength)
  35. {
  36. }
  37. double getValue()
  38. {
  39. return mValue;
  40. }
  41. double calculateVVariance()
  42. {
  43. auto vVar = 0.;
  44. auto meanOfDiffs = 0.;
  45. for (size_t k = 0; k < (mVarianceLength); k++)
  46. {
  47. meanOfDiffs += (mMeasuredValues[k] - mFilterValues[k]);
  48. }
  49. meanOfDiffs /= (mVarianceLength);
  50. for (size_t i = 0; i < (mVarianceLength); i++)
  51. {
  52. vVar += (pow(mMeasuredValues[i] - mFilterValues[i] - meanOfDiffs, 2.0));
  53. }
  54. vVar /= (mVarianceLength - 1);
  55. return vVar;
  56. }
  57. double calculateWVariance()
  58. {
  59. auto wVar = 0.;
  60. auto meanOfDiffs = 0.;
  61. for (size_t k = 0; k < (mVarianceLength); k++)
  62. {
  63. meanOfDiffs += (mFilterValues[(mCounter - k - 1) % mVarianceLength]
  64. - mFilterValues[(mCounter - k - 2) % mVarianceLength]);
  65. }
  66. meanOfDiffs /= (mVarianceLength);
  67. for (size_t i = 0; i < (mVarianceLength); i++)
  68. {
  69. wVar += (pow(mFilterValues[(mCounter - i - 1) % mVarianceLength]
  70. - mFilterValues[(mCounter - i - 2) % mVarianceLength] - meanOfDiffs,
  71. 2.0));
  72. }
  73. wVar /= (mVarianceLength - 1);
  74. return wVar;
  75. }
  76. void iterate(const double value)
  77. {
  78. const std::size_t currentIndex = mCounter % mVarianceLength;
  79. mMeasuredValues[currentIndex] = value;
  80. if (mCounter < (mVarianceLength + mVarianceLength))
  81. {
  82. if (mCounter == mVarianceLength)
  83. {
  84. mValue = value;
  85. }
  86. else
  87. {
  88. mValue = (mValue + value) / 2;
  89. }
  90. }
  91. else
  92. {
  93. // prediction equations
  94. const double prevFilterValue = mFilterValues[(mCounter - 1) % mVarianceLength];
  95. mFilterValues[currentIndex] = prevFilterValue;
  96. const auto wVariance = calculateWVariance();
  97. const double coVarianceEstimation = mCoVariance + wVariance;
  98. // update equations
  99. const auto vVariance = calculateVVariance();
  100. // Gain defines how easily the filter will adjust to a new condition
  101. // With gain = 1 the output equals the input, with gain = 0 the input
  102. // is ignored and the output equals the last filtered value
  103. const auto divisor = coVarianceEstimation + vVariance;
  104. const auto gain = divisor != 0. ? coVarianceEstimation / divisor : 0.7;
  105. mValue = prevFilterValue + gain * (value - prevFilterValue);
  106. mCoVariance = (1 - gain) * coVarianceEstimation;
  107. }
  108. mFilterValues[currentIndex] = mValue;
  109. ++mCounter;
  110. }
  111. double mValue;
  112. double mCoVariance;
  113. size_t mVarianceLength;
  114. size_t mCounter;
  115. std::array<double, n> mFilterValues;
  116. std::array<double, n> mMeasuredValues;
  117. };
  118. } // namespace link
  119. } // namespace ableton