// Prelude in C major from WTC I // Johan Sebastian Bach (1685-1750), BWV 846 // Coding by Antanas Budriūnas in July 2012 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, Inc. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //---- Harmony data (MIDI notes) ---------- [ [60, 64, 67, 72, 76], [60, 62, 69, 74, 77], [59, 62, 67, 74, 77], [60, 64, 67, 72, 76], [60, 64, 69, 76, 81], [60, 62, 66, 69, 74], [59, 62, 67, 74, 79], [59, 60, 64, 67, 72], [57, 60, 64, 67, 72], [50, 57, 62, 66, 72], [55, 59, 62, 67, 71], [55, 58, 64, 67, 73], [53, 57, 62, 69, 74], [53, 56, 62, 65, 71], [52, 55, 60, 67, 72], [52, 53, 57, 60, 65], [50, 53, 57, 60, 65], [43, 50, 55, 59, 65], [48, 52, 55, 60, 64], [48, 55, 58, 60, 64], [41, 53, 57, 60, 64], [42, 48, 57, 60, 63], [44, 53, 59, 60, 62], [43, 53, 55, 59, 62], [43, 52, 55, 60, 64], [43, 50, 55, 60, 65], [43, 50, 55, 59, 65], [43, 51, 57, 60, 66], [43, 52, 55, 60, 67], [43, 50, 55, 60, 65], [43, 50, 55, 59, 65], [36, 48, 55, 58, 64], [36, 48, 50, 53, 57, 60, 65], [36, 47, 62, 64, 65, 67, 71, 74, 77], [36, 48, 64, 67, 72] ] @=> int geile[][]; //---- Initial data and variables ------- [0., 1., -.5, 1.] @=> float figura[]; // main figuration 180::ms => dur d; // main notes' duration 0 => int n; // length (counting number of notes) now => time prad; Event ev; // for shreds' interaction int sk[]; //holds order for playing notes //-------------- Patch ------------------- JCRev r => dac; Rhodey rh[3]; for (0 => int i; i < rh.cap(); i++) { rh[i] => r; 0.1 => rh[i].gain; } //--------------- Figuration ------------- fun int[] fig (float forma[], int gama) /* values in the 'forma' array: * >0..1 – consecutive movement * -1..<0 – leap-wise movement * 'gama': lenght of notes' range */ { int s[1]; int h; //for each figuration turning point for (0 => int i; i < forma.cap(); i++) { if (forma[i] == 0) .001 +=> forma[i]; Std.abs((forma[i]*(gama-1)) $ int) => int k; if (i == 0) k => s[0]; else if (forma[i] > 0) { s[s.cap()-1] => h; while (h != k) { if (h < k) {h++;} else {h--;} s << h; } } else s << k; } return s; } //---------------- Fade ------------------- fun float fade(int i, int n) { return .95 + Math.fabs(2/(i-n-1) $ float); } //----------- One Pass ------------------ fun void grok (Event e, int g[], int ge[], dur d[]) { e => now; 0 => int j; // Ugen number in array for(0 => int i; i < g.cap(); i++) { Std.mtof(ge[g[i]]) => rh[j].freq; rh[j].noteOn(0.9); d[i] => now; if (i < 2) j++; else rh[j].noteOff(0.); if (i == g.cap()-1) { rh[0].noteOff(0.); rh[1].noteOff(0.); } } e.signal(); } //------------ Final chord function --------------- fun void akgrok(Event e,int s[]) { e => now; Rhodey rho[s.cap()]; for (0 => int i; i < rho.cap(); i++) { .1 => rho[i].gain; rho[i] => r; Std.mtof(s[i]) => rho[i].freq; rho[i].noteOn(1.); 50::ms => now; } } //----------- Play One Measure ------------------- for (0 => int i; i < geile.cap()-3; i++) { fig(figura, geile[i].cap()) @=> sk; dur da[0]; for (0 => int j; j < sk.cap(); j++) da << d; sk.cap()*2 +=> n; // counting number of notes spork ~ grok(ev, sk, geile[i], da); spork ~ grok(ev, sk, geile[i], da); } //------------- Coda --------------- geile.cap()-3 => int i; fig([0., .2, -.5, 1., .8, .9, .5, .7, .4, .5, .4], geile[i].cap()) @=> sk; dur da[0]; // array of durations for (0 => int j; j < sk.cap(); j++) da << d; spork ~ grok(ev, sk, geile[i], da); sk.cap() +=> n; // counting number of notes i++; fig([0., .2, -.7, 1., .8, .9, .7, .8, -.3, -.5, .3], geile[i].cap()) @=> sk; dur db[0]; // array of durations for (0 => int j; j < sk.cap(); j++) { db << fade(j, sk.cap()) * d; } spork ~ grok(ev, sk, geile[i], db); sk.cap() +=> n; // counting number of notes i++; //------------- Main Flow Control ------------ me.yield(); ev.signal(); prad + d * n => time baik; while (true) { d => now; if (now >= baik) { ev.signal(); break; } } //------------ Final Chord ------- <<<"The End","">>>; akgrok(ev, geile[geile.cap()-1]); 4::second => now; me.exit();