cpp conversion
This commit is contained in:
parent
20281ad17a
commit
3f257adf49
5 changed files with 299 additions and 0 deletions
34
CMakeLists.txt
Normal file
34
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
# 1. Generate the map for your Neovim clangd linter
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Include the SDK's CMake entry point
|
||||
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
|
||||
|
||||
project(clock C CXX ASM)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
pico_sdk_init()
|
||||
|
||||
include_directories(include)
|
||||
|
||||
add_executable(clock
|
||||
src/main.cpp
|
||||
src/Gate.cpp
|
||||
)
|
||||
|
||||
# Enable USB output (useful for later printf debugging)
|
||||
pico_enable_stdio_usb(clock 1)
|
||||
pico_enable_stdio_uart(clock 0)
|
||||
|
||||
# Pull in standard library and hardware abstraction
|
||||
target_link_libraries(clock
|
||||
pico_stdlib
|
||||
hardware_gpio
|
||||
hardware_i2c
|
||||
)
|
||||
|
||||
# Create the .uf2 file
|
||||
pico_add_extra_outputs(clock)
|
||||
36
include/Gate.h
Normal file
36
include/Gate.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Gate.h
|
||||
#ifndef Gate_h
|
||||
#define Gate_h
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
class Gate {
|
||||
private:
|
||||
bool state;
|
||||
int16_t cycle;
|
||||
uint32_t dur;
|
||||
uint32_t len;
|
||||
uint8_t width;
|
||||
uint8_t divideMode;
|
||||
uint16_t div;
|
||||
uint16_t modifier;
|
||||
std::string divString;
|
||||
uint8_t p;
|
||||
|
||||
public:
|
||||
Gate(uint8_t pin);
|
||||
uint8_t pin;
|
||||
|
||||
void turnOn();
|
||||
void turnOff();
|
||||
void setLen(uint32_t currentPeriod);
|
||||
void setDiv(uint16_t newDiv, uint8_t divide = 1);
|
||||
void setWidth(uint16_t newWidth);
|
||||
void setP(uint16_t prob);
|
||||
|
||||
bool getState();
|
||||
};
|
||||
|
||||
#endif
|
||||
47
include/globals.h
Normal file
47
include/globals.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef GLOBALS_H
|
||||
#define GLOBALS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#endif // GLOBALS_H
|
||||
|
||||
/*
|
||||
TODO:
|
||||
|
||||
PRE-DAC:
|
||||
[x] Figure out multiplicative beats X2 X4 X8 X16 X32?
|
||||
[ ] Swing/Phase (same thing)
|
||||
[x] Probability
|
||||
[ ] Humanization
|
||||
[ ] Euclidian Rhythms
|
||||
[ ] Steps - # of steps for a full pattern
|
||||
[ ] Hits - how many hits across the steps, must be less than steps
|
||||
[ ] Offset - move the starting point of the pattern
|
||||
[ ] Logic (NO | AND | OR | XOR)
|
||||
[ ] Mute
|
||||
[ ] Save
|
||||
[ ] Load
|
||||
|
||||
POST-DAC:
|
||||
[ ] Different Wave Forms
|
||||
[ ] Different Voltage levels
|
||||
[ ] v/oct?
|
||||
|
||||
100BPM
|
||||
4800BPM
|
||||
|
||||
POSSIBLE DIVISIONS:
|
||||
1: x48
|
||||
16: x32
|
||||
32: x16
|
||||
40: x8
|
||||
44: x4
|
||||
46: x2
|
||||
---
|
||||
48*1: 1 ** THIS NEEDS TO BE PASSED IN AS DIVIDE MODE
|
||||
48*2 = 96: /2
|
||||
48*4 = 192: /4
|
||||
48*8 = /8
|
||||
48*16 = /16
|
||||
|
||||
*/
|
||||
86
src/Gate.cpp
Normal file
86
src/Gate.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// 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;
|
||||
};
|
||||
}
|
||||
|
||||
96
src/main.cpp
Normal file
96
src/main.cpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#include <stdio.h>
|
||||
#include "hardware/structs/rosc.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/time.h"
|
||||
#include <cstdint>
|
||||
|
||||
#include "globals.h"
|
||||
#include "Gate.h"
|
||||
|
||||
static constexpr uint8_t OUT_1_PIN = 0;
|
||||
static constexpr uint8_t OUT_2_PIN = 2;
|
||||
static constexpr uint8_t OUT_3_PIN = 4;
|
||||
static constexpr uint8_t OUT_4_PIN = 6;
|
||||
static constexpr uint8_t OUT_5_PIN = 8;
|
||||
static constexpr uint8_t OUT_6_PIN = 10;
|
||||
static constexpr uint8_t OUT_7_PIN = 12;
|
||||
static constexpr uint8_t OUT_8_PIN = 14;
|
||||
|
||||
static constexpr uint8_t SCREEN_SCL_PIN = 18;
|
||||
static constexpr uint8_t SCREEN_SDA_PIN = 19;
|
||||
|
||||
static constexpr uint8_t ENCODER_CLK_PIN = 20;
|
||||
static constexpr uint8_t ENCODER_DT_PIN = 21;
|
||||
static constexpr uint8_t ENCODER_SW_PIN = 22;
|
||||
|
||||
volatile uint8_t PLAY = 1;
|
||||
volatile uint8_t BPM = 100;
|
||||
|
||||
static constexpr uint32_t MINUTE_US = 60000000;
|
||||
static constexpr uint8_t PPQN = 96;
|
||||
volatile uint32_t period_us = 0;
|
||||
|
||||
struct repeating_timer bpm_timer;
|
||||
|
||||
volatile bool beatToggle = false;
|
||||
|
||||
Gate out1(OUT_1_PIN);
|
||||
Gate out2(OUT_2_PIN);
|
||||
Gate out3(OUT_3_PIN);
|
||||
Gate out4(OUT_4_PIN);
|
||||
Gate out5(OUT_5_PIN);
|
||||
Gate out6(OUT_6_PIN);
|
||||
Gate out7(OUT_7_PIN);
|
||||
Gate out8(OUT_8_PIN);
|
||||
|
||||
|
||||
bool timer_callback(struct repeating_timer *t) {
|
||||
if (PLAY == 1) {
|
||||
beatToggle = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void init_timer(uint32_t period_us) {
|
||||
cancel_repeating_timer(&bpm_timer);
|
||||
add_repeating_timer_us(-(int64_t)period_us, timer_callback, NULL, &bpm_timer);
|
||||
}
|
||||
|
||||
|
||||
void update_period() {
|
||||
period_us = (uint32_t)(MINUTE_US / (uint32_t)BPM / PPQN);
|
||||
init_timer(period_us);
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
|
||||
srand(rosc_hw->randombit);
|
||||
|
||||
gpio_init(out1.pin);
|
||||
gpio_init(out2.pin);
|
||||
gpio_init(out3.pin);
|
||||
gpio_init(out4.pin);
|
||||
gpio_init(out5.pin);
|
||||
gpio_init(out6.pin);
|
||||
gpio_init(out7.pin);
|
||||
gpio_init(out8.pin);
|
||||
|
||||
gpio_set_dir(out1.pin, GPIO_OUT);
|
||||
gpio_set_dir(out2.pin, GPIO_OUT);
|
||||
gpio_set_dir(out3.pin, GPIO_OUT);
|
||||
gpio_set_dir(out4.pin, GPIO_OUT);
|
||||
gpio_set_dir(out5.pin, GPIO_OUT);
|
||||
gpio_set_dir(out6.pin, GPIO_OUT);
|
||||
gpio_set_dir(out7.pin, GPIO_OUT);
|
||||
gpio_set_dir(out8.pin, GPIO_OUT);
|
||||
|
||||
update_period();
|
||||
|
||||
while (true) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue