← strona główna

Etiuda stochastyczna – nagranie wideo

„Partytura” PDF (średnio 300 nut na sekundę.): StrzeleckiImprowizacjaStochastycznaNaMikrokontroler-162146-EVENTS-300perSec.pdf

Wizualizacja video:

Rolka pianolowa:

StrzeleckiImprowizacjaStochastycznaNaMikrokontroler-RolkaPianolowa

Kod dla Arduino:

int interruptPin = 2;
long faza = 0;
const int N = 30;
int czas = 10;
int czasInc = 10;
long swiatloFinalProg = 200;
void setup() {
  randomSeed(19751015);
  Serial.begin (31250);
  pinMode (interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), changeGo, FALLING) ;
  delay (1000);
  noteOn (60, 48, 0);
  delay (100);
  noteOff (60, 0, 0);
  delay (10000);
  jbjbjb(false);
  jbjbjb(true);
  delay(100);
}
void changeGo () {
  while (digitalRead(interruptPin) == false) {}
}
void loop() {
  if (faza == 0) {
    otwarcie();
    faza = 10;
  }
  if (faza == 10) {
    otwarcie_wyciszenie();
    faza = 20;
  }
  if (faza == 20) {
    otwarcie_crescendo ();
    faza = 30;
  }
  if (faza == 30) {
    otwarcie_kulminacja ();
    faza = 40;
  }

  if (faza == 40) {
    mors2(350);
    faza = 50;
  }
  if (faza == 50) {
    rozwiniecie(120);
    faza = 60;
  }
  if (faza == 60) {
    rozwiniecie2(300);
    faza = 70;
  }
  if (faza == 70) {
    mors(300);
    faza = 80;
  }
  if (faza == 80) {
    rozwiniecie3(500);
    faza = 90;
  }
  if (faza == 90) {
    durowe2(1);
    rozwiniecie3(50);
    durowe2(3);
    rozwiniecie3(40);
    durowe2(5);
    rozwiniecie3(30);
    durowe2(10);
    rozwiniecie3(20);
    durowe2(20);
    rozwiniecie3(10);
    durowe2(1);
    rozwiniecie3(50);
    durowe2(3);
    rozwiniecie3(40);
    durowe2(5);
    rozwiniecie3(30);
    durowe2(10);
    rozwiniecie3(20);
    durowe2(20);
    rozwiniecie3(10);
    faza = 100;
  }
  if (faza == 100) {
    durowe2(300);
    faza = 110;
  }
  if (faza == 110) {
    for (int n = 0; n < 10; n++) {
      int mini = random (12, 108);
      int maxi = mini + 12;
      klasterRozmigotany (random(20, 50), mini, maxi, 48, 108, random (1, 20), random (10, 50));
      liniaRozmigotany (random(20, 50), mini, maxi, 48, 108, random (1, 20), random (10, 50));
      klasterRozmigotany (random(20, 50), mini, maxi, 48, 108, random (1, 20), random (10, 50));
      liniaRozmigotany (random(20, 50), mini, maxi, 48, 108, random (1, 20), random (10, 50));
      klasterRozmigotany (random(20, 50), mini, maxi, 48, 108, random (1, 20), random (10, 50));
    }
    faza = 120;
  }
  if (faza == 120) {
    for (int n = 0; n < 100; n++) {
      int mini = random (24, 96);
      int maxi = mini + 24;
      klasterRozmigotany (random(5, 10), mini, maxi, 48, 108, 10, 10);
    }
    faza = 130;
  }
  if (faza == 130) {
    for (int n = 0; n < 150; n++) {
      int mini = random (24, 96);
      int maxi = mini + 24;
      klasterRozmigotany (3, mini, maxi, 48, 108, 1, 1);
    }
    faza = 140;
  }
  if (faza == 140) {
    cresc();
    faza = 150;
  }
  if (faza == 150) {
    ruchomeKlastery(5);
    faza = 160;
  }
  if (faza == 160) {
    jbjbjb(true);
    delay (5000);
    jbjbjb(false);
    faza = 170;
  }
  if (faza == 170) {
    finau();
    faza = 180;
  }
  if (faza == 180) {
    sustain();
    faza = 1000; // nie ma takiej
  }
  //    delay (czas);
}
void graj() {
  int p[N];
  int s[N];
  for (int k = 0; k < N; k++) {
    p[k] = random (0, 128);
    s[k] = random (1, 13);
  }
  for (int k = 0; k < N; k++) {
    p[k] = p[k] + s[k];
    if (p[k] > 128) {
      p[k] = 127;
      s[k] = s[k] * - 1;
    }
    if (p[k] < 0) {
      p[k] = 0;
      s[k] = s[k] * -1  ;
    }
    if (random (0, 10) == 1) s[k] = random (0, 12) * s[k] / abs(s[k]);
    noteOn (p[k], random (30, 90), 0);
  }
  delay (czas);
  for (int k = 0; k < N; k++) {
    noteOff (p[k], 0, 0);
  }

}
void otwarcie_kulminacja () {
  int d = 10;
  for (int v = 0; v < 200; v = v + 1) {
    for (int k = 24; k < 48; k++) {
      noteOn (k, 127, 0);
    }
    delay (d);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
  for (int k = 24; k < 48; k++) {
    noteOn (k, 127, 0);
  }
  //  delay (4000);
  for (int k = 24; k < 48; k++) {
    noteOff (k, 0, 0);
  }
}
void otwarcie_wyciszenie() {
  int d = 10;
  for (int v = 72; v > 36; v = v - 1) {
    for (int k = 24; k < 48; k++) {
      noteOn (k, v, 0);
    }
    delay (d);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
    for (int k = 24; k < 48; k++) {
      noteOn (k, v, 0);
    }
    delay (d);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
}
void otwarcie_crescendo () {
  int d = 10;
  for (int v = 36; v < 128; v = v + 1) {
    for (int k = 24; k < 48; k++) {
      noteOn (k, v, 0);
    }
    delay (d);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
    for (int k = 24; k < 48; k++) {
      noteOn (k, v, 0);
    }
    delay (d);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
}
void otwarcie () {
  for (int d = 7000; d > 0; d = d - 1000) {
    for (int k = 24; k < 48; k++) {
      noteOn (k, random (48, 72), 0);
    }
    delay (d);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
  for (int d = 500; d > 0; d = d - 10) {
    for (int k = 24; k < 48; k++) {
      noteOn (k, random (48, 72), 0);
    }
    delay (d);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }

}
void rozwiniecie (long ile) {
  for (int k = 0 ; k < ile; k++) {
    graj();
    if (czas < 50) {
      czasInc = 1 * czasInc / abs(czasInc);
    } else {
      czasInc = 10 * czasInc / abs(czasInc);
    }
    czas = czas + czasInc;
    if (czas < 0) {
      czas = 0;
      czasInc = czasInc * -1;
    }
    if (czas > 100) {
      czas = 100;
      czasInc = czasInc * -1;
    }
    if (czas < 10) {
      int ile = random (10, 80);
      for (int k = 1; k < ile; k++) graj();
    }
  }
}
void rozwiniecie2 (long ile) {
  int nuta;
  for (int k = 0 ; k < ile; k++) {
    nuta = random (0, 128);
    noteOn (nuta, random (36, 84), 0);
    delay(czas);
    noteOff (nuta, random (36, 84), 0);
    if (czas < 50) {
      czasInc = 1 * czasInc / abs(czasInc);
    } else {
      czasInc = 10 * czasInc / abs(czasInc);
    }
    czas = czas + czasInc;
    if (czas < 0) {
      czas = 0;
      czasInc = czasInc * -1;
    }
    if (czas > 100) {
      czas = 100;
      czasInc = czasInc * -1;
    }
    if (czas < 10) {
      int ile = random (10, 80);
      for (int k = 1; k < ile; k++) {
        nuta = random (0, 128);
        noteOn (nuta, random (36, 84), 0);
        delay(czas);
        noteOff (nuta, random (36, 84), 0);
      }
    }
  }
}
void rozwiniecie3 (long ile) {
  int nuta;
  for (int k = 0 ; k < ile; k++) {
    nuta = random (0, 128);
    if (random (0, 10) == 1) noteOn (nuta, random (36, 84), 0);
    delay(czas);
    noteOff (nuta, random (36, 84), 0);
    if (czas < 50) {
      czasInc = 1 * czasInc / abs(czasInc);
    } else {
      czasInc = 10 * czasInc / abs(czasInc);
    }
    czas = czas + czasInc;
    if (czas < 0) {
      czas = 0;
      czasInc = czasInc * -1;
    }
    if (czas > 100) {
      czas = 100;
      czasInc = czasInc * -1;
    }
    if (czas < 10) {
      int ile2 = random (10, 80);
      for (int k = 1; k < ile2; k++) {
        nuta = random (0, 128);
        noteOn (nuta, random (36, 84), 0);
        delay(czas);
        noteOff (nuta, random (36, 84), 0);
      }
    }
  }
}
void mors2(long ile) {
  int baza = random (0, 12);
  for (int k = 0; k < ile; k++) {
    for (int k = 24; k < 48; k++) {
      noteOn(k + baza, 45, 0);
    }
    for (int k = 24; k < 48; k++) {
      noteOff(k + baza, 0, 0);
    }
    delay(5);
    for (int k = 72; k < 96; k++) {
      noteOn(k + baza, 45, 0);
    }
    for (int k = 72; k < 96; k++) {
      noteOff(k + baza, 0, 0);
    }
    delay(3);
  }


}
void mors(long ile) {
  const int n = 2;
  unsigned long timeLayers[N];
  unsigned long lastLayers[N];
  long incLayers[N];
  timeLayers[0] = 3;
  timeLayers[1] = 1;
  incLayers[0] = -10;
  incLayers[1] = -10;
  unsigned long now = millis();
  lastLayers[0] = now;
  lastLayers[1] = now;
  for (int k = 0; k < ile; k++) {
    now = millis();
    if (now - lastLayers[0] > timeLayers[0]) {
      for (int k = 0; k < 60; k++) {
        noteOff(k, 0, 0);
        noteOn(k, 60, 0);
        lastLayers[0] = now;
      }
    }
    if (now - lastLayers[1] > timeLayers[1]) {
      for (int k = 61; k < 96; k++) {
        noteOff(k, 0, 0);
        noteOn(k, 60, 0);
        lastLayers[1] = now;
      }
    }
    //    for (int k = 0; k < n; k++) {
    //      timeLayers[k] = timeLayers[k] + incLayers[k];
    //      if (timeLayers[k] < 0) {
    //        timeLayers[k] = 0;
    //        incLayers[k] = incLayers[k] * -1;
    //      }
    //      if (timeLayers[k] > 500) {
    //        timeLayers[k] = 500;
    //        incLayers[k] = incLayers[k] * -1;
    //      }
    //    }
  }

}
void cresc() {
  int  d = 10;
  for (int v = 24; v < 128; v = v + 1) {
    for (int k = 0; k < 48; k++) {
      noteOn (k, v, 0);
    }
    delay (d);
    for (int k = 0; k < 48; k++) {
      noteOff (k, 0, 0);
    }
    for (int k = 0; k < 48; k++) {
      noteOn (k, v, 0);
    }
    delay (d);
    for (int k = 0; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
  for (int v = 0; v < 200; v = v + 1) {
    for (int k = 0; k < 48; k++) {
      noteOn (k, 127, 0);
    }
    delay (d);
    for (int k = 0; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
  for (int k = 0; k < 48; k++) {
    noteOn (k, 127, 0);
  }
  //  delay (4000);
  for (int k = 0; k < 48; k++) {
    noteOff (k, 0, 0);
  }
}
void ruchomeKlastery (long ile) {
  for (int n = 0; n < ile; n++) {
    int d = 0;
    for (int baza = 0; baza < 72; baza++) {
      for (int k = 24; k < 48; k++) {
        noteOn (k + baza, 127, 0);
      }
      delay (d);
      for (int k = 24; k < 48; k++) {
        noteOff (k + baza, 0, 0);
      }
    }
    for (int baza = 72; baza > 0; baza--) {
      for (int k = 24; k < 48; k++) {
        noteOn (k + baza, 127, 0);
      }
      delay (d);
      for (int k = 24; k < 48; k++) {
        noteOff (k + baza, 0, 0);
      }
    }
  }
}
void jbjbjb (bool action) {
  if (action == true) {
    for (int k = 24; k < 72; k++) {
      noteOn (k, 127, 0);
    }
  } else {
    for (int k = 0; k < 128; k++) {
      noteOff (k, 0, 0);
    }
  }
}
void klasterRozmigotany (long ile, int mini, int maxi, int veloMini, int veloMaxi, long trwanie, long odstep) {
  for (int n = 0; n < ile ; n++) {
    for (int k = mini; k <= maxi; k++) {
      noteOn (k, random (veloMini, veloMaxi + 1), 0);
    }
    delay (trwanie);
    for (int k = mini; k <= maxi; k++) {
      noteOff (k, 0, 0);
    }
    delay (odstep);
  }
}
void liniaRozmigotany (long ile, int mini, int maxi, int veloMini, int veloMaxi, long trwanie, long odstep) {
  int nuta;
  for (int n = 0; n < ile ; n++) {
    nuta = random (mini, maxi + 1);
    noteOn (nuta, random (veloMini, veloMaxi + 1), 0);
    delay (trwanie);
    noteOff (nuta, 0, 0);
    delay (odstep);
  }
}
void durowe (int ile) {
  int wzor[3] = {0, 4, 7};
  for (int k = 0; k < ile; k++) {
    int tonika = random (0, 12);
    for (int oktawa = 3; oktawa < 10; oktawa = oktawa + 12) {
      for (int skladnik = 0; skladnik < 3; skladnik++) {
        noteOn (tonika + wzor[skladnik] + (oktawa * 12), 127, 0);
        delay (random (80, 120));
        noteOff (tonika + wzor[skladnik] + (oktawa * 12), 0, 0);
      }
    }
  }
}
void durowe2 (int ile) {
  int wzor[3] = {0, 4, 7};
  int tonika;
  int velo;
  int maxi;
  int oktawaMin;
  int oktawaMax;
  int czasGrania;
  int czasPauzy;
  for (int k = 0; k < ile; k++) {
    // CHORD's parameters
    tonika = random (0, 12); // root note
    maxi = random (5, 20);
    velo = map (k % maxi, 0, maxi, 60, 127);
    oktawaMin = random (2, 6);
    oktawaMax = random (6, 12);
    czasGrania = random (20, 70);
    czasPauzy = 100 - czasGrania;
    // CHORD ON
    for (int oktawa = oktawaMin; oktawa < oktawaMax; oktawa = oktawa + 12) {
      for (int skladnik = 0; skladnik < 3; skladnik++) {
        noteOn (tonika + wzor[skladnik] + (oktawa * 12), velo, 0);
      }
    }
    delay (czasGrania);
    // CHORD OFF
    for (int oktawa = oktawaMin; oktawa < oktawaMax; oktawa = oktawa + 12) {
      for (int skladnik = 0; skladnik < 3; skladnik++) {
        noteOff (tonika + wzor[skladnik] + (oktawa * 12), 0, 0);
      }
    }
    delay (czasPauzy);
  }
}
void finau () {
  for (int l = 5000; l > 250; l = l - 300) {
    int veloMax = map (l, 300, 5000, 60, 72);
    veloMax = 72 - veloMax;
    for (int k = 24; k < 48; k++) {
      noteOn (k, random (48, veloMax), 0);
    }
    delay (l);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
  for (int l = 300; l > 10; l = l - 10) {
    int veloMax = map (l, 10, 300, 36, 48);
    veloMax = 48 - veloMax;
    for (int k = 24; k < 48; k++) {
      noteOn (k, random (30, veloMax), 0);
    }
    delay (l);
    for (int k = 24; k < 48; k++) {
      noteOff (k, 0, 0);
    }
  }
}
void sustain () {
  // odczekaj

  for (int l = 0; l < 200; l++) {
    for (int k = 24; k < 60; k++) {
      noteOn (k, random (24, 36), 0);
    }
    delay (10);
    for (int k = 24; k < 60; k++) {
      noteOff (k, 0, 0);
    }
  }
  // czekaj na cień
  while (analogRead(A6) > swiatloFinalProg) {
    for (int k = 24; k < 60; k++) {
      noteOn (k, random (24, 36), 0);
    }
    delay (10);
    for (int k = 24; k < 60; k++) {
      noteOff (k, 0, 0);
    }
  }
  okrzyk();
}
void okrzyk() {
  // crescendo
  for (int v = 48; v < 128; v++) {
    for (int k = 60; k < 96; k++) {
      noteOn (k, v, 0);
    }
    delay (10);
    for (int k = 60; k < 96; k++) {
      noteOff (k, 0, 0);
    }
  }
  // stay forever
  while (true) {
    for (int k = 60; k < 96; k++) {
      noteOn (k, random (117, 127), 0);
    }
    delay (10);
    for (int k = 60; k < 96; k++) {
      noteOff (k, 0, 0);
    }
  }
}
void noteOn (int pitch, int velo, int chann) {
  //  digitalWrite (13, LOW);
  Serial.write(B10010000 + chann);
  Serial.write(pitch);
  Serial.write(velo);
  //  digitalWrite (13, HIGH);
}
void noteOff (int pitch, int velo, int chann) {
  Serial.write(B10000000 + chann);
  Serial.write(pitch);
  Serial.write(velo);
}


Autorstwo kodu, partytury i realizacji dźwiękowej: Marcin Strzelecki

Układ elektroniczny do symulacji urządzenia MIDI przez mikrokontroler zbudowany przy współpracy Janusza Peszko