Added source code for first week
This commit is contained in:
		
							parent
							
								
									ddad5492e1
								
							
						
					
					
						commit
						4515ad9fdb
					
				
							
								
								
									
										41
									
								
								01LogisticChaos/01LogisticChaos.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								01LogisticChaos/01LogisticChaos.ino
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| // Basic demo for configuring the MCP4728 4-Channel 12-bit I2C DAC
 | ||||
| #include <Adafruit_MCP4728.h> | ||||
| #include <Wire.h> | ||||
| 
 | ||||
| Adafruit_MCP4728 mcp; | ||||
| 
 | ||||
| float xlog = 0.5; | ||||
| float r = 3.783423; | ||||
| 
 | ||||
| void setup(void) { | ||||
|   Serial.begin(115200); | ||||
|   while (!Serial) | ||||
|     delay(10); // will pause Zero, Leonardo, etc until serial console opens
 | ||||
| 
 | ||||
|   Serial.println("Adafruit MCP4728 test!"); | ||||
| 
 | ||||
|   // Try to initialize!
 | ||||
|   if (!mcp.begin(0x64)) { | ||||
|     Serial.println("Failed to find MCP4728 chip"); | ||||
|     while (1) { | ||||
|       delay(10); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   mcp.setChannelValue(MCP4728_CHANNEL_A, 4095); | ||||
|   mcp.setChannelValue(MCP4728_CHANNEL_B, 2048); | ||||
|   mcp.setChannelValue(MCP4728_CHANNEL_C, 1024); | ||||
|   mcp.setChannelValue(MCP4728_CHANNEL_D, 0); | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void loop() { | ||||
|   int pot = analogRead(A0); | ||||
|   r = (float)pot / 1024.0 + 3.0; | ||||
|   xlog = r * xlog * (1 - xlog); | ||||
|   int cv = round(xlog * 4095.0);   | ||||
|   mcp.setChannelValue(MCP4728_CHANNEL_A, cv); | ||||
|   delay(100); | ||||
| } | ||||
							
								
								
									
										111
									
								
								03Sequencer/03Sequencer.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								03Sequencer/03Sequencer.ino
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | ||||
| // 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[] = { -1, 6, 4, -1, 6, 5  };
 | ||||
| //float dur[] = { 2,  1, 1, 2, 1, 1  };
 | ||||
| //int pitch[] = { 4, -1, 4, -1 };
 | ||||
| //float dur[] = { 2,  2, 2, 2  };
 | ||||
| int pitch[] = { 2, 4, 5, 3, 4, 5, 2, 3, 3, 4, 5, 2, 4, 3, 5 ,2 }; | ||||
| float dur[] = { 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  }; | ||||
| float gate = 0.5; | ||||
| int bpm = 167; | ||||
| int phrase = 16; | ||||
| 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; | ||||
|       } | ||||
|     } | ||||
|   } 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); | ||||
| } | ||||
							
								
								
									
										96
									
								
								04KarplusStrongFish/04KarplusStrongFish.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								04KarplusStrongFish/04KarplusStrongFish.ino
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | ||||
| // Very basic Karplus-Strong 
 | ||||
| 
 | ||||
| // based on this explanation http://sites.music.columbia.edu/cmc/MusicAndComputers/chapter4/04_09.php
 | ||||
| 
 | ||||
| 
 | ||||
| #include <Adafruit_MCP4728.h> | ||||
| #include <Wire.h> | ||||
| 
 | ||||
| Adafruit_MCP4728 mcp; | ||||
| 
 | ||||
| #define nsamp 256 | ||||
| #define dacmax 256 | ||||
| 
 | ||||
| unsigned int phase; | ||||
| unsigned int length; | ||||
| unsigned int repeats; | ||||
| int note = 0; | ||||
| //int freqs[] = { 64, 56, 51, 48, 42, 38, 34, 32, 28, 25, 24, 21, 19, 17, 16  };
 | ||||
| //int tune2[] = { 2, -1, -1, 2, -1, -1, 3, -1, 2, -1, -1, -1, 0, -1, -1, -1 };
 | ||||
| //int tune2[] = { 2, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, 4, -1, -1, -1 };
 | ||||
