diff --git a/main-play.h b/main-play.h index ca34163..71944b5 100644 --- a/main-play.h +++ b/main-play.h @@ -19,21 +19,21 @@ void doPlay(bool forceDisplayUpdate) { display.display(); } - if (pipe.silent) { + if (pipe.Silent) { Chanter.NoteOff(); } else { // Calculate pitch, and glissando pitch - float pitch = tuning.GetPitch(pipe.note); - float glissandoPitch = tuning.GetPitch(pipe.glissandoNote); + float pitch = tuning.GetPitch(pipe.CurrentNote); + float glissandoPitch = tuning.GetPitch(pipe.GlissandoNote); // Bend pitch if fewer than 3 half steps away - if (abs(pipe.glissandoNote - pipe.note) < 3) { + if (abs(pipe.GlissandoNote - pipe.CurrentNote) < 3) { float diff = glissandoPitch - pitch; - pitch += diff * pipe.glissandoOpenness; + pitch = glissandoPitch - (diff * pipe.GlissandoPressure); } // Apply a low shelf filter if this is the alternate fingering - if (pipe.altFingering) { + if (pipe.AltFingering) { biquad1.setLowShelf(0, 2000, 0.2, 1); } else { biquad1.setHighShelf(0, 1000, 1.0, 1); @@ -47,17 +47,16 @@ void doPlay(bool forceDisplayUpdate) { } } - if (pipe.note != last_note) { + if (pipe.CurrentNote != last_note) { updateDisplay = true; } - diag("%d %f", pipe.keys, pipe.glissandoOpenness); #if 0 if (updateDisplay) { // Look up the note name - const char *note_name = NoteName(pipe.note); - if (pipe.silent) { - note_name = "--"; + const char *noteName = NoteName(pipe.CurrentNote); + if (pipe.Silent) { + noteName = "--"; updateDisplay = true; } @@ -65,10 +64,10 @@ void doPlay(bool forceDisplayUpdate) { display.setFont(&FreeSans9pt7b); display.setCursor(0, 16); - display.print(note_name); + display.print(noteName); display.display(); - last_note = pipe.note; + last_note = pipe.CurrentNote; } #endif } diff --git a/main-setup.h b/main-setup.h index 1e77f86..79d5ca8 100644 --- a/main-setup.h +++ b/main-setup.h @@ -36,7 +36,10 @@ void setupVolume() { break; case ADJUST_UP: case ADJUST_DOWN: - volume[i] += float(volAdjust)*0.02; + { + float vol = volume[i] + float(volAdjust)*0.02; + volume[i] = min(max(vol, 1.0), 0.0); + } break; default: break; @@ -143,6 +146,9 @@ void setupInfo() { display.print("FC-1"); display.setCursor(0, 24); display.print(buildDate); + display.setCursor(0, 0); + display.print("M:"); + display.print(AudioMemoryUsageMax()); } /** doSetup performs "setup mode" behavior for the pipe. diff --git a/pipe.cpp b/pipe.cpp index e5c82ec..97a3e75 100644 --- a/pipe.cpp +++ b/pipe.cpp @@ -8,7 +8,7 @@ #define GLISSANDO_STEPS (OPENVAL - CLOSEDVAL) Pipe::Pipe() { - keysLast = 0; + KeysLast = 0; } bool Pipe::Init() { @@ -17,11 +17,11 @@ bool Pipe::Init() { return false; } - // Proximity sensor - if (paj7620Init()) { + // Knee sensor + if (!kneeSensor.begin()) { return false; } - + // Bag button bagSensor.begin(); // This library takes the entire program out if you poll it 5-40 times without anything connected @@ -33,70 +33,72 @@ bool Pipe::Init() { void Pipe::Update() { uint8_t glissandoKeys = 0; - keysLast = keys; - keys = 0; + KeysLast = Keys; + Keys = 0; // Read the bag state, if there's a bag. // if there isn't a bag, don't try, or this library will crash the program. if (bag_enabled) { - bag = bagSensor.isPressed(); + Bag = bagSensor.isPressed(); } else { - bag = false; + Bag = false; } // 0x6c is actually 8 bytes, but all 8 are always the same... - paj7620ReadReg(0x6c, 1, &kneeClosedness); + KneeClosedness = 255 - kneeSensor.readRange(); for (int i = 0; i < NUM_KEYS; ++i) { - uint16_t val = max(capSensor.filteredData(i), CLOSEDVAL); - keyOpen[i] = ((val - CLOSEDVAL) / float(GLISSANDO_STEPS)); + uint16_t sensorReading = capSensor.filteredData(i); + uint16_t val = OPENVAL - min(max(sensorReading, CLOSEDVAL), OPENVAL); + KeyPressure[i] = val / float(GLISSANDO_STEPS); // keys = all keys which are at least touched // glissandoKeys = all keys which are fully closed // The glissando operation computes the difference. - if (keyOpen[i] < 1.0) { - glissandoOpenness = max(glissandoOpenness, keyOpen[i]); - bitSet(keys, i); + if (KeyPressure[i] > 0.0) { + bitSet(Keys, i); } - if (keyOpen[i] == 0.0) { + if (KeyPressure[i] == 1.0) { bitSet(glissandoKeys, i); } } // Compute glissando amount - glissandoOpenness = 0.0; + GlissandoPressure = 1.0; for (int i = 0; i < 8; ++i) { - glissandoOpenness = max(glissandoOpenness, keyOpen[i]); + if (KeyPressure[i] > 0) { + GlissandoPressure = min(GlissandoPressure, KeyPressure[i]); + } } // Look up notes in the big table - struct Fingering f = FingeredNote(keys); + struct Fingering f = FingeredNote(Keys); struct Fingering gf = FingeredNote(glissandoKeys); - note = f.note; - glissandoNote = gf.note; + CurrentNote = f.note; + GlissandoNote = gf.note; // Was the high bit set? That indicates "alternate fingering", which sounds different. - altFingering = f.alt; + AltFingering = f.alt; // If the bag is squished, jump up an octave // But only if the left thumb is down! - if (bag && (keys & bit(7))) { - note += NOTE_OCTAVE; - glissandoNote += NOTE_OCTAVE; + if (Bag && (Keys & bit(7))) { + CurrentNote += NOTE_OCTAVE; + GlissandoNote += NOTE_OCTAVE; } // All keys closed + knee = no sound - silent = ((kneeClosedness > 240) && (keys == 0xff)); + Silent = ((KneeClosedness > 240) && (Keys == 0xff)); } bool Pipe::Pressed(uint8_t key) { - return bitRead(keys, key); + return bitRead(Keys, key); } bool Pipe::JustPressed(uint8_t key) { - if (bitRead(keys, key)) { - return !bitRead(keysLast, key); + if (bitRead(Keys, key)) { + return !bitRead(KeysLast, key); } return false; } @@ -136,4 +138,4 @@ Adjust Pipe::ReadAdjust(uint8_t keyUp, uint8_t keyDown, uint16_t delay, uint16_t return ADJUST_DOWN; } return ADJUST_NONE; -} \ No newline at end of file +} diff --git a/pipe.h b/pipe.h index 8203b7a..6ef4955 100644 --- a/pipe.h +++ b/pipe.h @@ -1,12 +1,12 @@ #pragma once #include +#include #include -#include #include #include "tuning.h" -#define NUM_KEYS 8 +#define NUM_KEYS 12 enum Adjust { ADJUST_DOWN = -1, @@ -18,31 +18,31 @@ enum Adjust { class Pipe { public: // kneeClosedness indicates how "closed" the knee sensor is. 0 = wide open. - uint8_t kneeClosedness; + uint8_t KneeClosedness; // keys are which keys are being pressed. - uint16_t keys; - uint16_t keysLast; - float keyOpen[NUM_KEYS]; + uint16_t Keys; + uint16_t KeysLast; + float KeyPressure[NUM_KEYS]; // note holds the note being played, according to the fingering chart. - Note note; + Note CurrentNote; // glissandoNote is the note that would be played if partially open keys were fully open. - Note glissandoNote; + Note GlissandoNote; - // glissandoOpenness is how "open" the holes are in the direction of the glissandoNote. - float glissandoOpenness; + // glissandoPressure is how "closed" the holes are in the direction away from the glissandoNote. + float GlissandoPressure; // silent is true if all keys and the knee are closed. - bool silent; + bool Silent; // bag is true if the bag is being squished. - bool bag; + bool Bag; // altFingering is true if the "alternate fingering" is being played. // This should sound different than the standard fingering. - bool altFingering; + bool AltFingering; Pipe(); @@ -70,6 +70,7 @@ class Pipe { private: Adafruit_MPR121 capSensor; + Adafruit_VL6180X kneeSensor; QwiicButton bagSensor; bool bag_enabled; unsigned long nextRepeat[NUM_KEYS]; diff --git a/uilleann.ino b/uilleann.ino index b03e1c5..0c6c71c 100644 --- a/uilleann.ino +++ b/uilleann.ino @@ -1,10 +1,7 @@ #include -#include #include #include #include -#include -#include #include #include "patches.h" @@ -26,7 +23,7 @@ Adafruit_SSD1306 display(128, 32, &Wire, -1); // Settings uint8_t patch[4] = {0}; -float volume[4] = {0}; +float volume[5] = {0.75, 0.75, 0.75, 0.75, 0.3}; // Pipes #define NUM_DRONES 3 @@ -132,13 +129,6 @@ void diag(const char *fmt, ...) { #include "main-setup.h" void setup() { - // Initialize settings - // XXX: Read these from persistent storage later - for (int i = 0; i < 4; i++) { - patch[i] = 0; - volume[i] = 0.75; - } - // PREPARE TO BLINK pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, true); @@ -160,16 +150,16 @@ void setup() { diag("Pipe..."); while (!pipe.Init()) { - diag("No pipe. Is it connected?"); + diag("Pipe connected?"); blink(false); } diag("Audio..."); - AudioMemory(20); + AudioMemory(120); AudioProcessorUsageMaxReset(); AudioMemoryUsageMaxReset(); sgtl5000.enable(); - sgtl5000.volume(0.3); + sgtl5000.volume(volume[4]); diag("Synth..."); loadPatch(0); @@ -188,7 +178,7 @@ void setup() { for (int i = 0; i < NUM_DRONES; ++i) { mixDrones.gain(i, 1); } - biquad1.setBandpass(0, PITCH_CONCERT_A4, 1.0); + biquad1.setNotch(0, PITCH_CONCERT_A4, 0.001); diag("Drones..."); playDrones(); @@ -231,12 +221,12 @@ void loop() { // If we're infinitely (for the sensor) off the knee, // we might be in setup mode. - if (pipe.kneeClosedness == 0) { + if (pipe.KneeClosedness == 0) { // We only enter into setup mode if no keys are pressed. // This hopefully avoids accidentally entering setup while playing. // Like say you're playing a jaunty tune and suddenly there's an earthquake. // You ought to be able to finish the tune off before your pipe goes into setup mode. - if (upSetting || (pipe.keys == 0)) { + if (upSetting || (pipe.Keys == 0)) { doSetup(); upSetting = true; return;