@@ -10,10 +10,12 @@ struct ScaleCV : Module {
1010 enum InputIds {
1111 ROOT_INPUT ,
1212 MODE_INPUT ,
13+ ENUMS (QUANTIZER_INPUTS , 4 ),
1314 NUM_INPUTS
1415 };
1516 enum OutputIds {
1617 POLY_OUTPUT ,
18+ ENUMS (QUANTIZER_OUTPUTS , 4 ),
1719 NUM_OUTPUTS
1820 };
1921 enum LightIds {
@@ -58,6 +60,35 @@ void ScaleCV::process(const ProcessArgs &args){
5860 // Make the scale
5961 struct scale s = get_scale (root_note, mode);
6062
63+ // Quantizers
64+ for (int t=0 ; t<4 ; t++){
65+ if (inputs[QUANTIZER_INPUTS + t].isConnected () && outputs[QUANTIZER_OUTPUTS + t].isConnected ()){
66+ float in_v = inputs[QUANTIZER_INPUTS + t].getVoltage ();
67+ float in_octave = round (in_v) + 4 ;
68+ float in_semi = voltage_to_note (in_v);
69+ float lowest_dist = 12 .0f ;
70+ float out_note = 0 .0f ;
71+ for (int i=0 ; i<7 ; i++){
72+ float note = (float )(s.notes [i] - ((octave + 4 ) * 12 ));
73+ float dist = abs (note - in_semi);
74+ if (dist < lowest_dist){
75+ out_note = note;
76+ lowest_dist = dist;
77+ }
78+ // check one octave down
79+ note -= 12 ;
80+ dist = abs (note - in_semi);
81+ if (dist < lowest_dist){
82+ out_note = note;
83+ lowest_dist = dist;
84+ }
85+ }
86+ out_note += in_octave * 12 .0f ;
87+ outputs[QUANTIZER_OUTPUTS +t].setVoltage (note_to_voltage ((int )out_note));
88+ }
89+
90+ }
91+
6192 outputs[POLY_OUTPUT ].setChannels (7 );
6293 for (int t=0 ; t<7 ; t++){
6394 outputs[POLY_OUTPUT ].setVoltage (note_to_voltage (s.notes [t]),t);
@@ -115,13 +146,29 @@ struct ScaleCVWidget : ModuleWidget {
115146
116147 const int offsetXL = 40 ;
117148
149+ static const int offsetX = 28 ;
150+ static const int posY = 190 ;
151+ static const int spacingY2 = 32 ;
152+ static const int posY1 = posY + spacingY2;
153+ static const int posY2 = posY + (spacingY2 * 2 );
154+ static const int posY3 = posY + (spacingY2 * 3 );
118155
119156 addParam (createParamCentered<Rogan2PWhite>(Vec (centerX,95 ), module , ScaleCV::ROOT_PARAM ));
120157 addInput (createInputCentered<PJ301MPort>(Vec (centerX - offsetXL, 95 ), module , ScaleCV::ROOT_INPUT ));
121158
122159 addParam (createParamCentered<Rogan2PWhite>(Vec (centerX,140 ), module , ScaleCV::MODE_PARAM ));
123160 addInput (createInputCentered<PJ301MPort>(Vec (centerX - offsetXL, 140 ), module , ScaleCV::MODE_INPUT ));
124161
162+ addInput (createInputCentered<PJ301MPort>(Vec (centerX - offsetX, posY), module , ScaleCV::QUANTIZER_INPUTS + 0 ));
163+ addInput (createInputCentered<PJ301MPort>(Vec (centerX - offsetX, posY1), module , ScaleCV::QUANTIZER_INPUTS + 1 ));
164+ addInput (createInputCentered<PJ301MPort>(Vec (centerX - offsetX, posY2), module , ScaleCV::QUANTIZER_INPUTS + 2 ));
165+ addInput (createInputCentered<PJ301MPort>(Vec (centerX - offsetX, posY3), module , ScaleCV::QUANTIZER_INPUTS + 3 ));
166+
167+ addOutput (createOutputCentered<PJ301MPort>(Vec (centerX + offsetX, posY), module , ScaleCV::QUANTIZER_OUTPUTS + 0 ));
168+ addOutput (createOutputCentered<PJ301MPort>(Vec (centerX + offsetX, posY1), module , ScaleCV::QUANTIZER_OUTPUTS + 1 ));
169+ addOutput (createOutputCentered<PJ301MPort>(Vec (centerX + offsetX, posY2), module , ScaleCV::QUANTIZER_OUTPUTS + 2 ));
170+ addOutput (createOutputCentered<PJ301MPort>(Vec (centerX + offsetX, posY3), module , ScaleCV::QUANTIZER_OUTPUTS + 3 ));
171+
125172 addOutput (createOutputCentered<PJ301MPort>(Vec (centerX, 330 ), module , ScaleCV::POLY_OUTPUT ));
126173 }
127174};
0 commit comments