|
- #include "rack.hpp"
-
- namespace rack_plugin_JW_Modules {
-
- struct QuantizeUtils {
-
- //copied & fixed these scales http://www.grantmuller.com/MidiReference/doc/midiReference/ScaleReference.html
- int SCALE_AEOLIAN [7] = {0, 2, 3, 5, 7, 8, 10};
- int SCALE_BLUES [6] = {0, 3, 5, 6, 7, 10}; //FIXED!
- int SCALE_CHROMATIC [12]= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
- int SCALE_DIATONIC_MINOR [7] = {0, 2, 3, 5, 7, 8, 10};
- int SCALE_DORIAN [7] = {0, 2, 3, 5, 7, 9, 10};
- int SCALE_HARMONIC_MINOR [7] = {0, 2, 3, 5, 7, 8, 11};
- int SCALE_INDIAN [7] = {0, 1, 1, 4, 5, 8, 10};
- int SCALE_LOCRIAN [7] = {0, 1, 3, 5, 6, 8, 10};
- int SCALE_LYDIAN [7] = {0, 2, 4, 6, 7, 9, 10};
- int SCALE_MAJOR [7] = {0, 2, 4, 5, 7, 9, 11};
- int SCALE_MELODIC_MINOR [9] = {0, 2, 3, 5, 7, 8, 9, 10, 11};
- int SCALE_MINOR [7] = {0, 2, 3, 5, 7, 8, 10};
- int SCALE_MIXOLYDIAN [7] = {0, 2, 4, 5, 7, 9, 10};
- int SCALE_NATURAL_MINOR [7] = {0, 2, 3, 5, 7, 8, 10};
- int SCALE_PENTATONIC [5] = {0, 2, 4, 7, 9};
- int SCALE_PHRYGIAN [7] = {0, 1, 3, 5, 7, 8, 10};
- int SCALE_TURKISH [7] = {0, 1, 3, 5, 7, 10, 11};
-
- enum NoteEnum {
- NOTE_C,
- NOTE_C_SHARP,
- NOTE_D,
- NOTE_D_SHARP,
- NOTE_E,
- NOTE_F,
- NOTE_F_SHARP,
- NOTE_G,
- NOTE_G_SHARP,
- NOTE_A,
- NOTE_A_SHARP,
- NOTE_B,
- NUM_NOTES
- };
-
- enum ScaleEnum {
- AEOLIAN,
- BLUES,
- CHROMATIC,
- DIATONIC_MINOR,
- DORIAN,
- HARMONIC_MINOR,
- INDIAN,
- LOCRIAN,
- LYDIAN,
- MAJOR,
- MELODIC_MINOR,
- MINOR,
- MIXOLYDIAN,
- NATURAL_MINOR,
- PENTATONIC,
- PHRYGIAN,
- TURKISH,
- NONE,
- NUM_SCALES
- };
-
- // long printIter = 0;
- float closestVoltageInScale(float voltsIn, int rootNote, int currScale){
- int *curScaleArr;
- int notesInScale = 0;
- switch(currScale){
- case AEOLIAN: curScaleArr = SCALE_AEOLIAN; notesInScale=LENGTHOF(SCALE_AEOLIAN); break;
- case BLUES: curScaleArr = SCALE_BLUES; notesInScale=LENGTHOF(SCALE_BLUES); break;
- case CHROMATIC: curScaleArr = SCALE_CHROMATIC; notesInScale=LENGTHOF(SCALE_CHROMATIC); break;
- case DIATONIC_MINOR: curScaleArr = SCALE_DIATONIC_MINOR;notesInScale=LENGTHOF(SCALE_DIATONIC_MINOR); break;
- case DORIAN: curScaleArr = SCALE_DORIAN; notesInScale=LENGTHOF(SCALE_DORIAN); break;
- case HARMONIC_MINOR: curScaleArr = SCALE_HARMONIC_MINOR;notesInScale=LENGTHOF(SCALE_HARMONIC_MINOR); break;
- case INDIAN: curScaleArr = SCALE_INDIAN; notesInScale=LENGTHOF(SCALE_INDIAN); break;
- case LOCRIAN: curScaleArr = SCALE_LOCRIAN; notesInScale=LENGTHOF(SCALE_LOCRIAN); break;
- case LYDIAN: curScaleArr = SCALE_LYDIAN; notesInScale=LENGTHOF(SCALE_LYDIAN); break;
- case MAJOR: curScaleArr = SCALE_MAJOR; notesInScale=LENGTHOF(SCALE_MAJOR); break;
- case MELODIC_MINOR: curScaleArr = SCALE_MELODIC_MINOR; notesInScale=LENGTHOF(SCALE_MELODIC_MINOR); break;
- case MINOR: curScaleArr = SCALE_MINOR; notesInScale=LENGTHOF(SCALE_MINOR); break;
- case MIXOLYDIAN: curScaleArr = SCALE_MIXOLYDIAN; notesInScale=LENGTHOF(SCALE_MIXOLYDIAN); break;
- case NATURAL_MINOR: curScaleArr = SCALE_NATURAL_MINOR; notesInScale=LENGTHOF(SCALE_NATURAL_MINOR); break;
- case PENTATONIC: curScaleArr = SCALE_PENTATONIC; notesInScale=LENGTHOF(SCALE_PENTATONIC); break;
- case PHRYGIAN: curScaleArr = SCALE_PHRYGIAN; notesInScale=LENGTHOF(SCALE_PHRYGIAN); break;
- case TURKISH: curScaleArr = SCALE_TURKISH; notesInScale=LENGTHOF(SCALE_TURKISH); break;
- case NONE: return voltsIn;
- }
-
- //C1 == -2.00, C2 == -1.00, C3 == 0.00, C4 == 1.00
- //B1 == -1.08, B2 == -0.08, B3 == 0.92, B4 == 1.92
- float closestVal = 10.0;
- float closestDist = 10.0;
- float scaleNoteInVolts = 0;
- float distAway = 0;
- int octaveInVolts = int(floorf(voltsIn));
- float voltMinusOct = voltsIn - octaveInVolts;
- // int nextOctaveInVolts = (octaveInVolts + 1) * inverseMult; // If I decide to round to the next octave.
- for (int i=0; i < notesInScale; i++) {
- scaleNoteInVolts = curScaleArr[i] / 12.0;
- distAway = fabs(voltMinusOct - scaleNoteInVolts);
- if(distAway < closestDist){
- closestVal = scaleNoteInVolts;
- closestDist = distAway;
- }
-
- // If I decide to round to the next octave. (Ableton does NOT do this in their scale midi effect)
- // float distToNextOct = fabs(nextOctaveInVolts - voltsIn);
- // if(distToNextOct < closestDist){
- // closestVal = nextOctaveInVolts;
- // closestDist = distToNextOct;
- // }
-
- // if(printIter%100000==0){
- // printf("i:%i, rootNote:%i, voltsIn:%f, octaveInVolts:%i, closestVal:%f, closestDist:%f\n",
- // i, rootNote, voltsIn, octaveInVolts, closestVal, closestDist);
- // printIter = 0;
- // }
- }
- // printIter++;
- return octaveInVolts + rootNote/12.0 + closestVal;
- }
-
- std::string noteName(int note) {
- switch(note){
- case NOTE_C: return "C";
- case NOTE_C_SHARP: return "C#";
- case NOTE_D: return "D";
- case NOTE_D_SHARP: return "D#";
- case NOTE_E: return "E";
- case NOTE_F: return "F";
- case NOTE_F_SHARP: return "F#";
- case NOTE_G: return "G";
- case NOTE_G_SHARP: return "G#";
- case NOTE_A: return "A";
- case NOTE_A_SHARP: return "A#";
- case NOTE_B: return "B";
- default: return "";
- }
- }
-
- std::string scaleName(int scale) {
- switch(scale){
- case AEOLIAN: return "Aeolian";
- case BLUES: return "Blues";
- case CHROMATIC: return "Chromat";
- case DIATONIC_MINOR: return "Diat Min";
- case DORIAN: return "Dorian";
- case HARMONIC_MINOR: return "Harm Min";
- case INDIAN: return "Indian";
- case LOCRIAN: return "Locrian";
- case LYDIAN: return "Lydian";
- case MAJOR: return "Major";
- case MELODIC_MINOR: return "Mel Min";
- case MINOR: return "Minor";
- case MIXOLYDIAN: return "Mixolyd";
- case NATURAL_MINOR: return "Nat Min";
- case PENTATONIC: return "Penta";
- case PHRYGIAN: return "Phrygian";
- case TURKISH: return "Turkish";
- case NONE: return "None";
- default: return "";
- }
- }
- };
-
- } // namespace rack_plugin_JW_Modules
|