07 Dynamic Sequences
parent
dc007bceb5
commit
6c3532ea47
|
@ -0,0 +1,113 @@
|
|||
// 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 hexany[] = { 0.12928301694496647, 0.32192809488736235, 0.3923174227787603, 0.5849625007211562, 0.8073549220576041, 0.9068905956085185 };
|
||||
float tuning[18];
|
||||
int pitch[] = { 4, 3, 2, 1, 2, 3, 4, 3 };
|
||||
float dur[] = { 2, 2, 2, 2, 2, 2, 2, 2 };
|
||||
float gate = 0.5;
|
||||
int bpm = 135;
|
||||
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 o = 0; o < 3; o++ ) {
|
||||
for( int i = 0; i < 18; i++ ) {
|
||||
tuning[o * 6 + i] = round(n0 + octave * (o + hexany[i]));
|
||||
}
|
||||
}
|
||||
|
||||
s = 0;
|
||||
release_t = 0;
|
||||
play_t = 0;
|
||||
last_t = millis();
|
||||
init_t = last_t;
|
||||
}
|
||||
|
||||
|
||||
void make_tuning() {
|
||||
float n0 = 0;
|
||||
for( int i = 0; i < 18; i++ ) {
|
||||
tuning[i] = round(n0 + octave * hexany[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
updatePhrase();
|
||||
}
|
||||
}
|
||||
} 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 updatePhrase() {
|
||||
int n = random(phrase);
|
||||
pitch[n] = random(6);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue