xxxxxxxxxx
210
let initialF = 1;
let fibArray = [],pArray = [],scaleArray = [];
var noteCnt = 1,cnt = 0,x=0,y=0;
let pLoop = 0,playN = 1;
let xpos = [0],ypos = [0];
let osc, envelope, fft;
let note = 0;
function setup() {
createCanvas(400, 400);//canvas
fibonacci();
makeSel1()
makeSel()
pisanoP(noteCnt);
//noLoop();
angleMode(DEGREES)
osc = new p5.SinOsc();
envelope = new p5.Env();// Instantiate the envelope
envelope.setADSR(0.001, 0.5, 0.1, 0.5);// set attackTime, decayTime, sustainRatio, releaseTime
envelope.setRange(0.5, 0); // set attackLevel, releaseLevel
osc.start();
fft = new p5.FFT();
}
function draw() {
translate(width/2,width/2)
if (frameCount % 30 === 0||frameCount == 1) {
noteCnt = sel.value();
background(0)
stroke(255)
textSize(9)
text('Pisano Period',-195,-160)
textSize(8)
text(pArray,-190,-180)
text(noteCnt,-170,-150)
stroke(0)
drawKeys()
drawCircle(noteCnt)
drawLines()
if (cnt == 0){
noFill()
stroke(0,0,200)
strokeWeight(10)
circle(0,0,300)
strokeWeight(1)
fill(255)
}
let midiValue = scaleArray[pArray[cnt]];
let freqValue = midiToFreq(midiValue);
osc.freq(freqValue);
envelope.play(osc, 0, 0.1);
keyLight(midiValue)
fill(0,0,255)
circle(xpos[pArray[cnt]],ypos[pArray[cnt]],15)
fill(255)
if (cnt < (pArray.length-1)){
cnt = cnt +1
}else {
cnt = 0;
}
}
}
function pisanoP(noteCnt){
pArray = [];
pArray[0] = 0;
if (noteCnt > 1) {
pArray[1] = 1;
}
if(noteCnt>1){
for (let i = 2;i<50;i++){
if (pArray[i-2]== (noteCnt-1) && pArray[i-1] ==1){
i = 50;
} else {
pArray[i] = fibArray[i] % noteCnt
}
}
}
}
function fibonacci(){
fibArray[0] = 0;
fibArray[1] = 1;
for (let i = 2; i<100;i++){
fibArray[i] =fibArray[i-1]+fibArray[i-2];
}
}
function drawCircle(noteCnt){
playN = pArray.length;
xpos = [];
ypos = []
circle(0,0,width/1.4)
theta = 0
delta = 360/noteCnt;
for (let i = 0;i<noteCnt;i++){
xpos[i] = cos(theta)*width/3
ypos[i] = sin(theta)*width/3
theta = theta + delta;
circle(xpos[i],ypos[i],10)
}
}
function drawLines(){
for (i =1;i<pArray.length;i++){
line(xpos[pArray[i-1]],ypos[pArray[i-1]],xpos[pArray[i]],ypos[pArray[i]]);
}
}
function drawKeys(){
fill(200)
rect(-width/2,width/2-50,width,50)
fill(255);
for (let i = 0;i<15;i++){
rect(-width/2+i*width/15,width/2-50,width/15,50)
fill(0)
if (i !=0 && i!=3 && i !=7 && i!=10 && i!=14){
rect(-width/2+i*width/15-5,width/2-70,width/30,50)
}
fill(255)
}
}
function keyLight(mV){
if (mV==60||mV==62 || mV==64){
x = -width/2+13 + 13.5*(mV-60)
y = width/2 - 20
}
if (mV == 61||mV==63){
x = -width/2+14 + 14*(mV-60)
y = width/2 - 25
}
if (mV==65||mV==67||mV==69||mV==71){
x = -width/2+93 + 13.5*(mV-65)
y = width/2 - 20
}
if (mV == 66||mV==68||mV==70){
x = -width/2+94 + 14*(mV-65)
y = width/2 - 25
}
if (mV == 72||mV==74||mV ==76){
x = -width/2+200 + 14*(mV-72)
y = width/2 - 20
}
if (mV == 73||mV==75){
x = -width/2+214 + 14*(mV-73)
y = width/2 - 25
}
if (mV==77||mV==79||mV==81||mV==83){
x = -width/2+280 + 13.5*(mV-77)
y = width/2 - 20
}
if (mV==78||mV==80||mV==82){
x = -width/2+293 + 14*(mV-78)
y = width/2 - 25
}
if (mV==84){
x = -width/2+386
y = width/2 - 20
}
//x = -width/2+12
fill(0,200,255)
circle(x,y,20)
fill(255)
}
function makeSel(){
print(noteCnt)
sel = createSelect();
sel.position(10, 420);
sel.selected(noteCnt);
sel.changed(mySelectEvent);
if(sel1.value() == 'half step'){
for(let i = 0;i<25;i++){
sel.option(i+1);
}
scaleArray = [60, 61,62,63, 64, 65,66, 67,68, 69,70, 71,72,73,74,75,76,77,78,79,80,81,82,83,84];
} else{
for(let i = 0;i<15;i++){
sel.option(i+1);
}
scaleArray = [60,62, 64, 65, 67, 69, 71,72,74,76,77,79,81,83,84];
}
}
function makeSel1(){
sel1 = createSelect();
sel1.position(80, 420);
sel1.option('majorscale');
sel1.option('half step');
sel1.changed(sel1Event);
}
function sel1Event(){
makeSel()
mySelectEvent()
}
function mySelectEvent() {
noteCnt = sel.value();
pisanoP(noteCnt);
cnt = 0;
}