| int freqs[] = { 128, 112, 102, 96, 84, 76, 64, 56, 50, 48, 42, 38, 34, 32 }; | ||||
| int tune2[] = { 0, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1  }; | ||||
| 
 | ||||
| byte waveform[nsamp]; | ||||
| 
 | ||||
| int pd = 30; | ||||
| 
 | ||||
| void setup() { | ||||
| 
 | ||||
|   cli(); | ||||
| 
 | ||||
| //set timer1 interrupt at 1Hz
 | ||||
|   TCCR1A = 0;// set entire TCCR1A register to 0
 | ||||
|   TCCR1B = 0;// same for TCCR1B
 | ||||
|   TCNT1  = 0;//initialize counter value to 0
 | ||||
|   // set compare match register for 1hz increments
 | ||||
|   //OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
 | ||||
|   //OCR1A = 7812;// = (16*10^6) / (1*1024) - 1 (must be <65536)
 | ||||
|   OCR1A = 2000; | ||||
|   // turn on CTC mode
 | ||||
|   TCCR1B |= (1 << WGM12); | ||||
|   // Set CS10 and CS12 bits for 1024 escaler
 | ||||
|   TCCR1B |= (1 << CS12) | (1 << CS10);   | ||||
|   // enable timer compare interrupt
 | ||||
|   TIMSK1 |= (1 << OCIE1A); | ||||
| 
 | ||||
|   sei(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   if (!mcp.begin(0x64)) { | ||||
|     while (1) { | ||||
|       delay(100); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   randomSeed(analogRead(A0)); | ||||
|   mcp.setSpeed(800000L); | ||||
| 
 | ||||
|   phase=0; | ||||
|   note=0; | ||||
| } | ||||
| 
 | ||||
| ISR(TIMER1_COMPA_vect){//timer1
 | ||||
|   if( tune2[note] > -1 ) { | ||||
|     length=freqs[tune2[note]]; | ||||
|     for (int i=0; i<nsamp; ++i){   | ||||
|       waveform[i]=random(256); | ||||
|     } | ||||
|   } | ||||
|   note++; | ||||
|   if( note > 15 ) { | ||||
|     note = 0; | ||||
|   } | ||||
|   pd = analogRead(A0) >> 4; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| void loop() { | ||||
|   byte s1, s2; | ||||
|   int p0 = phase; | ||||
|   int p1 = phase - pd; | ||||
|   if( p1 < 0 ) { | ||||
|     p1 += length; | ||||
|   }  | ||||
|   phase += 1; | ||||
|   if( phase >= length ) { | ||||
|     phase = 0; | ||||
|   } | ||||
|   s1 = waveform[p1]; | ||||
|   s2 = waveform[p0]; | ||||
|   waveform[p0] =   ( s1 & s2 ) + ((s1 ^ s2) >> 1); | ||||
|   mcp.fastWrite(s1 << 4, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										128
									
								
								05Wavetable/05Wavetable.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								05Wavetable/05Wavetable.ino
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | ||||
| //waveform generator
 | ||||
| 
 | ||||
| // hacked from https://www.instructables.com/Arduino-Waveform-Generator-1/
 | ||||
| 
 | ||||
| #include <Adafruit_MCP4728.h> | ||||
| #include <Wire.h> | ||||
| 
 | ||||
| Adafruit_MCP4728 mcp; | ||||
| 
 | ||||
| #define nsamp 32 | ||||
| #define dacmax 256 | ||||
| 
 | ||||
| const byte nclk = 200; // a guess
 | ||||
| long int freq; //frequency in Hz
 | ||||
| long unsigned int phase; | ||||
| long unsigned int phase_inc; | ||||
| 
 | ||||
| int note = 0; | ||||
| int gate; | ||||
| int decay = 128; | ||||
| 
 | ||||
| float pattern[16]; | ||||
| 
 | ||||
| long unsigned int pattern_inc[4]; | ||||
| 
 | ||||
| void setup() { | ||||
|   TIMSK0 &= ~_BV(TOIE0); // disable timer0 overflow interrupt
 | ||||
| 
 | ||||
|   cli(); | ||||
| 
 | ||||
| //set timer1 interrupt at 1Hz
 | ||||
|   TCCR1A = 0;// set entire TCCR1A register to 0
 | ||||
|   TCCR1B = 0;// same for TCCR1B
 | ||||
|   TCNT1  = 0;//initialize counter value to 0
 | ||||
|   // set compare match register for 1hz increments
 | ||||
|   OCR1A = 3905;// = (16*10^6) / (1*1024) - 1 (must be <65536)
 | ||||
|   // turn on CTC mode
 | ||||
|   TCCR1B |= (1 << WGM12); | ||||
|   // Set CS10 and CS12 bits for 1024 prescaler
 | ||||
|   TCCR1B |= (1 << CS12) | (1 << CS10);   | ||||
|   // enable timer compare interrupt
 | ||||
|   TIMSK1 |= (1 << OCIE1A); | ||||
| 
 | ||||
|   sei(); | ||||
| 
 | ||||
| 
 | ||||
|   Serial.begin(115200); | ||||
| 
 | ||||
|   if (!mcp.begin(0x64)) { | ||||
|     while (1) { | ||||
|       delay(100); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| //  mcp.setSpeed(400000L);
 | ||||
| //  mcp.setSpeed(800000L);
 | ||||
|   mcp.setSpeed(800000L); | ||||
| 
 | ||||
|   freq=440; | ||||
|   phase=0; | ||||
|   //pattern[0] = 220.0;
 | ||||
|   // pattern[1] = 261.6255653005987;
 | ||||
|   // pattern[2] = 369.9944227116345;
 | ||||
|   // pattern[3] = 391.9954359817495;
 | ||||
|   for( int i = 0; i < 4; i++ ) { | ||||
|     pattern[i] = 0; | ||||
|   } | ||||
|   for( int i = 4; i < 6; i++ ) { | ||||
|     pattern[i] = 659.2551138257401; | ||||
|   } | ||||
|   for( int i = 6; i < 8; i++ ) { | ||||
|     pattern[i] = 493.8833012561241; | ||||
|   } | ||||
|   for( int i = 8; i < 16; i++ ) { | ||||
|     pattern[i] = 0; | ||||
|   } | ||||
| 
 | ||||
|   for( int i = 0; i < 16; i++ ) { | ||||
|     pattern_inc[i] = pattern[i] * 975592.231884058; | ||||
|   } | ||||
| 
 | ||||
|   setwave(); | ||||
| } | ||||
| 
 | ||||
| const float pi=3.14159265; | ||||
| byte waveform[nsamp]; | ||||
| byte phaseb = 0; | ||||
| void setwave(){ | ||||
|   for (int isamp=0; isamp<nsamp; ++isamp){ | ||||
|     float phip=(isamp+0.5)/nsamp; | ||||
|     float phi=2*pi*phip; | ||||
|     int val=0; | ||||
| 
 | ||||
|     //saw
 | ||||
|     val = dacmax * isamp / nsamp; | ||||
|     //val = ( isamp < nsamp / 2 ) ? 0 : dacmax - 1;
 | ||||
|         //sine
 | ||||
|     //val=(sin(phi)+1.0)*dacmax/2;
 | ||||
|     //val=((sin(phi)+0.333*sin(3*phi))/0.943+1)*dacmax/2;
 | ||||
| 
 | ||||
|     val=max(val,0); | ||||
|     val=min(val,dacmax-1); | ||||
|     waveform[isamp]=val; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ISR(TIMER1_COMPA_vect){ | ||||
|   note += 1; | ||||
|   if( note > 15 ) { | ||||
|     note = 0; | ||||
|   } | ||||
|   phase_inc = pattern_inc[note]; | ||||
|   gate = 4095; | ||||
| } | ||||
|   | ||||
| 
 | ||||
| 
 | ||||
| void loop() { | ||||
|   phase += phase_inc; | ||||
|   int redphase = phase >> 27; | ||||
|   mcp.fastWrite(waveform[redphase] << 4, gate, 0, 0); | ||||
|   if( gate > 0 ) { | ||||
|     gate -= decay; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -1,168 +0,0 @@ | ||||
| // We Wish You a Merry Christmas
 | ||||
| #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