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.

226 lines
6.2KB

  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. // Filtering and scaling of ADC values + input calibration.
  28. #ifndef RINGS_CV_SCALER_H_
  29. #define RINGS_CV_SCALER_H_
  30. #include "stmlib/stmlib.h"
  31. #include "rings/drivers/adc.h"
  32. #include "rings/drivers/codec.h"
  33. #include "rings/drivers/normalization_probe.h"
  34. #include "rings/drivers/trigger_input.h"
  35. #include "rings/settings.h"
  36. namespace rings {
  37. enum Law {
  38. LAW_LINEAR,
  39. LAW_QUADRATIC_BIPOLAR,
  40. LAW_QUARTIC_BIPOLAR
  41. };
  42. struct ChannelSettings {
  43. Law law;
  44. bool remove_offset;
  45. float lp_coefficient;
  46. };
  47. struct Patch;
  48. struct PerformanceState;
  49. class NormalizationDetector {
  50. public:
  51. NormalizationDetector() { }
  52. ~NormalizationDetector() { }
  53. void Init(float lp_coefficient, float threshold) {
  54. score_ = 0.0f;
  55. state_ = false;
  56. threshold_ = threshold;
  57. lp_coefficient_ = lp_coefficient;
  58. }
  59. void Process(float x, float y) {
  60. // x is supposed to be centered!
  61. score_ += lp_coefficient_ * (x * y - score_);
  62. float hysteresis = state_ ? -0.05f * threshold_ : 0.0f;
  63. state_ = score_ >= (threshold_ + hysteresis);
  64. }
  65. inline bool normalized() const { return state_; }
  66. inline float score() const { return score_; }
  67. private:
  68. float score_;
  69. float lp_coefficient_;
  70. float threshold_;
  71. bool state_;
  72. DISALLOW_COPY_AND_ASSIGN(NormalizationDetector);
  73. };
  74. class CvScaler {
  75. public:
  76. CvScaler() { }
  77. ~CvScaler() { }
  78. void Init(CalibrationData* calibration_data);
  79. void Read(Patch* patch, PerformanceState* performance_state);
  80. void DetectAudioNormalization(Codec::Frame* in, size_t size);
  81. inline bool ready_for_calibration() const {
  82. return true;
  83. }
  84. inline bool easter_egg() const {
  85. return adc_lp_[ADC_CHANNEL_POT_FREQUENCY] < 0.1f &&
  86. adc_lp_[ADC_CHANNEL_POT_STRUCTURE] > 0.9f &&
  87. adc_lp_[ADC_CHANNEL_POT_BRIGHTNESS] < 0.1f &&
  88. adc_lp_[ADC_CHANNEL_POT_POSITION] > 0.9f &&
  89. adc_lp_[ADC_CHANNEL_POT_DAMPING] > 0.4f &&
  90. adc_lp_[ADC_CHANNEL_POT_DAMPING] < 0.6f &&
  91. adc_lp_[ADC_CHANNEL_ATTENUVERTER_BRIGHTNESS] < -1.00f &&
  92. adc_lp_[ADC_CHANNEL_ATTENUVERTER_FREQUENCY] > 1.00f &&
  93. adc_lp_[ADC_CHANNEL_ATTENUVERTER_DAMPING] < -1.00f &&
  94. adc_lp_[ADC_CHANNEL_ATTENUVERTER_STRUCTURE] > 1.00f &&
  95. adc_lp_[ADC_CHANNEL_ATTENUVERTER_POSITION] < -1.00f;
  96. }
  97. inline void CalibrateC1() {
  98. cv_c1_ = adc_.float_value(ADC_CHANNEL_CV_V_OCT);
  99. }
  100. inline void CalibrateOffsets() {
  101. for (size_t i = 0; i < ADC_CHANNEL_NUM_OFFSETS; ++i) {
  102. calibration_data_->offset[i] = adc_.float_value(i);
  103. }
  104. }
  105. inline bool CalibrateC3() {
  106. float c3 = adc_.float_value(ADC_CHANNEL_CV_V_OCT); // 0.3640 v0.2
  107. float c1 = cv_c1_; // 0.6488 v0.2
  108. float delta = c3 - c1;
  109. if (delta > -0.4f && delta < -0.1f) {
  110. calibration_data_->pitch_scale = 24.0f / (c3 - c1);
  111. calibration_data_->pitch_offset = 12.0f - \
  112. calibration_data_->pitch_scale * c1;
  113. return true;
  114. }
  115. normalization_probe_enabled_ = true;
  116. return false;
  117. }
  118. inline void StartNormalizationCalibration() {
  119. normalization_probe_enabled_ = false;
  120. normalization_probe_forced_state_ = false;
  121. }
  122. inline void CalibrateLow() {
  123. cv_low_ = adc_.float_value(ADC_CHANNEL_CV_V_OCT);
  124. normalization_probe_forced_state_ = true;
  125. }
  126. inline bool CalibrateHigh() {
  127. float threshold = (cv_low_ + adc_.float_value(ADC_CHANNEL_CV_V_OCT)) * 0.5f;
  128. bool within_range = threshold >= 0.7f && threshold < 0.8f;
  129. if (within_range) {
  130. calibration_data_->normalization_detection_threshold = threshold;
  131. }
  132. normalization_probe_enabled_ = true;
  133. return within_range;
  134. }
  135. inline uint8_t adc_value(size_t index) const {
  136. return adc_.value(index) >> 8;
  137. }
  138. inline bool gate_value() const {
  139. return trigger_input_.value();
  140. }
  141. inline uint8_t normalization(size_t index) const {
  142. switch (index) {
  143. case 0:
  144. return fm_cv_ * 3.3f > 0.8f ? 255 : 0;
  145. break;
  146. case 1:
  147. return normalization_detector_trigger_.normalized() ? 255 : 0;
  148. break;
  149. case 2:
  150. return normalization_detector_v_oct_.normalized() ? 255 : 0;
  151. break;
  152. default:
  153. return normalization_detector_exciter_.normalized() ? 255 : 0;
  154. break;
  155. }
  156. }
  157. private:
  158. void DetectNormalization();
  159. Adc adc_;
  160. CalibrationData* calibration_data_;
  161. TriggerInput trigger_input_;
  162. NormalizationProbe normalization_probe_;
  163. NormalizationDetector normalization_detector_trigger_;
  164. NormalizationDetector normalization_detector_v_oct_;
  165. NormalizationDetector normalization_detector_exciter_;
  166. bool normalization_probe_value_[2];
  167. int32_t inhibit_strum_;
  168. float adc_lp_[ADC_CHANNEL_LAST];
  169. float transpose_;
  170. float fm_cv_;
  171. float cv_c1_;
  172. float cv_low_;
  173. int32_t chord_;
  174. bool normalization_probe_enabled_;
  175. bool normalization_probe_forced_state_;
  176. static ChannelSettings channel_settings_[ADC_CHANNEL_LAST];
  177. DISALLOW_COPY_AND_ASSIGN(CvScaler);
  178. };
  179. } // namespace rings
  180. #endif // RINGS_CV_SCALER_H_