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;
float VOL = 0.5f;
float ABS_VOL = 0.5f;
//float decay = 1.0f;
float decay = 0.99998f;
Adafruit_SSD1306 display(OLED_W, OLED_H, &Wire);
// ----- Menu Functions
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]);
// Modes
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]);
// Octave
int octave = 4;
int octave = 2;
// ---- Audio ----
@ -185,41 +186,36 @@ private:
for (auto &v : voices) {
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;
// Defined voices
switch(sound){
//SawSine
// Saw+Sine
case 0:
osc = (sineWave(v.phase1)+sineWave(v.phase2)+wavetableInt[(int)floor(1024.0f*v.phase2)])/3.0f;
break;
//Sine
// Sine Wave
case 1:
osc = (sineWave(v.phase1)+sineWave(v.phase2))/2.0f;
osc = sineWave(v.phase1);
break;
//Saw
// Saw Wave
case 2:
osc = (v.phase1);
osc = v.phase1;
break;
//Triangle
// Triangle Wave
case 3:
osc = abs((v.phase1*2)-1.0f);
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.phase2 += (v.freq *1.0f * (1.25f + detune)) / SAMPLE_RATE;
//v.phase2 += (v.freq *1.25f * (1.0f + detune)) / SAMPLE_RATE;
@ -265,8 +261,9 @@ StreamCopy copier(i2s, synth);
/* =========================================================
MATRIX SCAN
========================================================= */
=========================================================
Scan the key matrix and update the 16 bits representing them
*/
uint16_t scanMatrix() {
uint16_t state = 0;
@ -285,6 +282,75 @@ uint16_t scanMatrix() {
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
========================================================= */
@ -310,16 +376,26 @@ void drawPads(uint16_t keys) {
}
void drawScope() {
int mid = 35; // middle of scope on Y position
int mid = 45; // middle of scope on Y position
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++) {
int i1 = (synth.scopeIndex + x) & 127;
int i2 = (i1 + 1) & 127;
display.drawLine(
x,
mid - synth.scope[i1] * 20,
mid - synth.scope[i1] * scale * height,
x + 1,
mid - synth.scope[i2] * 20,
mid - synth.scope[i2] * scale * height,
SSD1306_WHITE
);
}
@ -370,10 +446,10 @@ void updateOLED(uint16_t keys) {
display.display();
}
/* =========================================================
SETUP
========================================================= */
void setup() {
genWaveTable();
for (int i = 0; i < 4; i++) {
@ -398,82 +474,22 @@ void setup() {
cfg.pin_bck = 16;
cfg.pin_ws = 17;
cfg.pin_data = 18;
i2s.begin(cfg);
}
/* =========================================================
LOOP
========================================================= */
static uint16_t lastKeys = 0;
static uint32_t lastUI = 0;
uint16_t keys = 0;
uint16_t changed = keys ^ lastKeys;
void loop() {
// Handle the realtime synthesizer stream
copier.copy();
}
// Seocnd core does inputs + display + leds
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) {
updateOLED(keys);
lastUI = millis();