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.

123 lines
3.4KB

  1. // Copyright 2015 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // Variable resolution quantizer.
  28. #ifndef MARBLES_RANDOM_QUANTIZER_H_
  29. #define MARBLES_RANDOM_QUANTIZER_H_
  30. #include "stmlib/stmlib.h"
  31. #include "stmlib/dsp/hysteresis_quantizer.h"
  32. #include "marbles/random/distributions.h"
  33. #include "marbles/random/quantizer.h"
  34. namespace marbles {
  35. const int kMaxDegrees = 16;
  36. const int kNumThresholds = 7;
  37. struct Degree {
  38. float voltage;
  39. uint8_t weight;
  40. };
  41. struct Scale {
  42. float base_interval;
  43. int num_degrees;
  44. Degree degree[kMaxDegrees];
  45. inline float cell_voltage(int i) const {
  46. float transposition = static_cast<float>(i / num_degrees) * base_interval;
  47. return degree[i % num_degrees].voltage + transposition;
  48. }
  49. void Init() {
  50. base_interval = 1.0f;
  51. num_degrees = 1;
  52. degree[0].voltage = 0.0f;
  53. degree[0].weight = 0.0f;
  54. }
  55. void InitMajor() {
  56. const uint8_t major_scale_weights[] = {
  57. 255, 16, 128, 16, 192, 64, 8, 224, 16, 96, 32, 160,
  58. };
  59. base_interval = 1.0f;
  60. num_degrees = 12;
  61. for (size_t i = 0; i < 12; ++i) {
  62. degree[i].voltage = static_cast<float>(i) * 0.0833333333f;
  63. degree[i].weight = major_scale_weights[i];
  64. }
  65. }
  66. void InitTenth() {
  67. const uint8_t major_scale_weights[] = {
  68. 255, 255, 255, 255, 255, 255, 255, 255, 255, 25
  69. };
  70. base_interval = 1.0f;
  71. num_degrees = 10;
  72. for (size_t i = 0; i < 10; ++i) {
  73. degree[i].voltage = static_cast<float>(i) * 0.1f;
  74. degree[i].weight = major_scale_weights[i];
  75. }
  76. }
  77. };
  78. class Quantizer {
  79. public:
  80. Quantizer() { }
  81. ~Quantizer() { }
  82. void Init(const Scale& scale);
  83. float Process(float value, float amount, bool hysteresis);
  84. private:
  85. struct Level {
  86. uint16_t bitmask; // bitmask of active degrees.
  87. uint8_t first; // index of the first active degree.
  88. uint8_t last; // index of the last active degree.
  89. };
  90. float voltage_[kMaxDegrees];
  91. Level level_[kNumThresholds];
  92. float feedback_[kNumThresholds];
  93. float base_interval_;
  94. float base_interval_reciprocal_;
  95. int num_degrees_;
  96. stmlib::HysteresisQuantizer level_quantizer_;
  97. DISALLOW_COPY_AND_ASSIGN(Quantizer);
  98. };
  99. } // namespace marbles
  100. #endif // MARBLES_RANDOM_QUANTIZER_H_