Monday, 31 August 2020

Final Project: Step Sequencer

Step Sequencer:

Main loop of sketch: Reads analog inputs used to control synth parameters. The controller reads and re-reads analog inputs until preset timer overflows. SIGNAL(PWN_INTERRUPT)  launches.

SIGNAL defined by PWN_INTERRUPT overflow. Synth runs at set frequency, regardless of main loop. 

1. Declare global variables (oscillator parameters). Hardware dependent functions (PWM_INTERRUPT). 
2. Frequency Mapping tables for grain repetition frequency. (Pentatonic mapping: default)
3. AudioOn() - sets PWM timer. 
4. setup() - PWM output in OUTPUT mode. 
5. AudioOn() triggers PWM timer.
6. Setting LED status. 

Casing Design - Built in Blender:





12x White Knobs
16x Rotary Potentiometers (10k)
4x Black Knobs
8x Momentary Button
8x LEDs
1x Arduino Mega 2560 R3
1x Audio Jack
1x Barrel Jack


 Fritz_Sequencer

Code:

int tempo = 100000;

int pattern = 0;

int counter = 0;


int a1 = 0; int a2 = 0; int a3 = 0; int a4 = 0; int a5 = 0; 

int b1 = 0; int b2 = 0; int b3 = 0; int b4 = 0; int b5 = 0; 

int c1 = 0; int c2 = 0; int c3 = 0; int c4 = 0; int c5 = 0; 

int d1 = 0; int d2 = 0; int d3 = 0; int d4 = 0; int d5 = 0; 

int e1 = 0; int e2 = 0; int e3 = 0; int e4 = 0; int e5 = 0; 

int f1 = 0; int f2 = 0; int f3 = 0; int f4 = 0; int f5 = 0; 

int g1 = 0; int g2 = 0; int g3 = 0; int g4 = 0; int g5 = 0; 

int h1 = 0; int h2 = 0; int h3 = 0; int h4 = 0; int h5 = 0; 


int live_sync_phase = 0;

int live_grain_phase = 0;

int live_grain_decay = 0;

int live_grain2_phase = 0;

int live_grain2_decay = 0;


 pinMode(39, OUTPUT); digitalWrite(39, LOW);

  pinMode(41, OUTPUT); digitalWrite(41, LOW);

  pinMode(43, OUTPUT); digitalWrite(43, LOW);

  pinMode(45, OUTPUT); digitalWrite(45, LOW);

  pinMode(47, OUTPUT); digitalWrite(47, LOW);

  pinMode(49, OUTPUT); digitalWrite(49, LOW);

  pinMode(51, OUTPUT); digitalWrite(51, LOW);

  pinMode(53, OUTPUT); digitalWrite(53, LOW);


  pinMode(24, INPUT); digitalWrite(24, HIGH);

  pinMode(26, INPUT); digitalWrite(26, HIGH);

  pinMode(28, INPUT); digitalWrite(28, HIGH);

  pinMode(30, INPUT); digitalWrite(30, HIGH);

  pinMode(32, INPUT); digitalWrite(32, HIGH);

  pinMode(34, INPUT); digitalWrite(34, HIGH);

  pinMode(36, INPUT); digitalWrite(36, HIGH);

  pinMode(38, INPUT); digitalWrite(38, HIGH);


void loop() {



  counter++; 


  if(counter>tempo){ 


  counter=0; //Reset the counter variable      

  if(pattern==8){pattern=0;} //Make sure we're not about to go to imaginary step 9.

  pattern++; //Let all of the following code know that we're setting up for the next step      

  //Turn off all of the step indicator lights in preparation for lighting the correct one.

  digitalWrite(39, LOW);digitalWrite(41, LOW);digitalWrite(43, LOW);digitalWrite(45, LOW);

  digitalWrite(47, LOW);digitalWrite(49, LOW);digitalWrite(51, LOW);digitalWrite(53, LOW);


  live_sync_phase = map(analogRead(14),0,1023,-500,500);

  live_grain_phase = map(analogRead(10),0,1023,-200,200);

  live_grain_decay = map(analogRead(9),0,1023,-20,20);

  live_grain2_phase = map(analogRead(8),0,1023,-200,200);

  live_grain2_decay = map(analogRead(11),0,1023,-50,50);


  tempo = map(analogRead(15),0,1023,1000,32000);


  switch(pattern){


    case 1:

    syncPhaseInc = a1 + live_sync_phase; grainPhaseInc = a2 + live_grain_phase; grainDecay = a3 + live_grain_decay; grain2PhaseInc = a4 + live_grain2_phase; grain2Decay = a5 + live_grain2_decay; digitalWrite(53, HIGH); break;

    case 2:

    syncPhaseInc = b1 + live_sync_phase; grainPhaseInc = b2 + live_grain_phase; grainDecay = b3 + live_grain_decay; grain2PhaseInc = b4 + live_grain2_phase; grain2Decay = b5 + live_grain2_decay; digitalWrite(51, HIGH); break;

    case 3:

    syncPhaseInc = c1 + live_sync_phase; grainPhaseInc = c2 + live_grain_phase; grainDecay = c3 + live_grain_decay; grain2PhaseInc = c4 + live_grain2_phase; grain2Decay = c5 + live_grain2_decay; digitalWrite(49, HIGH); break;

    case 4:

    syncPhaseInc = d1 + live_sync_phase; grainPhaseInc = d2 + live_grain_phase; grainDecay = d3 + live_grain_decay; grain2PhaseInc = d4 + live_grain2_phase; grain2Decay = d5 + live_grain2_decay; digitalWrite(47, HIGH); break;

    case 5:

    syncPhaseInc = e1 + live_sync_phase; grainPhaseInc = e2 + live_grain_phase; grainDecay = e3 + live_grain_decay; grain2PhaseInc = e4 + live_grain2_phase; grain2Decay = e5 + live_grain2_decay; digitalWrite(45, HIGH); break;

    case 6:

    syncPhaseInc = f1 + live_sync_phase; grainPhaseInc = f2 + live_grain_phase; grainDecay = f3 + live_grain_decay; grain2PhaseInc = f4 + live_grain2_phase; grain2Decay = f5 + live_grain2_decay; digitalWrite(43, HIGH); break;

    case 7:

    syncPhaseInc = g1 + live_sync_phase; grainPhaseInc = g2 + live_grain_phase; grainDecay = g3 + live_grain_decay; grain2PhaseInc = g4 + live_grain2_phase; grain2Decay = g5 + live_grain2_decay; digitalWrite(41, HIGH); break; 

    case 8:

    syncPhaseInc = h1 + live_sync_phase; grainPhaseInc = h2 + live_grain_phase; grainDecay = h3 + live_grain_decay; grain2PhaseInc = h4 + live_grain2_phase; grain2Decay = h5 + live_grain2_decay; digitalWrite(39, HIGH); break;

  }


    if(digitalRead(24)==LOW){changeStep(1);}

    if(digitalRead(26)==LOW){changeStep(2);}

    if(digitalRead(28)==LOW){changeStep(3);}

    if(digitalRead(30)==LOW){changeStep(4);}

    if(digitalRead(32)==LOW){changeStep(5);}

    if(digitalRead(34)==LOW){changeStep(6);}

    if(digitalRead(38)==LOW){changeStep(7);}

    if(digitalRead(36)==LOW){changeStep(8);}

}}


