-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWavetable-Polysynth.ino
More file actions
86 lines (72 loc) · 2.36 KB
/
Copy pathWavetable-Polysynth.ino
File metadata and controls
86 lines (72 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#define MAX_POLYPHONY (6)
#include "PolyphonyManager.h"
#include "WavetableReader.h"
#include "Wavetable.h"
#include "pwm.h"
#include "FspTimer.h"
const static uint8_t mod1Pin = A1;
const static uint8_t mod2Pin = A2;
const static uint8_t leftOutPin = D2;
const static uint8_t rightOutPin = D4;
const static uint16_t sampleRate = 22050;
const static size_t noteCount = 10;
const static float notes[noteCount] = { // Two octaves of minor pentatonic starting on C3
130.8127826503f, 155.56349186104f, 174.6141157165f, 195.99771799087f, 233.08188075904f,
261.6255653006f, 311.12698372208f, 349.228231433f, 391.99543598175f, 466.16376151809f };
PwmOut leftOutPwm(leftOutPin);
PwmOut rightOutPwm(rightOutPin);
float left, right;
void timerCallback(timer_callback_args_t __attribute((unused)) *p_args) {
PolyphonyManager::update(left, right);
leftOutPwm.pulse_perc(left);
rightOutPwm.pulse_perc(right);
};
FspTimer timer;
bool setupTimer() {
uint8_t type = GPT_TIMER;
int8_t index = FspTimer::get_available_timer(type);
if (index == 0) {
FspTimer::force_use_of_pwm_reserved_timer();
index = FspTimer::get_available_timer(type);
}
if (index == 0) return false;
if (!timer.begin(TIMER_MODE_PERIODIC, type, index, (float)sampleRate, 0.0f, timerCallback)) return false;
if (!timer.setup_overflow_irq()) return false;
if (!timer.open()) return false;
if (!timer.start()) return false;
}
const static float onePoleCoeff = 0.5;
inline float onePole(float &out, const float &in) {
out += onePoleCoeff * (in - out);
}
void setup() {
Serial.begin();
analogReadResolution(8);
PolyphonyManager::Init(sampleRate, tableSize);
leftOutPwm.begin(255, 0, true);
rightOutPwm.begin(255, 0, true);
setupTimer();
}
const static uint8_t readPeriod = 100;
uint32_t last = 0;
float mod1 = 0, mod2 = 0;
uint32_t noteLast = 0;
uint16_t noteNext = 0;
void loop() {
const uint32_t now = millis();
if (now >= last + readPeriod) {
onePole(mod1, analogRead(mod1Pin));
onePole(mod2, analogRead(mod2Pin));
WavetableReader::setModRawValues(mod1, mod2);
last = now;
}
if (now >= noteLast + noteNext) {
noteNext = random(1, 9) * 250;
PolyphonyManager::addNote(
notes[random(noteCount)], // freq
static_cast<uint32_t>(noteNext * (sampleRate / 1000.0f) * random(2, 4)), // duration
random(4, 13) / 16.0f // pan
);
noteLast = now;
}
}