Xmas sequencer

main
Mike Lynch 2023-12-22 17:45:33 +11:00
parent 23f0cb2357
commit e5728416f0
1 changed files with 112 additions and 0 deletions

112
Xmas/Xmas.ino 100644
View File

@ -0,0 +1,112 @@
// Basic demo for configuring the MCP4728 4-Channel 12-bit I2C DAC
#include <Adafruit_MCP4728.h>
#include <Wire.h>
Adafruit_MCP4728 mcp;
float tuning[13];
int m1[] = { 0, 5, 5, 7, 5, 4, 2, 2, 2, 7, 7, 9, 7, 5, 4, 0, 4, 9, 9, 10, 9, 7, 5, 2, 0, 0, 2, 7, 4, 5, 0, 5, 5, 5, 4, 4, 5, 4, 2, 0, 7, 9, 7, 7, 5, 5, 12, 0, 0, 0, 2, 7, 4, 5 };
float d1[] = { 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 4 };
float gate = 0.5;
int bpm = 240;
float beat_s = 60.0 / (float)bpm;
int beat_m = round(1000.0 * beat_s);
float voltrange = 5.0;
float octave = 4096.0 / voltrange; // number of DAC steps in an octave
float mod_b = 3.141592653589793 / 4.0;
typedef struct {
int s = 0;
bool noteOn = false;
long play = 0;
long rel = 0;
long last = 0;
long init = 0;
int *melody;
float *duration;
int len = 0;
MCP4728_channel_t pitch;
MCP4728_channel_t gate;
} sequencer;
sequencer seq1, seq2;
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 < 13; i++ ) {
tuning[i] = round(n0 + octave * (float)i / 12.0);
}
long now = millis();
seq1.last = now;
seq1.pitch = MCP4728_CHANNEL_A;
seq1.gate = MCP4728_CHANNEL_B;
seq1.melody = m1;
seq1.duration = d1;
seq1.len = sizeof(m1) / sizeof(m1[0]);
Serial.println("length of seq 1 pattern");
Serial.println(seq1.len);
// seq2.last = now;
// seq2.pitch = MCP4728_CHANNEL_C;
// seq2.gate = MCP4728_CHANNEL_D;
}
void loop() {
long now = millis();
runSequencer(seq1, now);
Serial.println(seq1.noteOn);
}
void runSequencer(sequencer seq, long now) {
if( seq.noteOn ) {
if( now - seq.last > seq.rel ) {
Serial.println("off");
noteOff(seq);
seq.last = now;
seq.play = round(beat_m * seq.duration[seq.s] * (1.0 - gate));
seq.noteOn = false;
seq.s += 1;
if( seq.s > seq.len ) {
seq.s = 0;
}
}
} else {
if( now - seq.last > seq.play ) {
noteOn(seq, seq.melody[seq.s]);
seq.last = now;
seq.rel = round(beat_m * seq.duration[seq.s] * gate);
seq.noteOn = true;
}
}
}
void noteOn(sequencer seq, int note) {
if( note > -1 ) {
mcp.setChannelValue(seq.pitch, tuning[note]);
mcp.setChannelValue(seq.gate, 4095);
}
}
void noteOff(sequencer seq) {
mcp.setChannelValue(seq.gate, 0);
}