Compare commits
No commits in common. "774980200c2d3c94aa7f451c07fd1d6ec914f7ae" and "09b1a6707acd53c886ce00b088dc7c64ab4c9d3e" have entirely different histories.
774980200c
...
09b1a6707a
File diff suppressed because one or more lines are too long
27
buttons.c
27
buttons.c
@ -4,21 +4,22 @@
|
||||
#include <pico/types.h>
|
||||
#include "hardware/gpio.h"
|
||||
|
||||
void check_button_change(uint pin, bool* btn_state) {
|
||||
static bool btn_prev[32] = { false };
|
||||
bool btn_now = gpio_get(pin);
|
||||
if (btn_now && !btn_prev[pin]) *btn_state = !*btn_state;
|
||||
btn_prev[pin] = btn_now;
|
||||
}
|
||||
void handle_vco_change(void) {
|
||||
static bool btn_prev = false;
|
||||
|
||||
void update_buttons() {
|
||||
check_button_change(QUANT_BUTTON, &state.quant_enabled);
|
||||
check_button_change(AMEN_BUTTON, &state.amen_enabled);
|
||||
|
||||
bool vco_change;
|
||||
check_button_change(VCO_BUTTON, &vco_change);
|
||||
if (vco_change) {
|
||||
bool btn_now = gpio_get(VCO_BUTTON);
|
||||
if (btn_now && !btn_prev) {
|
||||
if (state.vco_mode == VCO_SAW) state.vco_mode = VCO_SINE;
|
||||
otherwise state.vco_mode++;
|
||||
}
|
||||
}
|
||||
|
||||
void update_button(uint pin, bool *button_state) {
|
||||
if(gpio_get(pin) != *button_state) *button_state = !*button_state;
|
||||
}
|
||||
|
||||
void update_buttons() {
|
||||
update_button(QUANT_BUTTON, &state.quant_enabled);
|
||||
update_button(AMEN_BUTTON, &state.amen_enabled);
|
||||
handle_vco_change();
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include <pico/types.h>
|
||||
|
||||
void handle_vco_change(uint gpio, uint32_t events);
|
||||
void update_button(uint pin, bool *button_state);
|
||||
void update_buttons();
|
||||
|
||||
|
||||
2
const.h
2
const.h
@ -37,8 +37,6 @@
|
||||
#define REVERB_AMOUNT_MIN 0.0f
|
||||
#define REVERB_AMOUNT_MAX 1.0f
|
||||
|
||||
#define AMEN_BPM 85.0f
|
||||
#define AMEN_BARS 4.0f
|
||||
|
||||
#define otherwise else
|
||||
|
||||
|
||||
5
main.c
5
main.c
@ -68,7 +68,8 @@ void core1_main(void) {
|
||||
while (1) {
|
||||
update_buttons();
|
||||
update_inputs();
|
||||
printf("Sample: %f\n", state.dbg_sample);
|
||||
//printf("vco_mode: %d, quant_enabled: %d amen_enabled: %d\n", state.vco_mode,state.quant_enabled,state.amen_enabled);
|
||||
//printf("clock_bpm: %f\n",state.clock_bpm);
|
||||
sleep_ms(1);
|
||||
}
|
||||
}
|
||||
@ -77,6 +78,6 @@ __attribute__((noreturn))
|
||||
int main() {
|
||||
init_all();
|
||||
multicore_launch_core1(core1_main);
|
||||
while (1);
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
|
||||
4
pwm.c
4
pwm.c
@ -1,8 +1,8 @@
|
||||
#include <hardware/pwm.h>
|
||||
#include <pico/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "const.h"
|
||||
#include "state.h"
|
||||
#include "synth.h"
|
||||
|
||||
#include "pwm.h"
|
||||
@ -15,7 +15,7 @@ void pwm_isr(void) {
|
||||
pwm_clear_irq(slice);
|
||||
|
||||
float sample = get_sample();
|
||||
state.dbg_sample = sample;
|
||||
printf("sample: %f\n", sample);
|
||||
|
||||
uint16_t level = (uint16_t)((sample + 1.0f) * 0.5f * 3400.0f);
|
||||
pwm_set_chan_level(slice, chan, level);
|
||||
|
||||
2
state.h
2
state.h
@ -23,8 +23,6 @@ typedef struct {
|
||||
vco_mode_t vco_mode;
|
||||
bool quant_enabled;
|
||||
bool amen_enabled;
|
||||
|
||||
float dbg_sample;
|
||||
} state_t;
|
||||
|
||||
extern state_t state;
|
||||
|
||||
86
synth.cc
86
synth.cc
@ -1,9 +1,8 @@
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "daisysp.h"
|
||||
#include "state.h"
|
||||
#include "const.h"
|
||||
#include "daisysp.h"
|
||||
#include "vco.h"
|
||||
#include "dsp.h"
|
||||
|
||||
@ -16,19 +15,11 @@ Svf filter;
|
||||
AdEnv vco_env;
|
||||
AdEnv filter_env;
|
||||
|
||||
DelayLine<float, COMB0_SIZE> comb0;
|
||||
DelayLine<float, COMB1_SIZE> comb1;
|
||||
DelayLine<float, COMB2_SIZE> comb2;
|
||||
DelayLine<float, COMB3_SIZE> comb3;
|
||||
DelayLine<float, AP0_SIZE> ap0;
|
||||
DelayLine<float, AP1_SIZE> ap1;
|
||||
// TODO: Reverb
|
||||
|
||||
float clock_phase = 0.0f;
|
||||
bool clock_trig = false;
|
||||
|
||||
float amen_phase = 0.0f;
|
||||
float amen_length = 0.0f;
|
||||
|
||||
static inline auto vco_mode_to_daisy(vco_mode_t mode) {
|
||||
switch (mode) {
|
||||
case VCO_SQUARE: return daisysp::Oscillator::WAVE_SQUARE;
|
||||
@ -46,7 +37,7 @@ static inline float pot_to_time(float v, float min, float max) { return min * po
|
||||
static inline float quantize(float freq, float temp) {
|
||||
float midi = temp * log2f(freq / 440.0f) + 69.0f;
|
||||
float note = roundf(midi);
|
||||
return 440.0f * powf(2.0f, (note - 69.0f) / temp);
|
||||
return 440.0f * powf(2.0f, (midi - 69.0f) / temp);
|
||||
}
|
||||
|
||||
static inline float low_pass(float in, float* z, float coeff) {
|
||||
@ -54,54 +45,11 @@ static inline float low_pass(float in, float* z, float coeff) {
|
||||
return *z;
|
||||
}
|
||||
|
||||
float reverb(float in, float amount) {
|
||||
static float damp0 = 0.0f, damp1 = 0.0f, damp2 = 0.0f, damp3 = 0.0f;
|
||||
float feedback = 0.84f;
|
||||
float damp = 0.3f;
|
||||
|
||||
float c0 = comb0.Read(); low_pass(in + c0 * feedback, &damp0, damp); comb0.Write(damp0);
|
||||
float c1 = comb1.Read(); low_pass(in + c1 * feedback, &damp1, damp); comb1.Write(damp1);
|
||||
float c2 = comb2.Read(); low_pass(in + c2 * feedback, &damp2, damp); comb2.Write(damp2);
|
||||
float c3 = comb3.Read(); low_pass(in + c3 * feedback, &damp3, damp); comb3.Write(damp3);
|
||||
|
||||
float wet = (c0 + c1 + c2 + c3) * 0.25f;
|
||||
|
||||
const float g = 0.7f;
|
||||
float a0r = ap0.Read();
|
||||
float a0in = wet + (-g * a0r);
|
||||
ap0.Write(a0in);
|
||||
wet = a0r + g * a0in;
|
||||
|
||||
float a1r = ap1.Read();
|
||||
float a1in = wet + (-g * a1r);
|
||||
ap1.Write(a1in);
|
||||
wet = a1r + g * a1in;
|
||||
|
||||
return in + amount * (wet - in);
|
||||
}
|
||||
|
||||
#include "amenbreak.h"
|
||||
|
||||
float amenbreak(float beat_samples, float playback_rate) {
|
||||
amen_length = beat_samples * 4.0f * AMEN_BARS;
|
||||
|
||||
uint32_t idx0 = (uint32_t)amen_phase % amen_sample_count;
|
||||
uint32_t idx1 = (idx0 + 1) % amen_sample_count;
|
||||
float frac = amen_phase - floorf(amen_phase);
|
||||
float s0 = amen_samples[idx0] * (1.0f / 32768.0f);
|
||||
float s1 = amen_samples[idx1] * (1.0f / 32768.0f);
|
||||
float amen_out = s0 + frac * (s1 - s0);
|
||||
|
||||
amen_phase += playback_rate;
|
||||
if (amen_phase >= amen_length) amen_phase -= amen_length;
|
||||
return amen_out;
|
||||
}
|
||||
|
||||
void synth_init(void) {
|
||||
osc.Init(SAMPLE_RATE);
|
||||
osc.SetWaveform(vco_mode_to_daisy(VCO_SAW));
|
||||
osc.SetWaveform(vco_mode_to_daisy(VCO_SINE));
|
||||
osc.SetFreq(440.0f);
|
||||
osc.SetAmp(2.0f);
|
||||
osc.SetAmp(1.0f);
|
||||
|
||||
filter.Init(SAMPLE_RATE);
|
||||
filter.SetFreq(2000.0f);
|
||||
@ -109,7 +57,7 @@ void synth_init(void) {
|
||||
|
||||
vco_env.Init(SAMPLE_RATE);
|
||||
vco_env.SetTime(ADENV_SEG_ATTACK, 0.01f);
|
||||
vco_env.SetTime(ADENV_SEG_DECAY, 0.8f);
|
||||
vco_env.SetTime(ADENV_SEG_DECAY, 0.5f);
|
||||
vco_env.SetMin(0.0f);
|
||||
vco_env.SetMax(1.0f);
|
||||
|
||||
@ -119,22 +67,17 @@ void synth_init(void) {
|
||||
filter_env.SetMin(0.0f);
|
||||
filter_env.SetMax(1.0f);
|
||||
|
||||
state.clock_bpm = 0.2f;
|
||||
|
||||
clock_phase = 0.0f;
|
||||
clock_trig = false;
|
||||
|
||||
amen_phase = 0.0f;
|
||||
state.amen_enabled = true;
|
||||
state.reverb_amount = 1.0;
|
||||
}
|
||||
|
||||
float get_sample(void) {
|
||||
float bpm = BPM_MIN + state.clock_bpm * (BPM_MAX - BPM_MIN);
|
||||
float beat_samples = SAMPLE_RATE * 60.0f / bpm;
|
||||
float playback_rate = bpm / AMEN_BPM;
|
||||
return osc.Process();
|
||||
}
|
||||
|
||||
float clock_inc = bpm / 60.0f / SAMPLE_RATE;
|
||||
float _get_sample(void) {
|
||||
float bps = state.clock_bpm / 60.0f;
|
||||
float clock_inc = bps / SAMPLE_RATE;
|
||||
clock_phase += clock_inc;
|
||||
clock_trig = false;
|
||||
if (clock_phase >= 1.0f) {
|
||||
@ -175,12 +118,7 @@ float get_sample(void) {
|
||||
|
||||
float vca_out = filtered * vco_env_out * state.vco_volume;
|
||||
|
||||
float reverb_out = vca_out; //reverb(vca_out, state.reverb_amount);
|
||||
|
||||
float amen_out = 0.0f;
|
||||
if (state.amen_enabled) amen_out = amenbreak(beat_samples, playback_rate);
|
||||
|
||||
float mix = reverb_out + amen_out;
|
||||
float mix = vca_out;
|
||||
mix = fclamp(mix, -1.0f, 1.0f);
|
||||
|
||||
return mix;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user