uilleann/pipe.cpp

137 lines
3.0 KiB
C++
Raw Permalink Normal View History

2020-11-11 20:20:21 -07:00
#include "pipe.h"
#include "fingering.h"
#include "tuning.h"
2020-11-11 20:20:21 -07:00
#define CLOSEDVAL 0x30
#define OPENVAL 0x70
#define GLISSANDO_STEPS (OPENVAL - CLOSEDVAL)
Pipe::Pipe() {
2020-11-26 18:49:09 -07:00
KeysLast = 0;
2020-11-11 20:20:21 -07:00
}
bool Pipe::Init() {
// Capacative touch sensor
if (!capSensor.begin(0x5A)) {
return false;
}
2020-11-26 18:49:09 -07:00
// Bag button
2020-11-11 20:20:21 -07:00
return true;
2020-11-11 20:20:21 -07:00
}
void Pipe::Update() {
uint8_t glissandoKeys = 0;
2020-11-26 18:49:09 -07:00
KeysLast = Keys;
Keys = 0;
2020-11-25 17:13:54 -07:00
// Read the bag state, if there's a bag.
if (bag_enabled) {
// XXX: re-enable the bag sensor at some point
//Bag = bagSensor.isPressed();
} else {
2020-11-26 18:49:09 -07:00
Bag = false;
}
2020-11-25 21:53:45 -07:00
for (int i = 0; i < NUM_KEYS; ++i) {
int key = KeySensor[i];
if (key == -1) {
continue;
}
2020-11-26 18:49:09 -07:00
uint16_t sensorReading = capSensor.filteredData(i);
uint16_t val = OPENVAL - min(max(sensorReading, CLOSEDVAL), OPENVAL);
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[key] > 0.0) {
bitSet(Keys, key);
2020-11-11 20:20:21 -07:00
}
if (KeyPressure[key] == 1.0) {
bitSet(glissandoKeys, key);
2020-11-11 20:20:21 -07:00
}
}
2020-11-11 20:20:21 -07:00
2020-11-25 21:53:45 -07:00
// Compute glissando amount
2020-11-26 18:49:09 -07:00
GlissandoPressure = 1.0;
2020-11-25 21:53:45 -07:00
for (int i = 0; i < 8; ++i) {
2020-11-26 18:49:09 -07:00
if (KeyPressure[i] > 0) {
GlissandoPressure = min(GlissandoPressure, KeyPressure[i]);
}
2020-11-25 21:53:45 -07:00
}
// Look up notes in the big table
2020-11-26 18:49:09 -07:00
struct Fingering f = FingeredNote(Keys);
2020-11-25 17:13:54 -07:00
struct Fingering gf = FingeredNote(glissandoKeys);
2020-11-11 20:20:21 -07:00
2020-11-26 18:49:09 -07:00
CurrentNote = f.note;
GlissandoNote = gf.note;
2020-11-11 20:20:21 -07:00
// Was the high bit set? That indicates "alternate fingering", which sounds different.
2020-11-26 18:49:09 -07:00
AltFingering = f.alt;
2020-11-11 20:20:21 -07:00
// 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!
2020-11-26 18:49:09 -07:00
if (Bag && (Keys & bit(7))) {
CurrentNote += NOTE_OCTAVE;
GlissandoNote += NOTE_OCTAVE;
}
2020-11-11 20:20:21 -07:00
}
2020-11-24 16:56:58 -07:00
bool Pipe::Pressed(uint8_t key) {
2020-11-26 18:49:09 -07:00
return bitRead(Keys, key);
2020-11-24 16:56:58 -07:00
}
bool Pipe::JustPressed(uint8_t key) {
2020-11-26 18:49:09 -07:00
if (bitRead(Keys, key)) {
return !bitRead(KeysLast, key);
}
return false;
2020-11-24 16:56:58 -07:00
}
2020-11-25 17:13:54 -07:00
bool Pipe::typematicEvent(uint8_t key, uint16_t delay, uint16_t repeat) {
if (Pressed(key)) {
unsigned long now = millis();
if (JustPressed(key)) {
nextRepeat[key] = now + max(delay, repeat);
return true;
}
if (now >= nextRepeat[key]) {
nextRepeat[key] = now + repeat;
return true;
}
}
return false;
}
Adjust Pipe::ReadAdjust(uint8_t keyUp, uint8_t keyDown, uint16_t delay, uint16_t repeat) {
bool eventUp = typematicEvent(keyUp, delay, repeat);
bool eventDown = typematicEvent(keyDown, delay, repeat);
if (Pressed(keyUp) && Pressed(keyDown)) {
unsigned long nr = max(nextRepeat[keyUp], nextRepeat[keyDown]);
nextRepeat[keyUp] = nr;
nextRepeat[keyDown] = nr;
}
if (eventUp && eventDown) {
return ADJUST_BOTH;
} else if (eventUp) {
return ADJUST_UP;
} else if (eventDown) {
return ADJUST_DOWN;
}
return ADJUST_NONE;
2020-11-26 18:49:09 -07:00
}