×
Etiuda stochastyczna – nagranie wideo
„Partytura” PDF (średnio 300 nut na sekundę.): StrzeleckiImprowizacjaStochastycznaNaMikrokontroler-162146-EVENTS-300perSec.pdf
Wizualizacja video:
Rolka pianolowa:
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