main: move more tiny objects out of main.cpp
This commit is contained in:
5
src/inputs/BPM.cpp
Normal file
5
src/inputs/BPM.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "./BPM.h"
|
||||
#include "../Static.h"
|
||||
|
||||
STATIC_ALLOC(BPM);
|
||||
STATIC_TASK(BPM);
|
52
src/inputs/BPM.h
Normal file
52
src/inputs/BPM.h
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
#include <Figments.h>
|
||||
|
||||
class BPM : public InputSource {
|
||||
public:
|
||||
BPM() : InputSource("BPM") {}
|
||||
void handleEvent(const InputEvent& evt) override {
|
||||
if (evt.intent == InputEvent::BeatDetect) {
|
||||
m_nextBpm = millis();
|
||||
m_timings.insert(millis());
|
||||
Log.notice("%d timings", m_timings.size());
|
||||
if (m_timings.size() >= 5) {
|
||||
updateBPM();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputEvent read() override {
|
||||
if (m_bpm > 0) {
|
||||
uint16_t now = millis();
|
||||
if (now >= m_nextBpm) {
|
||||
m_nextBpm += m_bpm;
|
||||
return InputEvent{InputEvent::Beat, m_bpm};
|
||||
}
|
||||
if (now >= m_nextLearn && m_nextLearn != 0) {
|
||||
m_timings.clear();
|
||||
m_nextLearn = 0;
|
||||
}
|
||||
}
|
||||
return InputEvent{};
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t m_bpm = 0;
|
||||
uint16_t m_nextBpm = 0;
|
||||
uint16_t m_nextLearn = 0;
|
||||
Ringbuf<uint16_t, 7> m_timings;
|
||||
|
||||
void updateBPM() {
|
||||
uint16_t avgDelta = 0;
|
||||
for(uint8_t i = 0; i < m_timings.size() - 1; i++) {
|
||||
uint16_t delta = m_timings.peek(i+1) - m_timings.peek(i);
|
||||
Log.notice("Timing %d Delta %d", m_timings.peek(i), delta);
|
||||
avgDelta += delta;
|
||||
}
|
||||
m_bpm = avgDelta / 4;
|
||||
m_nextLearn = m_bpm * 5 + millis();
|
||||
Log.notice("BPM is now %d", m_bpm);
|
||||
uint16_t trash;
|
||||
m_timings.take(trash);
|
||||
}
|
||||
};
|
5
src/inputs/CircadianRhythm.cpp
Normal file
5
src/inputs/CircadianRhythm.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "./CircadianRhythm.h"
|
||||
#include "../Static.h"
|
||||
|
||||
STATIC_ALLOC(CircadianRhythm);
|
||||
STATIC_TASK(CircadianRhythm);
|
90
src/inputs/CircadianRhythm.h
Normal file
90
src/inputs/CircadianRhythm.h
Normal file
@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
#include <Figments.h>
|
||||
|
||||
struct ScheduleEntry {
|
||||
uint8_t hour;
|
||||
uint8_t brightness;
|
||||
};
|
||||
|
||||
std::array<ScheduleEntry, 10> schedule{{
|
||||
{0, 0},
|
||||
{5, 0},
|
||||
{6, 0},
|
||||
{7, 10},
|
||||
{8, 80},
|
||||
{11, 120},
|
||||
{18, 200},
|
||||
{19, 255},
|
||||
{22, 120},
|
||||
{23, 20}
|
||||
}};
|
||||
|
||||
class CircadianRhythm : public InputSource {
|
||||
private:
|
||||
bool needsUpdate = true;
|
||||
public:
|
||||
CircadianRhythm() : InputSource("CircadianRhythm") {}
|
||||
|
||||
void onStart() {
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
uint8_t brightnessForTime(uint8_t hour, uint8_t minute) const {
|
||||
ScheduleEntry start = schedule.back();
|
||||
ScheduleEntry end = schedule.front();
|
||||
for(ScheduleEntry cur : schedule) {
|
||||
// Find the last hour that is prior to or equal to now
|
||||
if (cur.hour <= hour) {
|
||||
start = cur;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(ScheduleEntry cur : schedule) {
|
||||
// Find the first hour that is after now
|
||||
// If no such hour exists, we should automatically wrap back to hour 0
|
||||
if (cur.hour > hour) {
|
||||
end = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (start.hour > end.hour) {
|
||||
end.hour += 24;
|
||||
}
|
||||
|
||||
uint16_t startTime = start.hour * 60;
|
||||
uint16_t endTime = end.hour * 60;
|
||||
uint16_t nowTime = hour * 60 + minute;
|
||||
|
||||
uint16_t duration = endTime - startTime;
|
||||
uint16_t curDuration = nowTime - startTime;
|
||||
|
||||
uint8_t frac = map8(curDuration, 0, duration);
|
||||
|
||||
return lerp8by8(start.brightness, end.brightness, frac);
|
||||
}
|
||||
|
||||
|
||||
InputEvent read() {
|
||||
EVERY_N_SECONDS(60) {
|
||||
needsUpdate = true;
|
||||
}
|
||||
if (needsUpdate) {
|
||||
uint8_t hour = 0;
|
||||
uint8_t minute = 0;
|
||||
needsUpdate = false;
|
||||
struct tm timeinfo;
|
||||
if (Platform::getLocalTime(&timeinfo)) {
|
||||
hour = timeinfo.tm_hour;
|
||||
minute = timeinfo.tm_min;
|
||||
} else {
|
||||
hour = 0;
|
||||
minute = 0;
|
||||
}
|
||||
Log.notice("Current time: %d:%d", hour, minute);
|
||||
return InputEvent{InputEvent::SetBrightness, brightnessForTime(hour, minute)};
|
||||
}
|
||||
return InputEvent{};
|
||||
}
|
||||
};
|
5
src/inputs/ConfigInput.cpp
Normal file
5
src/inputs/ConfigInput.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "./ConfigInput.h"
|
||||
#include "./Static.h"
|
||||
|
||||
STATIC_ALLOC(ConfigInput);
|
||||
STATIC_TASK(ConfigInput);
|
77
src/inputs/ConfigInput.h
Normal file
77
src/inputs/ConfigInput.h
Normal file
@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
#include <Figments.h>
|
||||
|
||||
class ConfigInputTask : public BufferedInputSource {
|
||||
public:
|
||||
ConfigInputTask() : BufferedInputSource("ConfigInput") {}
|
||||
|
||||
void handleEvent(const InputEvent& evt) override {
|
||||
if (evt.intent == InputEvent::UserInput) {
|
||||
Buttons::Chord chord = (Buttons::Chord) evt.asInt();
|
||||
switch (chord) {
|
||||
case Buttons::Circle:
|
||||
m_currentIntent = nextIntent();
|
||||
//Log.info("Next setting... (%d)", m_currentIntent);
|
||||
break;
|
||||
case Buttons::CircleTriangle:
|
||||
//Log.info("Increment...");
|
||||
increment();
|
||||
break;
|
||||
case Buttons::CircleCross:
|
||||
//Log.info("Decrement...");
|
||||
decrement();
|
||||
break;
|
||||
case Buttons::Triangle:
|
||||
//Log.info("Save...");
|
||||
setEvent(InputEvent::SaveConfigurationRequest);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
InputEvent::Intent m_currentIntent = InputEvent::SetDisplayLength;
|
||||
|
||||
void decrement() {
|
||||
int current = 0;
|
||||
switch (m_currentIntent) {
|
||||
case InputEvent::SetDisplayLength:
|
||||
current = Static<ConfigService>::instance()->coordMap()->pixelCount;
|
||||
break;
|
||||
case InputEvent::SetDisplayOffset:
|
||||
current = Static<ConfigService>::instance()->coordMap()->startPixel;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setEvent(InputEvent{m_currentIntent, current - 1});
|
||||
}
|
||||
|
||||
void increment() {
|
||||
int current = 0;
|
||||
switch (m_currentIntent) {
|
||||
case InputEvent::SetDisplayLength:
|
||||
current = Static<ConfigService>::instance()->coordMap()->pixelCount;
|
||||
break;
|
||||
case InputEvent::SetDisplayOffset:
|
||||
current = Static<ConfigService>::instance()->coordMap()->startPixel;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setEvent(InputEvent{m_currentIntent, current + 1});
|
||||
}
|
||||
|
||||
InputEvent::Intent nextIntent() {
|
||||
switch (m_currentIntent) {
|
||||
case InputEvent::SetDisplayLength:
|
||||
return InputEvent::SetDisplayOffset;
|
||||
case InputEvent::SetDisplayOffset:
|
||||
return InputEvent::SetDisplayLength;
|
||||
default:
|
||||
return InputEvent::None;
|
||||
}
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user