diff --git a/sketch/sketch.ino b/sketch/sketch.ino index 68ed089..5f9c09f 100644 --- a/sketch/sketch.ino +++ b/sketch/sketch.ino @@ -23,7 +23,7 @@ float decay = 0.99998f; float decay_off = 0.9995f; Adafruit_SSD1306 display(OLED_W, OLED_H, &Wire); // ----- Menu Functions -int sound = 0; //Default voice +int sound = 3; //Default voice String sounds[6] = { "Saw+Sine", "Sine", "Saw", "Triangle", "Square", "Noise" }; int sound_count = sizeof(sounds) / sizeof(sounds[0]); @@ -37,21 +37,23 @@ int octave = 2; // Arpeggio //int arp_pattern[5] = {1 ,3 ,5 ,3 ,1 }; -int arp_pattern[5] = {0 ,4 ,7 ,3 ,1 }; -int arpeggio = 1; // 0 = Off, 1 = +String arp_pattern_names[4] = {"Maj.","Min.","Dim.", "Aug."}; +int arp_pattern[4][3] = {{0 ,4 ,7},{0,3,7},{0,3,6},{0,4,8}}; +int arpeggio = 1; // 0 = Off, 1 = one of the patterns int arp_notes = 3; // Now many notes to arpeggiate int arp_delay = 150; // 300 ms // ---- Audio ---- //constexpr uint32_t SAMPLE_RATE = 96000; -constexpr uint32_t SAMPLE_RATE = 44100; +constexpr uint32_t SAMPLE_RATE = 30000; constexpr uint8_t CHANNELS = 1; constexpr uint8_t BITS = 16; // ----- Reverb ----- constexpr int reverb_time = 200; // 200 ms. constexpr int reverb_samples = (int)(reverb_time / 1000 * SAMPLE_RATE); + float reverbqueue[reverb_samples] = {}; float reverb_fade = 0.3f; @@ -119,7 +121,7 @@ void noteOn(float freq) { void noteOff(float freq) { for (auto &v : voices) { - if (v.active && fabs(v.startFreq - freq) < 0.01f) { + if (v.active && fabs(v.startFreq - freq) < 0.01f && !funcKey) { //v.active = false; v.decay = decay_off; } @@ -172,6 +174,12 @@ float transposeSemitones(float freq, int semitones) { SYNTH STREAM ========================================================= */ + +void synth_sawsine(){ + +} + + class SynthStream : public Stream { public: uint8_t frame[4]; @@ -221,13 +229,14 @@ private: v.arp_time = millis(); v.arp_position++; v.arp_position = v.arp_position % arp_notes; - v.freq = transposeSemitones(v.startFreq, arp_pattern[v.arp_position]); + v.freq = transposeSemitones(v.startFreq, arp_pattern[arpeggio-1][v.arp_position]); } - // Defined voices + + Defined voices switch (sound) { // Saw+Sine 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) )/ 2.0f; break; // Sine Wave case 1: @@ -252,7 +261,7 @@ private: } v.phase1 += v.freq / SAMPLE_RATE; - v.phase2 += (v.freq * 1.0f * (1.25f + detune)) / SAMPLE_RATE; + v.phase2 += (v.freq * (1.25f)) / SAMPLE_RATE; //v.phase2 += (v.freq *1.25f * (1.0f + detune)) / SAMPLE_RATE; if (v.phase1 >= 1) v.phase1 -= 1; if (v.phase2 >= 1) v.phase2 -= 1; @@ -262,9 +271,10 @@ private: if (v.env < 0.0005f) v.active = false; mix += osc * v.amp; + mix = mix / (1.0f + fabsf(mix)); } // Handle reverb - mix = (handleReverb(mix) + mix) / 2.0f; + //mix = (handleReverb(mix) + mix) / 2.0f; lp += cutoff * (mix - lp); @@ -466,10 +476,12 @@ void drawInfo() { // Show current menu mode display.setCursor(64, 6); display.print("Set:" + mode_names[mode]); + // Octave display.setCursor(90, 18); display.print("Oct:" + String(octave)); + // Arpeggio display.setCursor(40, 18); - display.print("Arp: "+ String((arpeggio ? "On" : "Off"))); + display.print("Arp:"+ String((arpeggio ? arp_pattern_names[arpeggio-1] : "Off"))); } void updateOLED(uint16_t keys) {