Skip to content

Commit

Permalink
#5 Clock input basics are working
Browse files Browse the repository at this point in the history
Steps are ocassionally lost but I can tackle that in another issue
  • Loading branch information
wraybowling committed Sep 2, 2020
1 parent e37bff8 commit 01575e7
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 82 deletions.
9 changes: 9 additions & 0 deletions equations/clock.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
i, sync rising, time, last_sync, delta
1, 1, 0, 0, 0
2, 0, 10, 0, 0
3, 0, 20, 10, 10
4, 0, 30, 20, 10
5, 1, 40, 30, 10
6, 0, 50, 40, 10
7, 0, 60, 50, 10
8, 0, 70, 60, 10
8 changes: 4 additions & 4 deletions src/DebouncedBoolean.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Best used on continuously read logic inputs
*
* set() shifts truthiness into the past
* isFresh() only returns true if no past value is true
* isRising() only returns true if no past value is true
*/

#pragma once
Expand All @@ -14,15 +14,15 @@ class DebouncedBoolean {

bool state[2] = {false};

void set(bool value){
void set(bool value) {
state[0] = state[1];
state[1] = value;
}

bool isFresh(){
bool isRising() {
return state[0] == false && state[1] == true;
}
void reset(){
void reset() {
state[2] = {false};
}
};
55 changes: 22 additions & 33 deletions src/clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,41 @@
*/

#include "clock.h"
#include "lights.h"

bool Clock::isHigh(uint16_t sync_voltage, uint16_t division_knob, uint32_t time) {

// measure time delta
const uint8_t DELTA = time - prev_time;
prev_time = time;
// get multiplier from knob
const int8_t KNOB_STEP = (division_knob * 5 + 512) >> 10; // >>10 quick divides by 1023

// measure time between syncs
const uint32_t PROGRESS = time - time_of_last_sync;

// reset if sync is rising
// if sync is rising
sync_debounce.set(sync_voltage > LOGIC_HIGH);
if (sync_debounce.isFresh()) {
if (sync_debounce.isRising()) {

// predict milliseconds of period
// ignoring clock division
period_prediction = predictor.Predict(DELTA);
reset();
return true;
} else {
period_accumulation += DELTA;
}
// repredict milliseconds of period
period_prediction = predictor.Predict(PROGRESS);
reset(time);

// get multiplier from knob
const int8_t KNOB_STEP = (division_knob * 5 + 512) >> 10; // quick divide by 1023

// if no division, duration of 1 pulse at 24ppqn is the same as period
if(KNOB_STEP == 0){
slot_duration = period_prediction;
} else if (KNOB_STEP == 1) {
// 16ppqn * 3/2 = 24ppqn
slot_duration = period_prediction * 1.5;
} else {
// 8ppqn, 4ppqn, 2ppqn, 1ppqn
const uint16_t MULTIPLIER = pow(2, KNOB_STEP - 2) * 3;
slot_duration = period_prediction * MULTIPLIER;
// no further logic is necessary if no multiplier
if (KNOB_STEP == 0) return true;
}

// if pulse has advanced, return true
const uint8_t PULSE_NUMBER = period_accumulation / slot_duration;
if(pulse_counter < 24 && PULSE_NUMBER > pulse_counter){
pulse_counter++;
const uint8_t MULTIPLIER = pow(2, KNOB_STEP - 1) * 3;

const uint16_t PULSE_NUMBER = PROGRESS * MULTIPLIER / period_prediction;
lights(0, PULSE_NUMBER);

if(PULSE_NUMBER != prev_pulse_number){
prev_pulse_number = PULSE_NUMBER;
return true;
}

return false;
}

void Clock::reset() {
pulse_counter = 0;
period_accumulation = 0;
void Clock::reset(uint32_t time) {
time_of_last_sync = time;
}
18 changes: 7 additions & 11 deletions src/clock.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
#ifndef CLOCK_H
#define CLOCK_H
#pragma once

#include "preferences.h"
#include "peaks_pattern_predictor.h"
#include "DebouncedBoolean.h"

class Clock {
private:
uint32_t prev_time;

DebouncedBoolean sync_debounce;

PatternPredictor<32, 8> predictor;
uint16_t period_prediction;
uint16_t period_accumulation;
uint8_t slot_duration;

uint8_t pulse_counter = 0;
uint32_t time_of_last_sync;
uint32_t period_prediction;
uint16_t prev_pulse_number;

public:
Clock() {
predictor.Init();
}
bool isHigh(uint16_t sync_voltage, uint16_t division_knob, uint32_t time);
void reset();
void reset(uint32_t time);
};

#endif
30 changes: 15 additions & 15 deletions src/grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
* weight for all channels at once in a single 8-bit byte
*/

#include <EEPROM.h>
// #include <EEPROM.h>

#define RESOLUTION 24 * 16

uint8_t * getWeight(uint16_t pulse, uint8_t width) {
uint8_t getWeight(uint16_t pulse, uint8_t width) {
// all 3 channels' weights as expressed by:
// 00110000 top
// 00001100 left
Expand All @@ -21,20 +19,22 @@ uint8_t * getWeight(uint16_t pulse, uint8_t width) {
// 11 3
uint8_t weight_byte = 0;
for(uint16_t i=pulse; i<width; i++){
weight_byte |= EEPROM.read(i % RESOLUTION);
// weight_byte |= EEPROM.read(i % RESOLUTION);
weight_byte = B00010101;
}
static uint8_t weights[3];
weights[0] = ((weight_byte & B00110000) >> 4);
weights[1] = ((weight_byte & B00001100) >> 2);
weights[2] = (weight_byte & B00000011);
return weight_byte;
// static uint8_t weights[3];
// weights[0] = ((weight_byte & B00110000) >> 4);
// weights[1] = ((weight_byte & B00001100) >> 2);
// weights[2] = (weight_byte & B00000011);

return weights;
// return weights;
}

void setWeight(uint16_t pulse, bool top, bool left, bool right) {
uint8_t memory_byte = EEPROM.read(pulse)
- B00010000 * !top
- B00000100 * !left
- B00000001 * !right;
EEPROM.write(pulse, memory_byte);
// uint8_t memory_byte = EEPROM.read(pulse)
// - B00010000 * !top
// - B00000100 * !left
// - B00000001 * !right;
// EEPROM.write(pulse, memory_byte);
}
32 changes: 17 additions & 15 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "preferences.h"
#include "pins.h"
#include "multiplexer.h"
#include "lights.h"
// #include "lights.h"
#include "grid.h"
#include "clock.h"
#include "DebouncedBoolean.h"
Expand Down Expand Up @@ -65,12 +65,8 @@ void loop() {
rightPressed.set(digitalRead(right_button));
uint16_t clock_div_knob__val = getTrigerMux(clock_div_knob);
uint8_t threshold = getTrigerMux(roll_rate_knob) * 4 / 1024;

uint32_t time = millis();

uint8_t *weights;

// set state
uint8_t weights[3];

// clock advancement
if( clock.isHigh(this_clock_in, clock_div_knob__val, time) ) {
Expand All @@ -80,16 +76,19 @@ void loop() {
// full roll rate acts as original gate
setWeight(
step,
topPressed.isFresh(),
leftPressed.isFresh(),
rightPressed.isFresh()
topPressed.isRising(),
leftPressed.isRising(),
rightPressed.isRising()
);

//advance clock
clock_until = time + 25;

//advance outputs
weights = getWeight(step, 1);
uint8_t weight_byte = getWeight(step, threshold);
weights[0] = ((weight_byte & B00110000) >> 4);
weights[1] = ((weight_byte & B00001100) >> 2);
weights[2] = (weight_byte & B00000011);
if(weights[0] > threshold) {
top_until = time + 25;
}
Expand All @@ -102,8 +101,8 @@ void loop() {

//advance step
step = (step+1) % RESOLUTION;

}
prev_clock_in = this_clock_in;

// cv outputs
digitalWrite(left_out, (left_until > time));
Expand All @@ -120,23 +119,26 @@ void loop() {
1
};
short viz = 4 * step / RESOLUTION;

uint8_t grw = 0
// reds
+ B01000000 * brightness[weights[0]]
+ B00010000 * brightness[weights[0]]
+ B00000100 * brightness[weights[0]]
+ B00010000 * brightness[weights[1]]
+ B00000100 * brightness[weights[2]]
;

uint8_t oranges = 0
+ tracker[viz] * (viz == 0 ? 1 : brightness[2])
+ threshold
+ (step & B1111)
// + B1000 * brightness[leftGrid.get_weight(step+0, 1)]
// + B0100 * brightness[leftGrid.get_weight(step+1, 1)]
// + B0010 * brightness[leftGrid.get_weight(step+2, 1)]
// + B0001 * brightness[leftGrid.get_weight(step+3, 1)]
;

lights(grw, oranges);
// lights(grw, (step & 255));


pwm = (pwm+1) % 80;

}
5 changes: 1 addition & 4 deletions src/multiplexer.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef MULTIPLEXER_H
#define MULTIPLEXER_H
#pragma once
/**
* multiplexed analog signals
* all are read on A6 via the getMux() function
Expand Down Expand Up @@ -30,5 +29,3 @@ bool getHostMode()
return 0; //slave
return 1; //normal
}

#endif
2 changes: 2 additions & 0 deletions src/preferences.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
#define PPQN 24 // pulses per quarter note
#define RESOLUTION (PPQN * 16) // 16 quarter notes
#define NOISE_FLOOR 128 // out of 1024
#define LOGIC_HIGH 900 // out of 1024

0 comments on commit 01575e7

Please sign in to comment.