void changeStep(int step_num){


  digitalWrite(39, LOW);digitalWrite(41, LOW);digitalWrite(43, LOW);digitalWrite(45, LOW);

  digitalWrite(47, LOW);digitalWrite(49, LOW);digitalWrite(51, LOW);digitalWrite(53, LOW);  


    switch(step_num){


    case 1:

    digitalWrite(53, HIGH); break;

    case 2:

    digitalWrite(51, HIGH); break;

    case 3:

    digitalWrite(49, HIGH); break;

    case 4:

    digitalWrite(47, HIGH); break;

    case 5:

    digitalWrite(45, HIGH); break;

    case 6:

    digitalWrite(43, HIGH); break;

    case 7:

    digitalWrite(41, HIGH); break; 

    case 8:

    digitalWrite(39, HIGH); break;

  }



while(1){  


  counter++;

  if(counter>tempo){


  counter=0;

  syncPhaseInc = mapPentatonic(analogRead(SYNC_CONTROL));


  grainPhaseInc  = mapPhaseInc(analogRead(GRAIN_FREQ_CONTROL)) / 2;

  grainDecay     = analogRead(GRAIN_DECAY_CONTROL) / 8;

  grain2PhaseInc = mapPhaseInc(analogRead(GRAIN2_FREQ_CONTROL)) / 2;

  grain2Decay    = analogRead(GRAIN2_DECAY_CONTROL) / 4; 


  if(digitalRead(24)==LOW && step_num==1){

    a1 = syncPhaseInc; a2 = grainPhaseInc; a3 = grainDecay; a4 = grain2PhaseInc; a5 = grain2Decay; 

    return;}


  else if(digitalRead(24)==LOW && step_num==2){

    b1 = syncPhaseInc; b2 = grainPhaseInc; b3 = grainDecay; b4 = grain2PhaseInc; b5 = grain2Decay; 

    return;}


  else if(digitalRead(24)==LOW && step_num==3){

    c1 = syncPhaseInc; c2 = grainPhaseInc; c3 = grainDecay; c4 = grain2PhaseInc; c5 = grain2Decay; 

    return;}


  else if(digitalRead(24)==LOW && step_num==4){

    d1 = syncPhaseInc; d2 = grainPhaseInc; d3 = grainDecay; d4 = grain2PhaseInc; d5 = grain2Decay; 

    return;}


  else if(digitalRead(24)==LOW && step_num==5){

    e1 = syncPhaseInc; e2 = grainPhaseInc; e3 = grainDecay; e4 = grain2PhaseInc; e5 = grain2Decay; 

    return;}


  else if(digitalRead(24)==LOW && step_num==6){

    f1 = syncPhaseInc; f2 = grainPhaseInc; f3 = grainDecay; f4 = grain2PhaseInc; f5 = grain2Decay; 

    return;}


  else if(digitalRead(24)==LOW && step_num==7){

    g1 = syncPhaseInc; g2 = grainPhaseInc; g3 = grainDecay; g4 = grain2PhaseInc; g5 = grain2Decay; 

    return;}


  else if(digitalRead(24)==LOW && step_num==8){

    h1 = syncPhaseInc; h2 = grainPhaseInc; h3 = grainDecay; h4 = grain2PhaseInc; h5 = grain2Decay; 

    return;}


    }

  }

}


Algorithmic Synthesis: Grain

Two triangle waves (1. Frequency, 2. Decay) calculated based on analog inputs. 







No comments:

Post a Comment