// Classical 2sf // Classical Inprvisation 2 // September 1, 2017 -- John Clavin // Fix - September 22, 2018 -- John Clavin var sfnames = [ 'wavfiles/m52.wav', 'wavfiles/m53.wav', 'wavfiles/m54.wav', 'wavfiles/m55.wav', 'wavfiles/m56.wav', 'wavfiles/m57.wav', 'wavfiles/m58.wav', 'wavfiles/m59.wav', 'wavfiles/m60.wav', 'wavfiles/m61.wav', 'wavfiles/m62.wav', 'wavfiles/m63.wav', 'wavfiles/m64.wav', 'wavfiles/m65.wav', 'wavfiles/m66.wav', 'wavfiles/m67.wav', 'wavfiles/m68.wav', 'wavfiles/m69.wav', 'wavfiles/m70.wav', 'wavfiles/m71.wav', 'wavfiles/m72.wav', 'wavfiles/m73.wav', 'wavfiles/m74.wav', 'wavfiles/m75.wav' ] var piano = []; var reverb = []; function preload() { for (n = 0; n < sfnames.length; n++) { piano[n] = loadSound(sfnames[n]); } } var noteArray = [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 ]; var minorTemplate = [2, 0, 1, 2, 0, 0, 0, 2, 0, 1, 1, 0, 2, 0, 1, 2, 0, 0, 0, 2, 0, 1, 1, 0, 2, 0, 1, 2, 0, 0, 0, 2, 0, 1, 1, 0, 2, 0 ]; var majorTemplate = [2, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0, 1, 2, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0, 1, 2, 0, 1, 0, 2, 0, 0, 2, 0, 1, 0, 1 ]; var dom7Template = [2, 0, 1, 0, 2, 0, 0, 2, 0, 1, 2, 0, 2, 0, 1, 0, 2, 0, 0, 2, 0, 1, 2, 0, 2, 0, 1, 0, 2, 0, 0, 2, 0, 1, 2, 0 ]; var dimTemplate = [2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1 ]; var tempChordArray = [2, 0, 1, 2, 0, 0, 0, 2, 0, 1, 1, 0, 2, 0, 1, 2, 0, 0, 0, 2, 0, 1, 1, 0 ]; var keyArray = [ [2, 2], [4, 2], [5, 1], [7, 3], [8, 3], [9, 2], [10, 3], [11, 4] ]; var chordProgression = [ [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] ]; var parserDirFlag; var parserIndex; var voiceArray = []; var music; var goMusic = false; var xPos = 0; var chordPIndex = 0; var lastRnd; function setup() { createCanvas(960, 400); frameRate(60); rectMode(CENTER); noStroke(); background(238); lastRand = floor(random(7)); masterVolume(0.50); parserDirFlag = true; parserIndex = 4; for (var v = 0; v < 4; v++) { voice = new jcOsc(); voiceArray.push(voice); } for (r = 0; r < piano.length; r++) { reverb[r] = new p5.Reverb(); reverb[r].process(piano[r], 1.74, 0.0); piano[r].setVolume(0.70); reverb[r].amp(1.0); } createChords(); music = new MusicManagement(); music.composeSpaces(); } function mousePressed() { goMusic = true; } function draw() { if (goMusic) { music.manage(); } } function MusicManagement() { this.timeSpaces = []; this.tsCounter = 0; this.composeSpaces = function() { for (var i = 0; i < 386; i++) { var s = new TimeSpace(); this.timeSpaces.push(s); } for (var j = 0; j < this.timeSpaces.length; j++) { this.timeSpaces[j].compose(j); } } this.manage = function() { this.timeSpaces[this.tsCounter].musicGraphics(); if ((this.tsCounter + 1) < this.timeSpaces.length) { if (frameCount % 11 == 1) { this.timeSpaces[this.tsCounter].play(); this.tsCounter++; } } else { goMusic = false; } } } function TimeSpace() { this.noteFoundFlag = false; this.hiNotesFlag = false; this.musicChord = 0; this.chordType = 0; this.notes2Play = []; this.numberOfNotes = 0; this.beatAmount = 0; this.chordIndex = 0; this.chordPIndex = 0; this.compose = function(spaceNumber) { if (spaceNumber % 128 == 127) { chordPIndex = 0; } this.beatAmount = chordProgression[chordPIndex][1]; this.numberOfNotes = 1; if (spaceNumber % this.beatAmount === 0) { this.numberOfNotes = 4; var c = chordProgression[chordPIndex][0] chordPIndex++; this.musicChord = keyArray[c][0]; this.chordType = keyArray[c][1]; // console.log(this.musicChord+" "+this.chordType) if (this.chordType == 1) { for (var maj = 0; maj < tempChordArray.length; maj++) { tempChordArray[maj] = majorTemplate[maj + (12 - this.musicChord)]; } } else if (this.chordType == 2) { for (var minor = 0; minor < tempChordArray.length; minor++) { tempChordArray[minor] = minorTemplate[minor + (12 - this.musicChord)]; } } else if (this.chordType == 3) { for (var d7 = 0; d7 < tempChordArray.length; d7++) { tempChordArray[d7] = dom7Template[d7 + (12 - this.musicChord)]; } } else { for (var dim = 0; dim < tempChordArray.length; dim++) { tempChordArray[dim] = dimTemplate[dim + (12 - this.musicChord)]; } } } if (this.numberOfNotes == 1) { noteFoundFlag = false; while (noteFoundFlag === false) { if (tempChordArray[parserIndex] > 0) { var note = noteArray[parserIndex]; this.notes2Play[0] = note; noteFoundFlag = true; } this.parserMove(); } if (random(100) < 22) { if (this.hiNotesFlag === true) { parserIndex = floor(random(4, 11)); } else { parserIndex = floor(random(13, 20)); } parserDirFlag = !parserDirFlag; noteFoundFlag = false; while (noteFoundFlag === false) { if (tempChordArray[parserIndex] == 2) { note = noteArray[parserIndex]; this.notes2Play[0] = note; noteFoundFlag = true; } this.parserMove(); } } } else { this.chordIndex = floor(random(4, 6)); for (var j = 0; j < 4; j++) { this.noteFoundFlag = false; while (this.noteFoundFlag === false) { if (tempChordArray[this.chordIndex] == 2) { note = noteArray[this.chordIndex]; this.notes2Play[j] = note; this.noteFoundFlag = true; } this.chordIndex++; } } } } this.parserMove = function() { if (parserIndex >= 23) { parserIndex = parserIndex - 3; parserDirFlag = false; } if (parserIndex <= 1) { parserIndex = parserIndex + 2; parserDirFlag = true; } if (parserDirFlag === true) { parserIndex++; } else { parserIndex--; } if (parserIndex > 12) { this.hiNotesFlag = true; } else { this.hiNotesFlag = false; } } this.play = function() { for (var n = 0; n < this.numberOfNotes; n++) { voiceArray[n].jamOn(this.notes2Play[n]); } } this.musicGraphics = function() { xPos = xPos + 0.25; for (var n = 0; n < this.numberOfNotes; n++) { var yPos = map(this.notes2Play[n], 77, 52, 0, height); noStroke(); if (this.numberOfNotes > 1) { fill(0); } else { fill(200, 0, 0); } rect(xPos, yPos, 6, 12); } } } function jcOsc() { this.jamOn = function(xnote) { this.note = xnote - 53; piano[this.note].play(); } } function createChords() { for (c = 0; c < 16; c++) { chordProgression[c][0] = rndNoRepeat(8); if (random(100) < 24) { var beats = 8; } else { beats = 16; } chordProgression[c][1] = beats; } } function rndNoRepeat(randomField) { var test = floor(random(randomField)); while (test == lastRand) { test = floor(random(randomField)); } lastRand = test; return test; }