Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • sdiy/rp2040-chord-vco
1 result
Select Git revision
Loading items
Show changes

Commits on Source 3

  • David Huss's avatar
    Code cleanup and refactoring · 43433993
    David Huss authored
    This should functionally change nothing, but:
    
    - makes code formatting, use of spaces and so on more consistent
    - fixes some wrongly indented parts of the code
    - renames some functions and variable to have them more cleary describe
      their purose
    - adds some comments and move others around
    - move all IO/Pins into #define variables that can be seen on top
    - factor some parts of the code out into functions to make the loop more
      concise
    43433993
  • David Huss's avatar
    Export Schematic to PDF · 960c3f31
    David Huss authored
    960c3f31
  • David Huss's avatar
    90ba64ae
#include <hardware/pwm.h> #include <hardware/pwm.h>
#define MODESWITCH_PIN_A 0
float osc_progress[6];//0~4=chord osc , 5=bass osc , 6=arpeggio osc #define MODESWITCH_PIN_B 1
#define PUSHBUTTON_PIN 6
#define VOCT_PIN 26
#define FREQ_POT_PIN 27
#define INVERSION_PIN 28
#define CHORD_POT_PIN 29
// 0-4=chord osc , 5=bass osc , 6=arpeggio osc
float osc_progress[6];
int osc_inverse[4]; int osc_inverse[4];
float osc_scale_rate[5]; // 0~3=chord osc , 6=arpeggio osc float osc_scale_rate[5]; // 0~3=chord osc , 6=arpeggio osc
int slice_num = 0; int slice_num = 0;
...@@ -8,7 +16,7 @@ float osc_freq = 0; ...@@ -8,7 +16,7 @@ float osc_freq = 0;
int wavetable[256]; // 1024 resolution , 256 rate int wavetable[256]; // 1024 resolution , 256 rate
float calb = 1.11; // calibration for reduce resistance error float calb = 1.11; // calibration for reduce resistance error
int adc, freq_pot; int adc, freq_pot;
int waveform = 0; int waveform_selection = 0;
int f0 = 35; // base osc frequency int f0 = 35; // base osc frequency
int j = 0; int j = 0;
...@@ -20,19 +28,22 @@ bool push_sw, old_push_sw;//push sw ...@@ -20,19 +28,22 @@ bool push_sw, old_push_sw;//push sw
int qnt[32]; int qnt[32];
int thr=0; // threshold number int thr=0; // threshold number
const static int majqnt[32]={// major scale quantize value
// Quantization values for the Major Scale
const static int majqnt[32]={
0, 34, 68, 85, 119, 153, 205, 239, 273, 290, 324, 358, 409, 443, 477, 494, 529, 563, 614, 648, 682, 699, 733, 767, 818, 853, 887, 904, 938, 972, 1023 0, 34, 68, 85, 119, 153, 205, 239, 273, 290, 324, 358, 409, 443, 477, 494, 529, 563, 614, 648, 682, 699, 733, 767, 818, 853, 887, 904, 938, 972, 1023
}; };
// Quantizer Threshold values for the Major Scale
const static int majthr[32]={// major scale quantize threshold const static int majthr[32]={
0, 17, 51, 85, 102, 136, 171, 222, 256, 290, 307, 341, 375, 426, 460, 494, 512, 546, 580, 631, 665, 699, 716, 750, 784, 835, 870, 904, 921, 955, 989,1024 0, 17, 51, 85, 102, 136, 171, 222, 256, 290, 307, 341, 375, 426, 460, 494, 512, 546, 580, 631, 665, 699, 716, 750, 784, 835, 870, 904, 921, 955, 989,1024
}; };
const static int minqnt[32]={// minor scale quantize value // Quantization values for the Minor Scale
const static int minqnt[32]={
0, 34, 51, 85, 119, 136, 205, 239, 256, 290, 324, 341, 409, 443, 460, 494, 529, 546, 614, 648, 665, 699, 733, 750, 818, 853, 870, 904, 938, 955, 1023 0, 34, 51, 85, 119, 136, 205, 239, 256, 290, 324, 341, 409, 443, 460, 494, 529, 546, 614, 648, 665, 699, 733, 750, 818, 853, 870, 904, 938, 955, 1023
}; };
// Quantizer Threshold values for the Minor Scale
const static int minthr[32]={// minor scale quantize threshold const static int minthr[32]={
17, 43, 68, 102, 128, 171, 222, 248, 273, 307, 333, 375, 426, 452, 477, 512, 538, 580, 631, 657, 682, 716, 742, 784, 836, 862, 887, 921, 947, 989, 1024 17, 43, 68, 102, 128, 171, 222, 248, 273, 307, 333, 375, 426, 452, 477, 512, 538, 580, 631, 657, 682, 716, 742, 784, 836, 862, 887, 921, 947, 989, 1024
}; };
...@@ -81,15 +92,18 @@ float freq_table[2048]; ...@@ -81,15 +92,18 @@ float freq_table[2048];
void setup1() { void setup1() {
} }
void setup() void setup() {
{ // Mode select switch is a On-Off-On switch with the outer pins connected
//Serial.begin(9600);//for development // to the pins 0 and 1.
pinMode(0, INPUT_PULLUP);//mode select pinMode(MODESWITCH_PIN_A, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);//mode select pinMode(MODESWITCH_PIN_B, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);//push sw
// Push Button
pinMode(PUSHBUTTON_PIN, INPUT_PULLUP);//push sw
table_set();//set wavetable // Create the waveform and put it into the wavetable
qnt_set(); wavetable_populate();
quantizer_select();
//-------------------octave select------------------------------- //-------------------octave select-------------------------------
for (int i = 0; i < 1230; i++) {//Covers 6(=1230) octaves. If it is 1230 or more, the operation becomes unstable. for (int i = 0; i < 1230; i++) {//Covers 6(=1230) octaves. If it is 1230 or more, the operation becomes unstable.
freq_table[i] = f0 * pow(2, (voctpow[i])); freq_table[i] = f0 * pow(2, (voctpow[i]));
...@@ -107,16 +121,16 @@ void setup() ...@@ -107,16 +121,16 @@ void setup()
irq_set_exclusive_handler(PWM_IRQ_WRAP, on_pwm_wrap); irq_set_exclusive_handler(PWM_IRQ_WRAP, on_pwm_wrap);
irq_set_enabled(PWM_IRQ_WRAP, true); irq_set_enabled(PWM_IRQ_WRAP, true);
//set PWM frequency // Set PWM frequency
pwm_set_clkdiv(slice_num, 4);//=sysclock/((resolution+1)*frequency) pwm_set_clkdiv(slice_num, 4);
pwm_set_wrap(slice_num, 1023);//resolutio pwm_set_wrap(slice_num, 1023); // Resolution
pwm_set_enabled(slice_num, true); // PWM output enable pwm_set_enabled(slice_num, true); // PWM output enable
} }
// Timer that pushes out the actual audio.
void on_pwm_wrap() { void on_pwm_wrap() {
pwm_clear_irq(slice_num); pwm_clear_irq(slice_num);
// if(select_mode!=2){
if (chord_mode == 2 || chord_mode == 3 || chord_mode == 4) { if (chord_mode == 2 || chord_mode == 3 || chord_mode == 4) {
osc_progress[0] = osc_progress[0] + osc_freq * osc_scale_rate[0]; osc_progress[0] = osc_progress[0] + osc_freq * osc_scale_rate[0];
osc_progress[1] = osc_progress[1] + osc_freq * osc_scale_rate[1]; osc_progress[1] = osc_progress[1] + osc_freq * osc_scale_rate[1];
...@@ -142,45 +156,39 @@ for(byte i = 0; i < 6; i++){ ...@@ -142,45 +156,39 @@ for(byte i = 0; i < 6; i++){
if (select_mode != 2){ if (select_mode != 2){
if ((chord_mode==2 || chord_mode==3 || chord_mode==4) && select_mode == 0) { if ((chord_mode==2 || chord_mode==3 || chord_mode==4) && select_mode == 0) {
pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/4+wavetable[(int)osc_progress[1]]/4+wavetable[(int)osc_progress[3]]/4+511); pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/4+wavetable[(int)osc_progress[1]]/4+wavetable[(int)osc_progress[3]]/4+511);
} } else if ((chord_mode == 2 ||chord_mode == 3 ||chord_mode == 4) && select_mode == 1) {
else if((chord_mode==2 ||chord_mode==3 ||chord_mode==4)&& select_mode==1){
pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/4+wavetable[(int)osc_progress[1]]/4+wavetable[(int)osc_progress[2]]/4+wavetable[(int)osc_progress[4]]/4+511); pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/4+wavetable[(int)osc_progress[1]]/4+wavetable[(int)osc_progress[2]]/4+wavetable[(int)osc_progress[4]]/4+511);
} } else if ((chord_mode == 0 || chord_mode == 1|| chord_mode == 5) && select_mode == 0) {
else if((chord_mode==0 ||chord_mode==1||chord_mode==5) && select_mode==0){
pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/5+wavetable[(int)osc_progress[1]]/5+wavetable[(int)osc_progress[2]]/5+wavetable[(int)osc_progress[3]]/5+511); pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/5+wavetable[(int)osc_progress[1]]/5+wavetable[(int)osc_progress[2]]/5+wavetable[(int)osc_progress[3]]/5+511);
} } else if ((chord_mode == 0 || chord_mode == 1|| chord_mode == 5) && select_mode == 1) {
else if((chord_mode==0 ||chord_mode==1||chord_mode==5) && select_mode==1){
pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/5+wavetable[(int)osc_progress[1]]/5+wavetable[(int)osc_progress[2]]/5+wavetable[(int)osc_progress[3]]/5+wavetable[(int)osc_progress[4]]/5+511); pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[0]]/5+wavetable[(int)osc_progress[1]]/5+wavetable[(int)osc_progress[2]]/5+wavetable[(int)osc_progress[3]]/5+wavetable[(int)osc_progress[4]]/5+511);
} }
} } else if (select_mode == 2){
else if(select_mode==2){
pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[5]]/2+511); pwm_set_chan_level(slice_num, PWM_CHAN_A, wavetable[(int)osc_progress[5]]/2+511);
} }
} }
void loop() void loop() {
{
old_push_sw = push_sw; old_push_sw = push_sw;
// -------------------frequeny calculation------------------------------- // -------------------frequeny calculation-------------------------------
adc = analogRead(26) * calb;//Correct resistance errors adc = analogRead(VOCT_PIN) * calb; // Correct resistance errors
qnt_set(); quantizer_select();
freq_pot = map(analogRead(27), 0, 1023, 0, 127); freq_pot = map(analogRead(FREQ_POT_PIN), 0, 1023, 0, 127);
osc_freq = freq_table[qnt[thr] + freq_pot]; // V/oct apply osc_freq = freq_table[qnt[thr] + freq_pot]; // V/oct apply
osc_freq = 256 * osc_freq / 122070 * 8;//7 is base octave osc_freq = 256 * osc_freq / 122070 * 8;//7 is base octave
Serial.print(analogRead(26));//for development Serial.print(analogRead(VOCT_PIN));
Serial.print(",");//for development Serial.print(",");
Serial.print(adc);//for development Serial.print(adc);
Serial.println("");//for development Serial.println("");
// -------------------chord mode select------------------------------- // -------------------chord mode select-------------------------------
chord_mode = analogRead(29)/171;//171=1023/6 , 6 is amount of chord mode chord_mode = analogRead(CHORD_POT_PIN)/171; //171=1023/6 , 6 is amount of chord mode
// ---------------------inversion--------------------- // ---------------------inversion---------------------
old_invAD = new_invAD; // countermeasure of noise old_invAD = new_invAD; // countermeasure of noise
new_invAD=analogRead(28); new_invAD = analogRead(INVERSION_PIN);
if (abs(old_invAD-new_invAD)<4){//countermeasure of noise if (abs(old_invAD-new_invAD)<4){//countermeasure of noise
new_invAD = old_invAD; new_invAD = old_invAD;
} }
...@@ -338,22 +346,13 @@ switch(chord_mode){ ...@@ -338,22 +346,13 @@ switch(chord_mode){
case 5: case 5:
select_table = 2;//4 chord select_table = 2;//4 chord
break; break;
} }
//----------------------mode select----------------- //----------------------mode select-----------------
if (digitalRead(0) == 1 && digitalRead(1) == 1) { readModeSwitch();
select_mode = 1;//chord with bass
}
else if (digitalRead(0) == 0 && digitalRead(1) == 1) {
select_mode = 2;//arpeggio
}
else if (digitalRead(0) == 1 && digitalRead(1) == 0) {
select_mode = 0;//chord without bass
}
// Set each oscillator frequency
if(chord_mode==2 ||chord_mode==3 ||chord_mode==4){//set each oscillator frequency if (chord_mode == 2 || chord_mode == 3 || chord_mode == 4) {
osc_scale_rate[0] = freq_rate[chord_3[select_chord3[select_table][thr%6]][0]] * osc_inverse[0]; osc_scale_rate[0] = freq_rate[chord_3[select_chord3[select_table][thr%6]][0]] * osc_inverse[0];
osc_scale_rate[1] = freq_rate[chord_3[select_chord3[select_table][thr%6]][1]] * osc_inverse[1]; osc_scale_rate[1] = freq_rate[chord_3[select_chord3[select_table][thr%6]][1]] * osc_inverse[1];
osc_scale_rate[2] = freq_rate[chord_3[select_chord3[select_table][thr%6]][2]] * osc_inverse[2]; osc_scale_rate[2] = freq_rate[chord_3[select_chord3[select_table][thr%6]][2]] * osc_inverse[2];
...@@ -366,18 +365,36 @@ if(chord_mode==0 ||chord_mode==1||chord_mode==5){ ...@@ -366,18 +365,36 @@ if(chord_mode==0 ||chord_mode==1||chord_mode==5){
}; };
// -------------------push sw , change wavetable------------------------------- // -------------------push sw , change wavetable-------------------------------
push_sw = digitalRead(6); push_sw = digitalRead(PUSHBUTTON_PIN);
// TODO: Add propper debouncing for the button here
if (push_sw == 0 && old_push_sw == 1) {//when push sw ON if (push_sw == 0 && old_push_sw == 1) {//when push sw ON
waveform++;//change waveform // Change the selected waveform and ensure the selection is within bounds
if (waveform > 7) { waveform_selection = min(waveform_selection + 1, 6);
waveform = 0; wavetable_populate();
} }
table_set(); }
// Reads the mode switch, a tri-state On-Off-On toggle switch
// Assign the resulting mode to the select_mode variable
void readModeSwitch() {
bool left = digitalRead(MODESWITCH_PIN_A);
bool right = digitalRead(MODESWITCH_PIN_B);
if (left && right) {
// Chord with bass
select_mode = 1;
} else if (!left && right) {
// Arpreggio
select_mode = 2;
} else if (left && !right) {
// Chord without bass
select_mode = 0;
} }
} }
void qnt_set(){//quantize v/oct input // Select the quantization for the V/oct input
if(chord_mode==0 ||chord_mode==1 ||chord_mode==2||chord_mode==3){//major scale void quantizer_select(){
// Major Scale
if (chord_mode <= 3) {
for (j=0; j<31; j++) { for (j=0; j<31; j++) {
if (adc>=majthr[j] && adc<majthr[j+1]) { if (adc>=majthr[j] && adc<majthr[j+1]) {
thr = j; thr = j;
...@@ -388,7 +405,8 @@ void qnt_set(){//quantize v/oct input ...@@ -388,7 +405,8 @@ void qnt_set(){//quantize v/oct input
} }
} }
if(chord_mode==4 ||chord_mode==5){//minor scale // Minor Scale
if (chord_mode >= 4) {
for (j=0; j<31; j++) { for (j=0; j<31; j++) {
if (adc>=minthr[j] && adc<minthr[j+1]) { if (adc>=minthr[j] && adc<minthr[j+1]) {
thr = j; thr = j;
...@@ -400,55 +418,64 @@ void qnt_set(){//quantize v/oct input ...@@ -400,55 +418,64 @@ void qnt_set(){//quantize v/oct input
} }
} }
void table_set() {//make wavetable // Populate the wavetable with values
switch (waveform) { void wavetable_populate() {
switch (waveform_selection) {
// Sawtooth wave
case 0: case 0:
for (int i = 0; i < 256; i++) { //saw for (int i = 0; i < 256; i++) {
wavetable[i] = i * 4 - 512; wavetable[i] = i * 4 - 512;
} }
break; break;
// Sine wave
case 1: case 1:
for (int i = 0; i < 256; i++) { //sin for (int i = 0; i < 256; i++) {
wavetable[i] = (sin(2 * M_PI * i / 256)) * 511; wavetable[i] = (sin(2 * M_PI * i / 256)) * 511;
} }
break; break;
// Square Wave
case 2: case 2:
for (int i = 0; i < 128; i++) { //squ for (int i = 0; i < 128; i++) {
wavetable[i] = 511; wavetable[i] = 511;
wavetable[i + 128] = -511; wavetable[i + 128] = -511;
} }
break; break;
// Triangle wave
case 3: case 3:
for (int i = 0; i < 128; i++) { //tri for (int i = 0; i < 128; i++) {
wavetable[i] = i * 8 - 511; wavetable[i] = i * 8 - 511;
wavetable[i + 128] = 511 - i * 8; wavetable[i + 128] = 511 - i * 8;
} }
break; break;
// Octave-Sawtooth wave
case 4: case 4:
for (int i = 0; i < 128; i++) { //oct saw for (int i = 0; i < 128; i++) {
wavetable[i] = i * 4 - 512 + i * 2; wavetable[i] = i * 4 - 512 + i * 2;
wavetable[i + 128] = i * 2 - 256 + i * 4; wavetable[i + 128] = i * 2 - 256 + i * 4;
} }
break; break;
// FM1 Wave
case 5: case 5:
for (int i = 0; i < 256; i++) { //FM1 for (int i = 0; i < 256; i++) {
wavetable[i] = (sin(2 * M_PI * i / 256 + sin(2 * M_PI * 3 * i / 256)) ) * 511; wavetable[i] = (sin(2 * M_PI * i / 256 + sin(2 * M_PI * 3 * i / 256)) ) * 511;
} }
break; break;
// FM2 Wave
case 6: case 6:
for (int i = 0; i < 256; i++) { //FM2 for (int i = 0; i < 256; i++) {
wavetable[i] = (sin(2 * M_PI * i / 256 + sin(2 * M_PI * 7 * i / 256))) * 511; wavetable[i] = (sin(2 * M_PI * i / 256 + sin(2 * M_PI * 7 * i / 256))) * 511;
} }
break; break;
// FM3 Wave
case 7: case 7:
for (int i = 0; i < 256; i++) { //FM3 for (int i = 0; i < 256; i++) {
wavetable[i] = (sin(2 * M_PI * i / 256 + sin(2 * M_PI * 4 * i / 256 + sin(2 * M_PI * 11 * i / 256)))) * 511; wavetable[i] = (sin(2 * M_PI * i / 256 + sin(2 * M_PI * 4 * i / 256 + sin(2 * M_PI * 11 * i / 256)))) * 511;
} }
break; break;
......
File added
File added
Source diff could not be displayed: it is too large. Options to address this: view the blob.