cleaning up

This commit is contained in:
Dominic DiTaranto 2026-02-23 15:49:26 -05:00
parent 6532b218fe
commit 7fd4600a42
5 changed files with 143 additions and 105 deletions

View file

@ -3,16 +3,14 @@
#define Gate_h
#include <cstdint>
#include <string>
class Gate {
private:
bool state;
int16_t cycle;
uint32_t dur;
uint32_t len;
uint16_t div;
uint32_t lastTriggerTick = 0xFFFFFFFF;
public:
Gate(uint8_t pin);
@ -21,6 +19,8 @@ class Gate {
int8_t modifierSelectionIndex;
uint8_t divideMode;
uint16_t modifier;
uint16_t tickInterval;
bool isEnabled;
uint8_t width;
uint8_t p;
@ -29,9 +29,6 @@ class Gate {
void setLen(uint32_t currentPeriod);
void setDiv(uint8_t modifier_selection_index);
void setWidth(uint16_t newWidth);
void setP(uint16_t prob);
bool getState();
};
#endif

View file

@ -6,6 +6,8 @@
#include <array>
#include <string>
// PINS
static constexpr uint8_t OUT_1_PIN = 0;
static constexpr uint8_t OUT_2_PIN = 2;
static constexpr uint8_t OUT_3_PIN = 4;
@ -22,12 +24,12 @@ static constexpr uint8_t ENCODER_CLK_PIN = 20;
static constexpr uint8_t ENCODER_DT_PIN = 21;
static constexpr uint8_t ENCODER_SW_PIN = 22;
// TIME BASED
extern volatile uint8_t BPM;
static constexpr uint32_t MINUTE_US = 60000000;
static constexpr uint8_t PPQN = 96;
extern volatile uint32_t MASTER_TICK;
static uint32_t MASTER_TICK = 0;
// Modifiers in UI order
static std::array<uint8_t, 10> MODIFIERS = {8, 4, 2, 0, 1, 2, 3, 4, 8, 16};
@ -36,11 +38,15 @@ static std::array<uint8_t, 10> MOD_TYPES = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1};
// Modifier string
static std::array<std::string, 10> MODIFIER_STRINGS = {"x8", "x4", "x2", "x0", "/1", "/2", "/3", "/4", "/8", "/16"};
inline uint32_t millis() {
return to_ms_since_boot(get_absolute_time());
}
inline uint32_t micros() {
return to_us_since_boot(get_absolute_time());
}
#endif // GLOBALS_H

View file

@ -10,8 +10,6 @@
#include "pico-ssd1306/shapeRenderer/ShapeRenderer.h"
#include "pico-ssd1306/textRenderer/TextRenderer.h"
//TODO:
// the pulses are not even... they occur independently of eachother.
pico_ssd1306::SSD1306* display = nullptr;
extern void update_BPM(bool up);

View file

@ -1,20 +1,18 @@
// 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;
modifierSelectionIndex = 3;
editing = 0;
modifierSelectionIndex = 3;
divideMode = 0; // 1 divison | 0 multiplication
modifier = 0; // divide mode modifier (4x, /32, etc)
div = 0; // cycles needed before a pulse based on divide mode and modifier
cycle = 0; // how many cycles have passed since last pulse
dur = 0; // how long pulse is on
width = 50; // pulse width
@ -23,73 +21,134 @@ Gate::Gate(uint8_t pin) {
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(uint8_t modifier_selecton_index) {
printf("HOW ABOUT HERE\n");
uint8_t modifier = MODIFIERS[modifier_selecton_index];
uint8_t mod_type = MOD_TYPES[modifier_selecton_index];
if (mod_type == 1) {
div = PPQN * modifier;
} else {
div = PPQN / modifier;
}
divideMode = mod_type;
this->modifier = modifier;
if (this->modifier == 0) {
turnOff();
switch(modifier_selecton_index) {
case 0: // x8 (32nd triplets)
tickInterval = 8; // 96 / 12 hits per beat
isEnabled = true;
divideMode = 0;
modifier = 8;
break;
case 1: // x4 (16th triplets)
tickInterval = 16; // 96 / 6 hits per beat
isEnabled = true;
divideMode = 0;
modifier = 4;
break;
case 2: // x2 (8th triplets)
tickInterval = 32; // 96 / 3 hits per beat
isEnabled = true;
divideMode = 0;
modifier = 2;
break;
case 3: // 0 (OFF)
tickInterval = 0;
isEnabled = false;
divideMode = 0;
modifier = 0;
break;
case 4: // /1 (Quarter Notes - The Pulse)
tickInterval = 96; // 96 / 1 hit per beat
isEnabled = true;
divideMode = 1;
modifier = 1;
break;
case 5: // /2 (8th Notes)
tickInterval = 192; // 96 * 2 (1 hit every 2 beats)
isEnabled = true;
divideMode = 1;
modifier = 2;
break;
case 6: // /3 (Dotted Quarter or specialized)
tickInterval = 288; // 96 * 3 (1 hit every 3 beats)
isEnabled = true;
divideMode = 1;
modifier = 3;
break;
case 7: // /4 (Whole Notes)
tickInterval = 384; // 96 * 4 (1 hit every 4 beats)
isEnabled = true;
divideMode = 1;
modifier = 4;
break;
case 8: // /8 (2 Bar phrasing)
tickInterval = 768; // 96 * 8 (1 hit every 8 beats)
isEnabled = true;
divideMode = 1;
modifier = 8;
break;
case 9: // /16 (4 Bar phrasing)
tickInterval = 1536; // 96 * 16 (1 hit every 16 beats)
isEnabled = true;
divideMode = 1;
modifier = 16;
break;
default:
tickInterval = 96;
isEnabled = true;
divideMode = 1;
}
// TODO: check if this is actually needed
setWidth(this->width);
};
void Gate::setWidth(uint16_t newWidth) {
width = newWidth;
if (divideMode == 1) {
len = (uint32_t)((double)(MINUTE_US / BPM) * (width / 100.0) / 1000.0);
} else {
len = (uint32_t)((double)(MINUTE_US / BPM / modifier) * (width / 100.0) / 1000.0);
}
};
void Gate::setP(uint16_t prob) {
this->p = prob;
void Gate::setWidth(uint16_t newWidth) {
this->width = newWidth;
double ms_per_tick = (60000.0 / (double)BPM) / 96.0;
double ms_between_triggers = ms_per_tick * (double)this->tickInterval;
this->len = (uint32_t)(ms_between_triggers * (this->width / 100.0));
uint32_t max_allowed_len = (ms_between_triggers > 5) ? (uint32_t)ms_between_triggers - 2 : 1;
if (this->len > max_allowed_len) {
this->len = max_allowed_len;
}
if (this->len < 1) this->len = 1;
}
void Gate::turnOn() {
cycle += 1;
uint8_t pRes = 1;
if (!isEnabled || tickInterval == 0) return;
if (cycle == div) {
if (p < 100) {
uint32_t r = (rand() % 100) + 1;
if (r > p) {
pRes = 0;
}
}
if (MASTER_TICK % tickInterval == 0) {
if (MASTER_TICK != lastTriggerTick) {
lastTriggerTick = MASTER_TICK;
if (pRes == 1) {
state = 1;
gpio_put(pin, state);
dur = millis();
}
cycle = 0;
};
uint8_t pRes = 1;
if (p < 100) {
if ((rand() % 100) + 1 > p) pRes = 0;
}
if (pRes == 1) {
state = 1;
gpio_put(pin, 1);
dur = millis();
}
}
}
else {
lastTriggerTick = 0xFFFFFFFF;
}
}
void Gate::turnOff() {
if (state == 1 && millis() - dur >= len) {
state = 0;
gpio_put(pin, state);
dur = 0;
};
if (state == 1) {
if (millis() - dur >= len) {
state = 0;
gpio_put(pin, 0);
}
}
}

View file

@ -11,14 +11,16 @@
#include "DisplayHandler.h"
#include "EncoderHandler.h"
struct repeating_timer bpm_timer = {0};
// Time based operations
struct repeating_timer bpm_timer = {0};
volatile uint8_t BPM = 60;
volatile uint8_t PLAY = 1;
volatile uint32_t period_us = 0;
volatile uint32_t MASTER_TICK;
volatile bool beatToggle = false;
// Initialize Outputs
Gate out1(OUT_1_PIN);
Gate out2(OUT_2_PIN);
Gate out3(OUT_3_PIN);
@ -30,13 +32,15 @@ Gate out8(OUT_8_PIN);
static Gate* outputs[] = {&out1, &out2, &out3, &out4, &out5, &out6, &out7, &out8};
// Initialize Handlers
static DisplayHandler display_handler(outputs);
static EncoderHandler encoder_handler(&display_handler);
bool timer_callback(struct repeating_timer *t) {
if (PLAY == 1) {
beatToggle = true;
MASTER_TICK += 1;
}
return true;
@ -86,58 +90,32 @@ void setup_outs() {
}
// manual setup
out1.setDiv(1);
// out1.setWidth(50);
//
// out2.setDiv(4, 0);
// out2.setWidth(50);
//
// out3.setDiv(2, 0);
// out3.setWidth(50);
//
// out4.setDiv(1);
// out4.setWidth(50);
//
// out5.setDiv(2);
// out5.setWidth(50);
//
// out6.setDiv(4);
// out6.setWidth(50);
//
// out7.setDiv(8);
// out7.setWidth(50);
//
// out8.setDiv(16);
// out8.setWidth(50);
// out1.setDiv(5);
// out1.setWidth(80);
}
void handle_outs() {
if (beatToggle) {
for (Gate* g: outputs) {
if (g->modifier != 0) {
g->turnOn();
}
}
beatToggle = false;
}
for (Gate* g: outputs) {
if (g->modifier != 0) {
g->turnOff();
}
}
for (Gate* g: outputs) {
g->turnOn();
g->turnOff();
}
}
int main() {
// initialize
stdio_init_all();
// Seed random
srand(rosc_hw->randombit);
// Initialize display and multicore
display_handler.setup();
multicore_launch_core1(core1_entry);
multicore_fifo_push_blocking(1);
// Initialize Encoder
encoder_handler.setup();
setup_outs();