Fixed issues with overflows

This commit is contained in:
superminaren 2026-02-15 12:37:38 +01:00
parent 4575ebf29a
commit 07917c0e6e
1 changed files with 108 additions and 92 deletions

View File

@ -17,21 +17,22 @@
bool funcKey = false; bool funcKey = false;
float VOL = 0.5f; float VOL = 0.5f;
float ABS_VOL = 0.5f;
//float decay = 1.0f; //float decay = 1.0f;
float decay = 0.99998f; float decay = 0.99998f;
Adafruit_SSD1306 display(OLED_W, OLED_H, &Wire); Adafruit_SSD1306 display(OLED_W, OLED_H, &Wire);
// ----- Menu Functions // ----- Menu Functions
int sound = 0; //Default voice int sound = 0; //Default voice
String sounds[4] = {"Saw+Sine", "Sine", "Saw", "Triangle"}; String sounds[6] = {"Saw+Sine", "Sine", "Saw", "Triangle", "Square", "Noise"};
int sound_count = sizeof(sounds)/sizeof(sounds[0]); int sound_count = sizeof(sounds)/sizeof(sounds[0]);
// Modes // Modes
int mode = 0; int mode = 0;
String mode_names[3] = {"Vol", "Sou", "Oct"}; String mode_names[4] = {"Vol", "Sou", "Oct", "Env"};
int mode_count = sizeof(mode_names)/sizeof(mode_names[0]); int mode_count = sizeof(mode_names)/sizeof(mode_names[0]);
// Octave // Octave
int octave = 4; int octave = 2;
// ---- Audio ---- // ---- Audio ----
@ -185,41 +186,36 @@ private:
for (auto &v : voices) { for (auto &v : voices) {
if (!v.active) continue; if (!v.active) continue;
/* SQUARE Wave
float square1 = (v.phase1>0.5f);
float square2 = (v.phase2>0.5f);
float osc = (saw1+saw2)/2.0f;
*/
float osc = 0.0f; float osc = 0.0f;
// Defined voices // Defined voices
switch(sound){ switch(sound){
//SawSine // Saw+Sine
case 0: case 0:
osc = (sineWave(v.phase1)+sineWave(v.phase2)+wavetableInt[(int)floor(1024.0f*v.phase2)])/3.0f; osc = (sineWave(v.phase1)+sineWave(v.phase2)+wavetableInt[(int)floor(1024.0f*v.phase2)])/3.0f;
break; break;
//Sine // Sine Wave
case 1: case 1:
osc = (sineWave(v.phase1)+sineWave(v.phase2))/2.0f; osc = sineWave(v.phase1);
break; break;
//Saw // Saw Wave
case 2: case 2:
osc = (v.phase1); osc = v.phase1;
break; break;
//Triangle // Triangle Wave
case 3: case 3:
osc = abs((v.phase1*2)-1.0f); osc = abs((v.phase1*2)-1.0f);
break; break;
// Square Wave
case 4:
osc = (v.phase1>0.5f);
break;
// Noise
case 5:
osc = sineWave(v.phase1)+(random(-1000,1000)/2000.0f);
break;
} }
//SINE
//osc = (osc+(v.phase1 > 0.5f)+(v.phase2 > 0.5f)) / 3.0f;
//float saw = sin(v.phase2 * (TWO_PI-PI));
//float osc = (saw1+saw2)/2.0f;
v.phase1 += v.freq / SAMPLE_RATE; v.phase1 += v.freq / SAMPLE_RATE;
v.phase2 += (v.freq *1.0f * (1.25f + detune)) / SAMPLE_RATE; v.phase2 += (v.freq *1.0f * (1.25f + detune)) / SAMPLE_RATE;
//v.phase2 += (v.freq *1.25f * (1.0f + detune)) / SAMPLE_RATE; //v.phase2 += (v.freq *1.25f * (1.0f + detune)) / SAMPLE_RATE;
@ -265,8 +261,9 @@ StreamCopy copier(i2s, synth);
/* ========================================================= /* =========================================================
MATRIX SCAN MATRIX SCAN
========================================================= */ =========================================================
Scan the key matrix and update the 16 bits representing them
*/
uint16_t scanMatrix() { uint16_t scanMatrix() {
uint16_t state = 0; uint16_t state = 0;
@ -285,6 +282,75 @@ uint16_t scanMatrix() {
return state; return state;
} }
static uint16_t lastKeys = 0;
static uint32_t lastUI = 0;
uint16_t keys = 0;
uint16_t changed = keys ^ lastKeys;
// Handle key scanning and menus
void handleInputs(){
lastKeys = keys;
keys = scanMatrix();
changed = keys ^ lastKeys;
for (int i = 0; i < 16; i++) {
if (changed & (1 << i)) {
if (i < 12) {
if ((keys & (1 << i))){
noteOn(noteFreq[i]);
}else{
noteOff(noteFreq[i]);
}
} else {
funcKey = (keys & (1 << 12));
// If Enter key pressed
if(keys & (1 << 14)){
mode = mode+1;
mode = mode % mode_count;
}
// If Left key is pressed
if(keys & (1 << 13)){
switch(mode){
case 0: // Volume
if(VOL > 0.1f){ VOL-=0.1f; } break;
case 1: // Sound
sound = sound - 1;
if( sound < 0 ){sound = sound_count-1;}
break;
case 2: // Octave
if(octave>1){ octave = octave-1;}
initNotes();
break;
case 3: // Envelope
// TODO
break;
}
// If Right key is pressed
}else if((keys & (1 << 15))){
switch(mode){
case 0: // Volume
if(VOL<1.0f){VOL+=0.1f;}
break;
case 1: // Sound
sound = sound + 1;
sound = sound % sound_count;
break;
case 2: // Octave
if(octave<8){octave = octave + 1;}
initNotes();
break;
case 3: // Envelope
break;
}
}
//menuButton(i-12);
}
}
}
return;
}
/* ========================================================= /* =========================================================
OLED DRAWING OLED DRAWING
========================================================= */ ========================================================= */
@ -310,16 +376,26 @@ void drawPads(uint16_t keys) {
} }
void drawScope() { void drawScope() {
int mid = 35; // middle of scope on Y position int mid = 45; // middle of scope on Y position
int height = 20; int height = 20;
float maxVal = 0.0f;
float threshold = 0.002f;
float scale = 1.0f;
for (int x = 0; x < 127; x++) {
int i1 = (synth.scopeIndex + x) & 127;
if(synth.scope[i1]>threshold && synth.scope[i1] > maxVal){
maxVal = synth.scope[i1];
}
}
scale = 1.0f/maxVal;
for (int x = 0; x < 127; x++) { for (int x = 0; x < 127; x++) {
int i1 = (synth.scopeIndex + x) & 127; int i1 = (synth.scopeIndex + x) & 127;
int i2 = (i1 + 1) & 127; int i2 = (i1 + 1) & 127;
display.drawLine( display.drawLine(
x, x,
mid - synth.scope[i1] * 20, mid - synth.scope[i1] * scale * height,
x + 1, x + 1,
mid - synth.scope[i2] * 20, mid - synth.scope[i2] * scale * height,
SSD1306_WHITE SSD1306_WHITE
); );
} }
@ -370,10 +446,10 @@ void updateOLED(uint16_t keys) {
display.display(); display.display();
} }
/* ========================================================= /* =========================================================
SETUP SETUP
========================================================= */ ========================================================= */
void setup() { void setup() {
genWaveTable(); genWaveTable();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@ -398,82 +474,22 @@ void setup() {
cfg.pin_bck = 16; cfg.pin_bck = 16;
cfg.pin_ws = 17; cfg.pin_ws = 17;
cfg.pin_data = 18; cfg.pin_data = 18;
i2s.begin(cfg); i2s.begin(cfg);
} }
/* ========================================================= /* =========================================================
LOOP LOOP
========================================================= */ ========================================================= */
static uint16_t lastKeys = 0;
static uint32_t lastUI = 0;
uint16_t keys = 0;
uint16_t changed = keys ^ lastKeys;
void loop() { void loop() {
// Handle the realtime synthesizer stream
copier.copy(); copier.copy();
} }
// Seocnd core does inputs + display + leds
void loop1(){ void loop1(){
keys = scanMatrix();
changed = keys ^ lastKeys;
for (int i = 0; i < 16; i++) {
if (changed & (1 << i)) {
if (i < 12){
if ((keys & (1 << i))){
noteOn(noteFreq[i]);
}else{
noteOff(noteFreq[i]);
}
}else{
funcKey = (keys & (1 << 12));
// If Enter key pressed
if(keys & (1 << 14)){
mode = mode+1;
mode = mode % mode_count;
}
// If Left key is pressed
if(keys & (1 << 13)){
switch(mode){
case 0: // Volume
if(VOL>0.1f){VOL-=0.1f;}
break;
case 1: // Sound
sound = sound - 1;
if(sound<0){sound = sound_count-1;}
break;
case 2: // Octave
if(octave>1){octave = octave-1;}
initNotes();
break;
}
// If Right key is pressed
}else if((keys & (1 << 15))){
switch(mode){
case 0: // Volume
if(VOL<1.0f){VOL+=0.1f;}
break;
case 1: // Sound
sound = sound + 1;
sound = sound % sound_count;
break;
case 2: // Octave
if(octave<8){octave = octave + 1;}
initNotes();
break;
}
}
//menuButton(i-12);
}
}
}
lastKeys = keys; handleInputs();
if (millis() - lastUI > 30) { if (millis() - lastUI > 30) {
updateOLED(keys); updateOLED(keys);
lastUI = millis(); lastUI = millis();