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.

210 lines
6.0KB

  1. // Copyright 2013 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. // CV scaling functions.
  28. #ifndef TIDES_CV_SCALER_H_
  29. #define TIDES_CV_SCALER_H_
  30. #include "stmlib/stmlib.h"
  31. #include "stmlib/utils/dsp.h"
  32. #include "tides/resources.h"
  33. namespace tides {
  34. const int16_t kOctave = 12 * 128;
  35. #define SE * 128
  36. const uint16_t quantize_lut[7][12] = {
  37. /* semitones */
  38. {0, 1 SE, 2 SE, 3 SE, 4 SE, 5 SE, 6 SE, 7 SE, 8 SE, 9 SE, 10 SE, 11 SE},
  39. /* ionian */
  40. {0, 0, 2 SE, 2 SE, 4 SE, 5 SE, 5 SE, 7 SE, 7 SE, 9 SE, 9 SE, 11 SE},
  41. /* aeolian */
  42. {0, 0, 2 SE, 3 SE, 3 SE, 5 SE, 5 SE, 7 SE, 8 SE, 8 SE, 10 SE, 10 SE},
  43. /* whole tones */
  44. {0, 0, 2 SE, 2 SE, 4 SE, 4 SE, 6 SE, 6 SE, 8 SE, 8 SE, 10 SE, 10 SE},
  45. /* pentatonic minor */
  46. {0, 0, 3 SE, 3 SE, 3 SE, 5 SE, 5 SE, 7 SE, 7 SE, 10 SE, 10 SE, 10 SE},
  47. /* pent-3 */
  48. {0, 0, 0, 0, 7 SE, 7 SE, 7 SE, 7 SE, 10 SE, 10 SE, 10 SE, 10 SE},
  49. /* fifths */
  50. {0, 0, 0, 0, 0, 0, 7 SE, 7 SE, 7 SE, 7 SE, 7 SE, 7 SE},
  51. };
  52. enum AdcChannel {
  53. ADC_CHANNEL_LEVEL,
  54. ADC_CHANNEL_V_OCT,
  55. ADC_CHANNEL_FM,
  56. ADC_CHANNEL_FM_ATTENUVERTER,
  57. ADC_CHANNEL_SHAPE,
  58. ADC_CHANNEL_SLOPE,
  59. ADC_CHANNEL_SMOOTHNESS,
  60. ADC_CHANNEL_LAST
  61. };
  62. class CvScaler {
  63. public:
  64. struct CalibrationData {
  65. int32_t level_offset;
  66. int32_t v_oct_offset;
  67. int32_t v_oct_scale;
  68. int32_t fm_offset;
  69. int32_t fm_scale;
  70. int32_t padding[3];
  71. };
  72. CvScaler() { }
  73. ~CvScaler() { }
  74. void Init();
  75. inline void ProcessSampleRate(const uint16_t* raw_adc_data) {
  76. level_raw_ = (level_raw_ * 15 + raw_adc_data[ADC_CHANNEL_LEVEL]) >> 4;
  77. level_ = -level_raw_ + calibration_data_.level_offset;
  78. if (level_ < 32) { // 2 LSB of ADC noise.
  79. level_ = 0;
  80. }
  81. }
  82. inline void ProcessControlRate(const uint16_t* raw_adc_data) {
  83. int32_t scaled_value;
  84. scaled_value = 32767 - static_cast<int32_t>(
  85. raw_adc_data[ADC_CHANNEL_SHAPE]);
  86. shape_ = (shape_ * 7 + scaled_value) >> 3;
  87. scaled_value = 32767 - static_cast<int32_t>(
  88. raw_adc_data[ADC_CHANNEL_SLOPE]);
  89. slope_ = (slope_ * 7 + scaled_value) >> 3;
  90. scaled_value = 32767 - static_cast<int32_t>(
  91. raw_adc_data[ADC_CHANNEL_SMOOTHNESS]);
  92. smoothness_ = (smoothness_ * 7 + scaled_value) >> 3;
  93. scaled_value = static_cast<int32_t>(raw_adc_data[ADC_CHANNEL_V_OCT]);
  94. v_oct_ = (v_oct_ * 3 + scaled_value) >> 2;
  95. scaled_value = static_cast<int32_t>(raw_adc_data[ADC_CHANNEL_FM]);
  96. fm_ = (fm_ * 3 + scaled_value) >> 2;
  97. scaled_value = static_cast<int32_t>(
  98. raw_adc_data[ADC_CHANNEL_FM_ATTENUVERTER]);
  99. attenuverter_ = (attenuverter_ * 15 + scaled_value) >> 4;
  100. }
  101. inline uint16_t level() const { return level_; }
  102. inline int16_t shape() const { return shape_; }
  103. inline int16_t slope() const { return slope_; }
  104. inline int16_t smoothness() const { return smoothness_; }
  105. inline int16_t pitch() {
  106. if (quantize_) {
  107. // Apply hysteresis and filtering to ADC reading to prevent
  108. // jittery quantization.
  109. if ((v_oct_ > previous_v_oct_ + 16) ||
  110. (v_oct_ < previous_v_oct_ - 16)) {
  111. previous_v_oct_ = v_oct_;
  112. } else {
  113. previous_v_oct_ += (v_oct_ - previous_v_oct_) >> 5;
  114. v_oct_ = previous_v_oct_;
  115. }
  116. }
  117. int32_t pitch = (v_oct_ - calibration_data_.v_oct_offset) * \
  118. calibration_data_.v_oct_scale >> 15;
  119. pitch += 60 << 7;
  120. if (quantize_) {
  121. uint16_t semi = pitch >> 7;
  122. uint16_t octaves = semi / 12 ;
  123. semi -= octaves * 12;
  124. pitch = octaves * kOctave +
  125. quantize_lut[quantize_ - 1][semi];
  126. }
  127. return pitch;
  128. }
  129. inline int16_t fm() {
  130. int32_t attenuverter_value = attenuverter_ - 32768;
  131. int32_t attenuverter_sign = 1;
  132. if (attenuverter_value < 0) {
  133. attenuverter_value = -attenuverter_value - 1;
  134. attenuverter_sign = - 1;
  135. }
  136. attenuverter_value = attenuverter_sign * static_cast<int32_t>(
  137. stmlib::Interpolate88(lut_attenuverter_curve, attenuverter_value << 1));
  138. int32_t fm = (fm_ - calibration_data_.fm_offset) * \
  139. calibration_data_.fm_scale >> 15;
  140. fm = fm * attenuverter_value >> 16;
  141. return fm;
  142. }
  143. inline uint16_t raw_attenuverter() const { return attenuverter_; }
  144. void CaptureCalibrationValues() {
  145. v_oct_c2_ = v_oct_;
  146. }
  147. void Calibrate();
  148. inline bool can_enter_calibration() const {
  149. return level_raw_ >= 49152;
  150. }
  151. uint8_t quantize_;
  152. private:
  153. void SaveCalibrationData();
  154. CalibrationData calibration_data_;
  155. int32_t level_raw_;
  156. int32_t level_;
  157. int32_t v_oct_;
  158. int32_t previous_v_oct_;
  159. int32_t fm_;
  160. int32_t attenuverter_;
  161. int32_t shape_;
  162. int32_t slope_;
  163. int32_t smoothness_;
  164. int32_t v_oct_c2_;
  165. static const CalibrationData init_calibration_data_;
  166. uint16_t version_token_;
  167. DISALLOW_COPY_AND_ASSIGN(CvScaler);
  168. };
  169. } // namespace tides
  170. #endif // TIDES_CV_SCALER_H_