mirror of
https://github.com/bbswitzer/PianoProject
synced 2026-01-16 19:05:11 -05:00
123 lines
3.7 KiB
C++
123 lines
3.7 KiB
C++
#include "sustain.h"
|
|
#include "sustain.h"
|
|
#include "serial.h"
|
|
#include "settings.h"
|
|
|
|
Sustain sustain;
|
|
|
|
Sustain::Sustain()
|
|
{
|
|
//initialize one row of vectors so program won't crash while comparing
|
|
//initialize sustain as off by default
|
|
for(int index = 0; index < 4; index++)
|
|
{
|
|
schedule[index].reserve(6);
|
|
schedule[index].resize(1);
|
|
}
|
|
schedule[OFF].push_back(millis());
|
|
}
|
|
|
|
void Sustain::prepareToSchedule(uint8_t velocity)
|
|
{
|
|
const uint8_t SUSTAIN_MIN_VELOCITY = 64;
|
|
if(Setting::handleNotes && Setting::scheduleNotes)
|
|
{
|
|
if(velocity < SUSTAIN_MIN_VELOCITY)
|
|
{
|
|
scheduleSustain(false);
|
|
} else if(instances == 0) //only schedule if sustain is off
|
|
scheduleSustain(true);
|
|
} else
|
|
{
|
|
if(velocity < SUSTAIN_MIN_VELOCITY)
|
|
ledcWrite(0, 0);
|
|
else
|
|
ledcWrite(0, 255);
|
|
}
|
|
}
|
|
|
|
void Sustain::checkSchedule()
|
|
{
|
|
unsigned long ms = millis();
|
|
//less checks for sustain because it's slower and less important
|
|
if(schedule[OFF].size() > 1 && schedule[DEACTIVATION].size() > 1 &&
|
|
ms >= schedule[OFF].at(1) && schedule[OFF].at(1) >= schedule[DEACTIVATION].at(1))
|
|
{
|
|
schedule[DEACTIVATION].erase(schedule[DEACTIVATION].begin()++);
|
|
ledcWrite(0, 0);
|
|
}
|
|
if(schedule[ACTIVATION].size() > 1 && schedule[OFF].size() > 1 &&
|
|
ms >= schedule[ACTIVATION].at(1) && schedule[ACTIVATION].at(1) >= schedule[OFF].at(1))
|
|
{
|
|
schedule[OFF].erase(schedule[OFF].begin()++);
|
|
ledcWrite(0, 255);
|
|
}
|
|
if(schedule[ON].size() > 1 && schedule[ACTIVATION].size() > 1 &&
|
|
ms >= schedule[ON].at(1) && schedule[ON].at(1) >= schedule[ACTIVATION].at(1))
|
|
{
|
|
schedule[ACTIVATION].erase(schedule[ACTIVATION].begin()++);
|
|
}
|
|
if(schedule[DEACTIVATION].size() > 1 && schedule[ON].size() > 1 &&
|
|
ms >= schedule[DEACTIVATION].at(1) && schedule[DEACTIVATION].at(1) >= schedule[ON].at(1))
|
|
{
|
|
schedule[ON].erase(schedule[ON].begin()++);
|
|
ledcWrite(0, 30);
|
|
}
|
|
}
|
|
|
|
void Sustain::checkForErrors()
|
|
{
|
|
unsigned long ms = millis();
|
|
if(ms >= timeSinceActivation + Setting::sustainTimeoutMs && timeSinceActivation > 0) resetSchedule();
|
|
if(schedule[ON].size() > 1) if(ms >= schedule[ON].at(1) + Setting::sustainTimeoutMs) resetSchedule();
|
|
}
|
|
|
|
void Sustain::resetSchedule()
|
|
{
|
|
for(int index = 0; index < 4; index++)
|
|
schedule[index].resize(1);
|
|
schedule[OFF].push_back(millis());
|
|
timeSinceActivation = 0;
|
|
instances = 0;
|
|
ledcWrite(0, 0);
|
|
}
|
|
|
|
void Sustain::scheduleSustain(bool state)
|
|
{
|
|
unsigned long ms = millis();
|
|
unsigned long msAndDelay = ms + fullDelay;
|
|
using namespace Setting;
|
|
|
|
if(state)
|
|
{
|
|
if(msAndDelay - sustainOnMs >= schedule[OFF].back()) //if sustain can be scheduled with current scheduling
|
|
{
|
|
schedule[ACTIVATION].push_back(msAndDelay - sustainOnMs);
|
|
schedule[ON]. push_back(msAndDelay);
|
|
timeSinceActivation = ms;
|
|
instances++;
|
|
} else if(msAndDelay - sustainOffMs - sustainOnMs >= schedule[ON].back()) //if current scheduling can be modified to still schedule the sustain
|
|
{
|
|
schedule[ON]. push_back(msAndDelay - sustainOnMs - sustainOffMs);
|
|
schedule[ON]. erase(----schedule[ON].end());
|
|
schedule[OFF]. push_back(msAndDelay - sustainOnMs);
|
|
schedule[OFF]. erase(----schedule[OFF].end());
|
|
schedule[ACTIVATION].push_back(msAndDelay - sustainOnMs);
|
|
schedule[ON]. push_back(msAndDelay);
|
|
timeSinceActivation = ms;
|
|
instances++;
|
|
}
|
|
} else if(instances > 0) //if sustain off command and sustain is not already off
|
|
{
|
|
instances = 0;
|
|
if(msAndDelay - sustainOffMs >= schedule[ON].back()) //if sustain can be ideally deactivated
|
|
{
|
|
schedule[DEACTIVATION].push_back(msAndDelay - sustainOffMs);
|
|
schedule[OFF]. push_back(msAndDelay);
|
|
} else //deactivate sustain anyways so it's not stuck on
|
|
{
|
|
schedule[DEACTIVATION].push_back(msAndDelay);
|
|
schedule[OFF]. push_back(msAndDelay + sustainOffMs);
|
|
}
|
|
}
|
|
} |