Compare commits
	
		
			9 Commits
		
	
	
		
			23f0cb2357
			...
			88fda8a5f2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					88fda8a5f2 | ||
| 
						 | 
					56fae7e54d | ||
| 
						 | 
					71fd9e319a | ||
| 
						 | 
					f4d75a627e | ||
| 
						 | 
					bd9940b96b | ||
| 
						 | 
					0468c427d8 | ||
| 
						 | 
					b5b4c3bdd3 | ||
| 
						 | 
					9ce26424a9 | ||
| 
						 | 
					e5728416f0 | 
							
								
								
									
										168
									
								
								Xmas/Xmas.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								Xmas/Xmas.ino
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,168 @@
 | 
				
			|||||||
 | 
					// Basic demo for configuring the MCP4728 4-Channel 12-bit I2C DAC
 | 
				
			||||||
 | 
					#include <Adafruit_MCP4728.h>
 | 
				
			||||||
 | 
					#include <Wire.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Adafruit_MCP4728 mcp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float tuning[16];
 | 
				
			||||||
 | 
					// 0 = A, 8 = F (tonic)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int m1[] =   { 3, 8, 8, 10, 8,  7,  5,  5,  5, 10, 10, 12, 10,  8,  7,  3,  7, 12, 12, 13, 12, 10,  8,  5, 3,  3,  5,  10,  7,  8,  3, 8,   8,  8,  7,  7,  8,  7,  5,  3, 10, 12, 10, 10, 8, 8,   15, 3,   3,  3, 5, 10, 7, 8  };
 | 
				
			||||||
 | 
					int s1[] =   { 0, 2, 4,  5, 6,  7,  8, 10, 12, 14, 16, 17, 18, 19, 20, 22, 24, 26, 28, 29, 30, 31, 32, 34, 36, 37, 38, 40, 42, 44, 48, 50, 52, 54, 56, 60, 62, 64, 66, 68, 72, 74, 76, 77, 78, 79, 80, 82, 84, 85, 86, 88, 90, 92 };  
 | 
				
			||||||
 | 
					float d1[] = { 2, 1, 1,  1, 1,  1,  2,  1,  2,  1,  1,  1,  1,  1,  2,  1,  2,  1, 1,  1,   1,  1,  2,  2, 1,  1,  2,   2,  2,  4,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 1,   1,  1,  1,  1, 1,   1,  1, 2, 2, 2, 4  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int m2[] =   {    8,                1,          2,                  3,          4,                  5,     0,      1,       3,  8,     8,           3,      5,          7,      8,                  7,      0,     1,      3,   8  };
 | 
				
			||||||
 | 
					int s2[] =   {    2,                8,         14,                 20,         26,                 32,     36,     38,     42, 44,    50,          56,      62,        68,     74,                 80,     84,    86,     90, 92 };
 | 
				
			||||||
 | 
					float d2[] =   {  6,                6,          6,                  6,          6,                  4,      2,      4,      2,  6,     6,           6,       6,         6,      6,                  4,      2,     4,      2,  4  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// int m1[] =     { 0,    2,    4,   5,     7,   9,  11, 12 };
 | 
				
			||||||
 | 
					// int s1[] =     { 0,    2,    4,   6,    8,  10,  12,  14 };
 | 
				
			||||||
 | 
					// float d1[] =   { 1.0, 0.5, 1.0, 0.5,  1.0, 0.5, 1.0, 0.5  };
 | 
				
			||||||
 | 
					// int m2[] =     { 0,    4,    7,  12, 0,    4,    7,  12, 0,    4,    7,  12, 0,    4,    7,  12 };
 | 
				
			||||||
 | 
					// int s2[] =     { 0, 1 ,    2,    3,   4,    5,  6,  7, 8, 9, 10, 11, 12, 13, 14, 15 };
 | 
				
			||||||
 | 
					// float d2[] =   { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float gate = 0.5;
 | 
				
			||||||
 | 
					int bpm = 320;
 | 
				
			||||||
 | 
					float beat_s = 60.0 / (float)bpm;
 | 
				
			||||||
 | 
					int beat = round(1000.0 * beat_s); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// count_in = number of beats since t0 to wait before we startt playing
 | 
				
			||||||
 | 
					// repeat = number of beats to repeat - could be computed from the sequence data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// From here on, all times are in milliseconds to head off floating point errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long count_in = 4 * beat;
 | 
				
			||||||
 | 
					int repeat = 96;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 = -1;
 | 
				
			||||||
 | 
					  bool playing = false;
 | 
				
			||||||
 | 
					  bool looped = false;
 | 
				
			||||||
 | 
					  long play = 0;
 | 
				
			||||||
 | 
					  long rel = 0;
 | 
				
			||||||
 | 
					  long last = 0;
 | 
				
			||||||
 | 
					  long init = 0;
 | 
				
			||||||
 | 
					  int *melody;
 | 
				
			||||||
 | 
					  int *start;
 | 
				
			||||||
 | 
					  float *duration;
 | 
				
			||||||
 | 
					  int len = 0;
 | 
				
			||||||
 | 
					  MCP4728_channel_t pitch;
 | 
				
			||||||
 | 
					  MCP4728_channel_t gate;
 | 
				
			||||||
 | 
					} sequencer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sequencer seq1, seq2;
 | 
				
			||||||
 | 
					long start_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float n0 = 0;
 | 
				
			||||||
 | 
					  for( int i = 0; i < 16; i++ ) {
 | 
				
			||||||
 | 
					      tuning[i] = round(n0 + octave * (float)i / 12.0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  long now = millis();
 | 
				
			||||||
 | 
					  start_time = now;
 | 
				
			||||||
 | 
					  seq1.last = now;
 | 
				
			||||||
 | 
					  seq1.pitch = MCP4728_CHANNEL_A;
 | 
				
			||||||
 | 
					  seq1.gate = MCP4728_CHANNEL_B;
 | 
				
			||||||
 | 
					  seq1.melody = m1;
 | 
				
			||||||
 | 
					  seq1.start = s1;
 | 
				
			||||||
 | 
					  seq1.duration = d1;
 | 
				
			||||||
 | 
					  seq1.len = sizeof(m1) / sizeof(m1[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  times_to_ms(seq1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  seq2.last = now;
 | 
				
			||||||
 | 
					  seq2.pitch = MCP4728_CHANNEL_C;
 | 
				
			||||||
 | 
					  seq2.gate = MCP4728_CHANNEL_D;
 | 
				
			||||||
 | 
					  seq2.melody = m2;
 | 
				
			||||||
 | 
					  seq2.duration = d2;
 | 
				
			||||||
 | 
					  seq2.start = s2;
 | 
				
			||||||
 | 
					  seq2.len = sizeof(m2) / sizeof(m2[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  times_to_ms(seq2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void times_to_ms(sequencer& seq) {
 | 
				
			||||||
 | 
					  for( int i = 0; i < seq.len; i++ ) {
 | 
				
			||||||
 | 
					    seq.start[i] *= beat;
 | 
				
			||||||
 | 
					    seq.duration[i] = (float)beat * seq.duration[i] * 0.8;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {
 | 
				
			||||||
 | 
					  long now = millis();
 | 
				
			||||||
 | 
					  long t = now - start_time;
 | 
				
			||||||
 | 
					  long beats = -1;
 | 
				
			||||||
 | 
					  if( t >= count_in ) {
 | 
				
			||||||
 | 
					    beats = (t - count_in) % (beat * repeat);
 | 
				
			||||||
 | 
					    runSequencer(seq1, t, beats);
 | 
				
			||||||
 | 
					    runSequencer(seq2, t, beats);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void runSequencer(sequencer& seq, long now, long beats) {
 | 
				
			||||||
 | 
					  int next = seq.s + 1;
 | 
				
			||||||
 | 
					  int start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if( seq.playing ) {
 | 
				
			||||||
 | 
					    if( now > seq.rel ) {
 | 
				
			||||||
 | 
					      mcp.setChannelValue(seq.gate, 0);
 | 
				
			||||||
 | 
					      seq.playing = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if( next > seq.len - 1 ) {
 | 
				
			||||||
 | 
					    seq.s = -1;
 | 
				
			||||||
 | 
					    seq.looped = true;
 | 
				
			||||||
 | 
					    return; // don't start the loop yet
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    start = seq.start[next];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if( seq.looped ) { // reached the end and waiting for the start of the bar
 | 
				
			||||||
 | 
					    if( beats < seq.last ) {
 | 
				
			||||||
 | 
					      seq.looped = false; // bar has restarted, start waiting
 | 
				
			||||||
 | 
					      seq.s = -1;
 | 
				
			||||||
 | 
					      next = 0;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  seq.last = beats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if( beats >= start ) {
 | 
				
			||||||
 | 
					    seq.s = next;
 | 
				
			||||||
 | 
					    seq.rel = now + seq.duration[seq.s];
 | 
				
			||||||
 | 
					    if( seq.melody[seq.s] > -1 ) {
 | 
				
			||||||
 | 
					      mcp.setChannelValue(seq.pitch, tuning[seq.melody[seq.s]]);
 | 
				
			||||||
 | 
					      mcp.setChannelValue(seq.gate, 4095);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    seq.playing = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user