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.

167 lines
6.1KB

  1. #include "rack.hpp"
  2. namespace rack_plugin_JW_Modules {
  3. struct QuantizeUtils {
  4. //copied & fixed these scales http://www.grantmuller.com/MidiReference/doc/midiReference/ScaleReference.html
  5. int SCALE_AEOLIAN [7] = {0, 2, 3, 5, 7, 8, 10};
  6. int SCALE_BLUES [6] = {0, 3, 5, 6, 7, 10}; //FIXED!
  7. int SCALE_CHROMATIC [12]= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
  8. int SCALE_DIATONIC_MINOR [7] = {0, 2, 3, 5, 7, 8, 10};
  9. int SCALE_DORIAN [7] = {0, 2, 3, 5, 7, 9, 10};
  10. int SCALE_HARMONIC_MINOR [7] = {0, 2, 3, 5, 7, 8, 11};
  11. int SCALE_INDIAN [7] = {0, 1, 1, 4, 5, 8, 10};
  12. int SCALE_LOCRIAN [7] = {0, 1, 3, 5, 6, 8, 10};
  13. int SCALE_LYDIAN [7] = {0, 2, 4, 6, 7, 9, 10};
  14. int SCALE_MAJOR [7] = {0, 2, 4, 5, 7, 9, 11};
  15. int SCALE_MELODIC_MINOR [9] = {0, 2, 3, 5, 7, 8, 9, 10, 11};
  16. int SCALE_MINOR [7] = {0, 2, 3, 5, 7, 8, 10};
  17. int SCALE_MIXOLYDIAN [7] = {0, 2, 4, 5, 7, 9, 10};
  18. int SCALE_NATURAL_MINOR [7] = {0, 2, 3, 5, 7, 8, 10};
  19. int SCALE_PENTATONIC [5] = {0, 2, 4, 7, 9};
  20. int SCALE_PHRYGIAN [7] = {0, 1, 3, 5, 7, 8, 10};
  21. int SCALE_TURKISH [7] = {0, 1, 3, 5, 7, 10, 11};
  22. enum NoteEnum {
  23. NOTE_C,
  24. NOTE_C_SHARP,
  25. NOTE_D,
  26. NOTE_D_SHARP,
  27. NOTE_E,
  28. NOTE_F,
  29. NOTE_F_SHARP,
  30. NOTE_G,
  31. NOTE_G_SHARP,
  32. NOTE_A,
  33. NOTE_A_SHARP,
  34. NOTE_B,
  35. NUM_NOTES
  36. };
  37. enum ScaleEnum {
  38. AEOLIAN,
  39. BLUES,
  40. CHROMATIC,
  41. DIATONIC_MINOR,
  42. DORIAN,
  43. HARMONIC_MINOR,
  44. INDIAN,
  45. LOCRIAN,
  46. LYDIAN,
  47. MAJOR,
  48. MELODIC_MINOR,
  49. MINOR,
  50. MIXOLYDIAN,
  51. NATURAL_MINOR,
  52. PENTATONIC,
  53. PHRYGIAN,
  54. TURKISH,
  55. NONE,
  56. NUM_SCALES
  57. };
  58. // long printIter = 0;
  59. float closestVoltageInScale(float voltsIn, int rootNote, int currScale){
  60. int *curScaleArr;
  61. int notesInScale = 0;
  62. switch(currScale){
  63. case AEOLIAN: curScaleArr = SCALE_AEOLIAN; notesInScale=LENGTHOF(SCALE_AEOLIAN); break;
  64. case BLUES: curScaleArr = SCALE_BLUES; notesInScale=LENGTHOF(SCALE_BLUES); break;
  65. case CHROMATIC: curScaleArr = SCALE_CHROMATIC; notesInScale=LENGTHOF(SCALE_CHROMATIC); break;
  66. case DIATONIC_MINOR: curScaleArr = SCALE_DIATONIC_MINOR;notesInScale=LENGTHOF(SCALE_DIATONIC_MINOR); break;
  67. case DORIAN: curScaleArr = SCALE_DORIAN; notesInScale=LENGTHOF(SCALE_DORIAN); break;
  68. case HARMONIC_MINOR: curScaleArr = SCALE_HARMONIC_MINOR;notesInScale=LENGTHOF(SCALE_HARMONIC_MINOR); break;
  69. case INDIAN: curScaleArr = SCALE_INDIAN; notesInScale=LENGTHOF(SCALE_INDIAN); break;
  70. case LOCRIAN: curScaleArr = SCALE_LOCRIAN; notesInScale=LENGTHOF(SCALE_LOCRIAN); break;
  71. case LYDIAN: curScaleArr = SCALE_LYDIAN; notesInScale=LENGTHOF(SCALE_LYDIAN); break;
  72. case MAJOR: curScaleArr = SCALE_MAJOR; notesInScale=LENGTHOF(SCALE_MAJOR); break;
  73. case MELODIC_MINOR: curScaleArr = SCALE_MELODIC_MINOR; notesInScale=LENGTHOF(SCALE_MELODIC_MINOR); break;
  74. case MINOR: curScaleArr = SCALE_MINOR; notesInScale=LENGTHOF(SCALE_MINOR); break;
  75. case MIXOLYDIAN: curScaleArr = SCALE_MIXOLYDIAN; notesInScale=LENGTHOF(SCALE_MIXOLYDIAN); break;
  76. case NATURAL_MINOR: curScaleArr = SCALE_NATURAL_MINOR; notesInScale=LENGTHOF(SCALE_NATURAL_MINOR); break;
  77. case PENTATONIC: curScaleArr = SCALE_PENTATONIC; notesInScale=LENGTHOF(SCALE_PENTATONIC); break;
  78. case PHRYGIAN: curScaleArr = SCALE_PHRYGIAN; notesInScale=LENGTHOF(SCALE_PHRYGIAN); break;
  79. case TURKISH: curScaleArr = SCALE_TURKISH; notesInScale=LENGTHOF(SCALE_TURKISH); break;
  80. case NONE: return voltsIn;
  81. }
  82. //C1 == -2.00, C2 == -1.00, C3 == 0.00, C4 == 1.00
  83. //B1 == -1.08, B2 == -0.08, B3 == 0.92, B4 == 1.92
  84. float closestVal = 10.0;
  85. float closestDist = 10.0;
  86. float scaleNoteInVolts = 0;
  87. float distAway = 0;
  88. int octaveInVolts = int(floorf(voltsIn));
  89. float voltMinusOct = voltsIn - octaveInVolts;
  90. // int nextOctaveInVolts = (octaveInVolts + 1) * inverseMult; // If I decide to round to the next octave.
  91. for (int i=0; i < notesInScale; i++) {
  92. scaleNoteInVolts = curScaleArr[i] / 12.0;
  93. distAway = fabs(voltMinusOct - scaleNoteInVolts);
  94. if(distAway < closestDist){
  95. closestVal = scaleNoteInVolts;
  96. closestDist = distAway;
  97. }
  98. // If I decide to round to the next octave. (Ableton does NOT do this in their scale midi effect)
  99. // float distToNextOct = fabs(nextOctaveInVolts - voltsIn);
  100. // if(distToNextOct < closestDist){
  101. // closestVal = nextOctaveInVolts;
  102. // closestDist = distToNextOct;
  103. // }
  104. // if(printIter%100000==0){
  105. // printf("i:%i, rootNote:%i, voltsIn:%f, octaveInVolts:%i, closestVal:%f, closestDist:%f\n",
  106. // i, rootNote, voltsIn, octaveInVolts, closestVal, closestDist);
  107. // printIter = 0;
  108. // }
  109. }
  110. // printIter++;
  111. return octaveInVolts + rootNote/12.0 + closestVal;
  112. }
  113. std::string noteName(int note) {
  114. switch(note){
  115. case NOTE_C: return "C";
  116. case NOTE_C_SHARP: return "C#";
  117. case NOTE_D: return "D";
  118. case NOTE_D_SHARP: return "D#";
  119. case NOTE_E: return "E";
  120. case NOTE_F: return "F";
  121. case NOTE_F_SHARP: return "F#";
  122. case NOTE_G: return "G";
  123. case NOTE_G_SHARP: return "G#";
  124. case NOTE_A: return "A";
  125. case NOTE_A_SHARP: return "A#";
  126. case NOTE_B: return "B";
  127. default: return "";
  128. }
  129. }
  130. std::string scaleName(int scale) {
  131. switch(scale){
  132. case AEOLIAN: return "Aeolian";
  133. case BLUES: return "Blues";
  134. case CHROMATIC: return "Chromat";
  135. case DIATONIC_MINOR: return "Diat Min";
  136. case DORIAN: return "Dorian";
  137. case HARMONIC_MINOR: return "Harm Min";
  138. case INDIAN: return "Indian";
  139. case LOCRIAN: return "Locrian";
  140. case LYDIAN: return "Lydian";
  141. case MAJOR: return "Major";
  142. case MELODIC_MINOR: return "Mel Min";
  143. case MINOR: return "Minor";
  144. case MIXOLYDIAN: return "Mixolyd";
  145. case NATURAL_MINOR: return "Nat Min";
  146. case PENTATONIC: return "Penta";
  147. case PHRYGIAN: return "Phrygian";
  148. case TURKISH: return "Turkish";
  149. case NONE: return "None";
  150. default: return "";
  151. }
  152. }
  153. };
  154. } // namespace rack_plugin_JW_Modules