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>
float osc_progress[6];//0~4=chord osc , 5=bass osc , 6=arpeggio osc
#define MODESWITCH_PIN_A 0
#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];
float osc_scale_rate[5]; // 0~3=chord osc , 6=arpeggio osc
int slice_num = 0;
......@@ -8,7 +16,7 @@ float osc_freq = 0;
int wavetable[256]; // 1024 resolution , 256 rate
float calb = 1.11; // calibration for reduce resistance error
int adc, freq_pot;
int waveform = 0;
int waveform_selection = 0;
int f0 = 35; // base osc frequency
int j = 0;
......@@ -20,19 +28,22 @@ bool push_sw, old_push_sw;//push sw
int qnt[32];
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
};
const static int majthr[32]={// major scale quantize threshold
// Quantizer Threshold values for the Major Scale
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
};
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
};
const static int minthr[32]={// minor scale quantize threshold
// Quantizer Threshold values for the Minor Scale
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
};
......@@ -81,15 +92,18 @@ float freq_table[2048];
void setup1() {
}
void setup()
{
//Serial.begin(9600);//for development
pinMode(0, INPUT_PULLUP);//mode select
pinMode(1, INPUT_PULLUP);//mode select
pinMode(6, INPUT_PULLUP);//push sw
void setup() {
// Mode select switch is a On-Off-On switch with the outer pins connected
// to the pins 0 and 1.
pinMode(MODESWITCH_PIN_A, INPUT_PULLUP);
pinMode(MODESWITCH_PIN_B, INPUT_PULLUP);
// Push Button
pinMode(PUSHBUTTON_PIN, INPUT_PULLUP);//push sw
table_set();//set wavetable
qnt_set();
// Create the waveform and put it into the wavetable
wavetable_populate();
quantizer_select();
//-------------------octave select-------------------------------
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]));
......@@ -107,16 +121,16 @@ void setup()
irq_set_exclusive_handler(PWM_IRQ_WRAP, on_pwm_wrap);
irq_set_enabled(PWM_IRQ_WRAP, true);
//set PWM frequency
pwm_set_clkdiv(slice_num, 4);//=sysclock/((resolution+1)*frequency)
pwm_set_wrap(slice_num, 1023);//resolutio
// Set PWM frequency
pwm_set_clkdiv(slice_num, 4);
pwm_set_wrap(slice_num, 1023); // Resolution
pwm_set_enabled(slice_num, true); // PWM output enable
}
// Timer that pushes out the actual audio.
void on_pwm_wrap() {
pwm_clear_irq(slice_num);
// if(select_mode!=2){
if (chord_mode == 2 || chord_mode == 3 || chord_mode == 4) {
osc_progress[0] = osc_progress[0] + osc_freq * osc_scale_rate[0];
osc_progress[1] = osc_progress[1] + osc_freq * osc_scale_rate[1];
......@@ -142,45 +156,39 @@ for(byte i = 0; i < 6; i++){
if (select_mode != 2){
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);
}
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);
}
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);
}
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);
}
}
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);
}
}
void loop()
{
void loop() {
old_push_sw = push_sw;
// -------------------frequeny calculation-------------------------------
adc = analogRead(26) * calb;//Correct resistance errors
qnt_set();
freq_pot = map(analogRead(27), 0, 1023, 0, 127);
adc = analogRead(VOCT_PIN) * calb; // Correct resistance errors
quantizer_select();
freq_pot = map(analogRead(FREQ_POT_PIN), 0, 1023, 0, 127);
osc_freq = freq_table[qnt[thr] + freq_pot]; // V/oct apply
osc_freq = 256 * osc_freq / 122070 * 8;//7 is base octave
Serial.print(analogRead(26));//for development
Serial.print(",");//for development
Serial.print(adc);//for development
Serial.println("");//for development
Serial.print(analogRead(VOCT_PIN));
Serial.print(",");
Serial.print(adc);
Serial.println("");
// -------------------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---------------------
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
new_invAD = old_invAD;
}
......@@ -338,22 +346,13 @@ switch(chord_mode){
case 5:
select_table = 2;//4 chord
break;
}
//----------------------mode select-----------------
if (digitalRead(0) == 1 && digitalRead(1) == 1) {
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
}
readModeSwitch();
if(chord_mode==2 ||chord_mode==3 ||chord_mode==4){//set each oscillator frequency
// 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[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];
......@@ -366,18 +365,36 @@ if(chord_mode==0 ||chord_mode==1||chord_mode==5){
};
// -------------------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
waveform++;//change waveform
if (waveform > 7) {
waveform = 0;
// Change the selected waveform and ensure the selection is within bounds
waveform_selection = min(waveform_selection + 1, 6);
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
if(chord_mode==0 ||chord_mode==1 ||chord_mode==2||chord_mode==3){//major scale
// Select the quantization for the V/oct input
void quantizer_select(){
// Major Scale
if (chord_mode <= 3) {
for (j=0; j<31; j++) {
if (adc>=majthr[j] && adc<majthr[j+1]) {
thr = j;
......@@ -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++) {
if (adc>=minthr[j] && adc<minthr[j+1]) {
thr = j;
......@@ -400,55 +418,64 @@ void qnt_set(){//quantize v/oct input
}
}
void table_set() {//make wavetable
switch (waveform) {
// Populate the wavetable with values
void wavetable_populate() {
switch (waveform_selection) {
// Sawtooth wave
case 0:
for (int i = 0; i < 256; i++) { //saw
for (int i = 0; i < 256; i++) {
wavetable[i] = i * 4 - 512;
}
break;
// Sine wave
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;
}
break;
// Square Wave
case 2:
for (int i = 0; i < 128; i++) { //squ
for (int i = 0; i < 128; i++) {
wavetable[i] = 511;
wavetable[i + 128] = -511;
}
break;
// Triangle wave
case 3:
for (int i = 0; i < 128; i++) { //tri
for (int i = 0; i < 128; i++) {
wavetable[i] = i * 8 - 511;
wavetable[i + 128] = 511 - i * 8;
}
break;
// Octave-Sawtooth wave
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 + 128] = i * 2 - 256 + i * 4;
}
break;
// FM1 Wave
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;
}
break;
// FM2 Wave
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;
}
break;
// FM3 Wave
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;
}
break;
......
File added
File added
Source diff could not be displayed: it is too large. Options to address this: view the blob.