| 
							- #pragma once
 - 
 - #include <utility>
 - 
 - class PitchUtils
 - {
 - public:
 -     static constexpr float semitone = 1.f / 12.f;    // one semitone is a 1/12 volt
 -     static constexpr float octave = 1.f;
 -     static std::pair<int, int> cvToPitch(float cv);
 -     static int cvToSemitone(float cv);
 -     static float pitchToCV(int octave, int semi);
 -     static bool isAccidental(float cv);
 - };
 - 
 - inline std::pair<int, int> PitchUtils::cvToPitch(float cv)
 - {
 -      // VCV 0 is C4
 -     int octave = int(std::floor(cv));
 -     float remainder = cv - octave;
 -     octave += 4;
 -     float s = remainder * 12;
 -     int semi = int(std::round(s));
 -     return std::pair<int, int>(octave, semi);
 - }
 - 
 - inline  int PitchUtils::cvToSemitone(float cv)
 - {
 -     auto p = cvToPitch(cv);
 -     return p.first * 12 + p.second;
 - }
 - 
 - inline float PitchUtils::pitchToCV(int octave, int semi)
 - {
 -     return float(octave - 4) + semi * semitone;
 - }
 - 
 - inline bool PitchUtils::isAccidental(float cv)
 - {
 -     int semi = cvToPitch(cv).second;
 -     bool ret = false;
 -     switch (semi) {
 -         case 1:
 -         case 3:
 -         case 6:
 -         case 8:
 -         case 10:
 -             ret = true;
 -             break;
 -     }
 -     return ret;
 - }
 
 
  |