Compare commits

...

2 Commits

4 changed files with 44 additions and 64 deletions

View File

@ -51,7 +51,6 @@ void doPlay(bool forceDisplayUpdate) {
updateDisplay = true;
}
#if 0
if (updateDisplay) {
// Look up the note name
const char *noteName = NoteName(pipe.CurrentNote);
@ -69,5 +68,4 @@ void doPlay(bool forceDisplayUpdate) {
display.display();
last_note = pipe.CurrentNote;
}
#endif
}

View File

@ -17,15 +17,7 @@ bool Pipe::Init() {
return false;
}
// 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
bag_enabled = bagSensor.isConnected();
return true;
}
@ -37,29 +29,31 @@ void Pipe::Update() {
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();
// XXX: re-enable the bag sensor at some point
//Bag = bagSensor.isPressed();
} else {
Bag = false;
}
// 0x6c is actually 8 bytes, but all 8 are always the same...
KneeClosedness = 255 - kneeSensor.readRange();
for (int i = 0; i < NUM_KEYS; ++i) {
int key = KeySensor[i];
if (key == -1) {
continue;
}
uint16_t sensorReading = capSensor.filteredData(i);
uint16_t val = OPENVAL - min(max(sensorReading, CLOSEDVAL), OPENVAL);
KeyPressure[i] = val / float(GLISSANDO_STEPS);
KeyPressure[key] = 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 (KeyPressure[i] > 0.0) {
bitSet(Keys, i);
if (KeyPressure[key] > 0.0) {
bitSet(Keys, key);
}
if (KeyPressure[i] == 1.0) {
bitSet(glissandoKeys, i);
if (KeyPressure[key] == 1.0) {
bitSet(glissandoKeys, key);
}
}
@ -81,6 +75,9 @@ void Pipe::Update() {
// Was the high bit set? That indicates "alternate fingering", which sounds different.
AltFingering = f.alt;
// All keys closed + knee = no sound
Silent = ((KeyPressure[11] > 0) && (CurrentNote == NOTE_D4));
// If the bag is squished, jump up an octave
// But only if the left thumb is down!
if (Bag && (Keys & bit(7))) {
@ -88,8 +85,6 @@ void Pipe::Update() {
GlissandoNote += NOTE_OCTAVE;
}
// All keys closed + knee = no sound
Silent = ((KneeClosedness > 240) && (Keys == 0xff));
}
bool Pipe::Pressed(uint8_t key) {

8
pipe.h
View File

@ -8,6 +8,9 @@
#define NUM_KEYS 12
// A mapping of MPR121 input to pipe key
const int KeySensor[NUM_KEYS] = { 11, -1, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1 };
enum Adjust {
ADJUST_DOWN = -1,
ADJUST_NONE = 0,
@ -17,9 +20,6 @@ enum Adjust {
class Pipe {
public:
// kneeClosedness indicates how "closed" the knee sensor is. 0 = wide open.
uint8_t KneeClosedness;
// keys are which keys are being pressed.
uint16_t Keys;
uint16_t KeysLast;
@ -70,8 +70,6 @@ class Pipe {
private:
Adafruit_MPR121 capSensor;
Adafruit_VL6180X kneeSensor;
QwiicButton bagSensor;
bool bag_enabled;
unsigned long nextRepeat[NUM_KEYS];
bool typematicEvent(uint8_t key, uint16_t delay, uint16_t repeat);

View File

@ -11,16 +11,15 @@
const char *buildDate = __DATE__;
#if defined(ADAFRUIT_TRELLIS_MAdafruit_SSD1306EXPRESS)
#include <Adafruit_NeoTrellisM4.h>
Adafruit_NeoTrellisM4 trellis; // = Adafruit_NeoTrellisM4();
#endif
Adafruit_NeoTrellisM4 trellis = Adafruit_NeoTrellisM4();
Pipe pipe;
Tuning tuning = Tuning(NOTE_D4, PITCH_CONCERT_D4, TUNINGSYSTEM_JUST);
Adafruit_SSD1306 display(128, 32, &Wire, -1);
// Settings
#define VOLUME_INITIAL 0.8
uint8_t patch[4] = {0};
@ -40,13 +39,7 @@ AudioMixer4 mixL;
AudioMixer4 mixR;
AudioSynthNoiseWhite noise;
#if defined(ADAFRUIT_TRELLIS_M4_EXPRESS)
AudioOutputAnalogStereo out1;
#else
AudioOutputI2S out1;
#endif
AudioControlSGTL5000 sgtl5000;
AudioConnection FMVoicePatchCords[] = {
{noise, 0, mixL, 3},
@ -80,15 +73,18 @@ AudioConnection FMVoicePatchCords[] = {
FMVoiceWiring(Regulators[2]),
};
void blink(bool forever) {
void blink(int count, bool forever) {
for (;;) {
digitalWrite(LED_BUILTIN, true);
delay(200);
digitalWrite(LED_BUILTIN, false);
delay(200);
for (int i = 0; i < count; i++) {
digitalWrite(LED_BUILTIN, true);
delay(200);
digitalWrite(LED_BUILTIN, false);
delay(200);
}
if (!forever) {
return;
}
delay(1200);
}
}
@ -139,34 +135,30 @@ void setup() {
// Initialize display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) {
blink(true);
blink(2, true);
}
digitalWrite(LED_BUILTIN, false);
diag("Hello!");
#if defined(ADAFRUIT_TRELLIS_M4_EXPRESS)
diag("Trellis...");
trellis.begin();
#endif
diag("Pipe...");
while (!pipe.Init()) {
diag("Pipe connected?");
blink(false);
blink(3, false);
}
diag("Audio...");
AudioMemory(120);
AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset();
sgtl5000.enable();
sgtl5000.volume(volume[4]);
diag("Synth...");
loadPatch(0);
loadPatch(1);
loadPatch(2);
noise.amplitude(1.0);
noise.amplitude(0.0);
diag("Mixer...");
// Turn on all mixer channels
@ -216,23 +208,20 @@ void loop() {
static bool upSetting = true; // GET IT?
pipe.Update();
#if defined(ADAFRUIT_TRELLIS_M4_EXPRESS)
trellis.tick();
#endif
// If we're infinitely (for the sensor) off the knee,
// we might be in setup mode.
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)) {
doSetup();
upSetting = true;
return;
}
if (trellis.justPressed(0)) {
upSetting = !upSetting;
}
if (upSetting) {
trellis.setPixelColor(0, 0x200000);
doSetup();
return;
}
for (int i = 0; i < 12; i += 1) {
trellis.setPixelColor(i, 0xffffff * pipe.KeyPressure[i]);
}
doPlay(upSetting);