diff --git a/Xmas/Xmas.ino b/Xmas/Xmas.ino new file mode 100644 index 0000000..0dcbba4 --- /dev/null +++ b/Xmas/Xmas.ino @@ -0,0 +1,112 @@ +// Basic demo for configuring the MCP4728 4-Channel 12-bit I2C DAC +#include +#include + +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); +}