master_clock/src/Gate.cpp
2026-02-19 23:32:34 -05:00

86 lines
1.8 KiB
C++

// Gate.cpp
#include "pico/stdlib.h"
#include "Gate.h"
#include "globals.h"
#include <string>
#include <cstdlib>
Gate::Gate(uint8_t pin) {
this->pin = pin;
state = 0;
divideMode = 1; // 1 divison | 0 multiplication
modifier = 1; // divide mode modifier (4x, /32, etc)
div = 1; // cycles needed before a pulse based on divide mode and modifier
cycle = 0; // how many cycles have passed since last pulse
divString = ""; // string for screen .. probably does not belong here
dur = 0; // how long pulse is on
width = 50; // pulse width
len = 0; // max len a pulse can be on, as determined by width
p = 100; // probability of a pulse
}
bool Gate::getState() {
return state;
}
void Gate::setLen(uint32_t currentPeriod) {
len = (uint32_t)((double)currentPeriod * (width / 100.0) / 1000.0);
}
void Gate::setDiv(uint16_t modifier, uint8_t divide) {
if (divide == 1) {
div = ppqn * modifier;
divString = "/" + std::to_string(modifier);
} else {
div = ppqn / modifier;
divString = "x" + std::to_string(modifier);
}
divideMode = divide;
this->modifier = modifier;
};
void Gate::setWidth(uint16_t newWidth) {
width = newWidth;
if (divideMode == 1) {
len = (uint32_t)((double)(minute / BPM) * (width / 100.0) / 1000.0);
} else {
len = (uint32_t)((double)(minute / BPM / modifier) * (width / 100.0) / 1000.0);
}
};
void Gate::setP(uint16_t prob) {
this->p = prob;
}
void Gate::turnOn() {
cycle += 1;
uint8_t pRes = 1;
if (cycle == div) {
if (p < 100) {
uint32_t r = (rand() % 100) + 1;
if (r > p) {
pRes = 0;
}
}
if (pRes == 1) {
state = 1;
digitalWrite(pin, state);
dur = millis();
}
cycle = 0;
};
}
void Gate::turnOff() {
if (state == 1 && millis() - dur >= len) {
state = 0;
digitalWrite(pin, state);
dur = 0;
};
}