Looptober24/097TET/097TET.ino

105 lines
2.3 KiB
Arduino
Raw Normal View History

2024-10-12 00:35:16 +00:00
// Basic demo for configuring the MCP4728 4-Channel 12-bit I2C DAC
#include <Adafruit_MCP4728.h>
#include <Wire.h>
Adafruit_MCP4728 mcp;
// 1 3 5 7 hexany log2
float tuning[22];
// bassline
//int pitch[] = { 1, 2, -1, 0, -1, 1, -1, 0, -1, 1, -1 };
//float dur[] = { 0.25, 0.25, 0.5, 0.25, 0.5, 0.25, 0.5, 0.25, 0.5, 0.25, 0.5 };
// kick
//int pitch[] = { 1, -1, 1, -1, 1, -1, 1, -1, 1 };
//float dur[] = { 0.25, 0.75, 0.25, 0.75, 0.25, 0.75, 0.25, 0.75};
int pitch[] = { 9, 7, 5, 3, 8, 6, 5, 3 };
float dur[] = { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 };
float gate = 0.25;
int bpm = 140;
int phrase = 8;
float beat_s = 60.0 / (float)bpm;
int beat_m = round(1000.0 * beat_s);
float voltrange = 4.85; // measured this, probably not accurate
float octave = 4096.0 / voltrange; // number of DAC steps in an octave
float mod_b = 3.141592653589793 / 4.0;
int s;
bool noteon = false;
long play_t;
long release_t;
long last_t;
long init_t;
void setup(void) {
Serial.begin(115200);
while (!Serial)
delay(10); // will pause Zero, Leonardo, etc until serial console opens
if (!mcp.begin(0x64)) {
Serial.println("Failed to find MCP4728 chip");
while (1) {
delay(10);
}
Serial.println("MCP4728 initialised");
}
mcp.setChannelValue(MCP4728_CHANNEL_B, 0);
float n0 = 0;
for( int i = 0; i < 22; i++ ) {
tuning[i] = round(n0 + octave * (float)i / 7.0);
}
s = 0;
release_t = 0;
play_t = 0;
last_t = millis();
init_t = last_t;
}
void loop() {
long now = millis();
if( noteon ) {
if( now - last_t > release_t ) {
noteOff();
last_t = now;
play_t = round(beat_m * dur[s] * (1.0 - gate));
noteon = false;
s += 1;
if( s == phrase ) {
s = 0;
}
}
} else {
if( now - last_t > play_t ) {
noteOn(pitch[s]);
last_t = now;
release_t = round(beat_m * dur[s] * gate);
noteon = true;
}
}
// sychronise this better
long mod_t = (now - init_t);
float mod = 0.5 + 0.5 * sin(mod_b * (float)mod_t / (float)beat_m);
mcp.setChannelValue(MCP4728_CHANNEL_C, round(4095.0 * mod));
}
void noteOn(int note) {
if( note > -1 ) {
mcp.setChannelValue(MCP4728_CHANNEL_A, tuning[note]);
mcp.setChannelValue(MCP4728_CHANNEL_B, 4095);
}
}
void noteOff() {
mcp.setChannelValue(MCP4728_CHANNEL_B, 0);
}