I am randomly playing 4 notes, A4,B4,C4,D4 from an array using MonoSynth. I also have four coloured quadrants representing each note. Blue=A4, Yellow=B4, Red=C4, Green=D4.
I am using a promise/await in a for loop.
Should the note A4 be played (and it does) I would then colour the Blue square Pink for the duration of the note, returning to blue once finished playing. To reiterate should the note C4 come up, it would then be played and the red square would be colored pink for the duration for the note being played and then return to red.
My problem is: I cannot synch the note duration with the graphical pink square. I have worked on this for some days viewing documentation, youtube and even a helpful answer from stackoverflow for the early part of this program.
Any help would be greatly appreciated.
SEE:
let keys = ["A4", "B4", "C4", "D4"];
let monoSynth = new p5.MonoSynth();
let notes = [];
let quadrants = [];
let start=true;
function setup() {
createCanvas(500,500);
background('grey');
}
function topLeft1(){
fill('blue');
rect(100,100,150,150);
}
function topRight1(){
fill('yellow');
rect(250,100,150,150);
}
function bottomLeft1(){
fill('red');
rect(100,250,150,150);
}
function bottomRight1(){
fill('green');
rect(250,250,150,150);
}
function topLeft2(){
fill('pink');
rect(100,100,150,150);
}
function topRight2(){
fill('pink');
rect(250,100,150,150);
}
function bottomLeft2(){
fill('pink');
rect(100,250,150,150);
}
function bottomRight2(){
fill('pink');
rect(250,250,150,150);
}
function originalSquares(){
topLeft1();
topRight1();
bottomLeft1();
bottomRight1();
}//osqrs
function pinkSquare(n){
if (n==0){
topLeft2();
}
else if (n==1){
topRight2();
}
else if (n==2){
bottomLeft2;
}
else{
bottomRight2();
}
}//ps
function loadKeys(x,y){
for (let i=0; i<30;i++){
let temp= round(random(0,3));
y[i]=temp;
x[i]=keys[temp];
}//for i
}//loadKeys
function asyncDelay(t) {
return new Promise(res => setTimeout(res, t));
}
async function playStuff() {
for (let i=0; i<30;i++){
monoSynth.play(notes[i], 5, 0, 3/ 6);
pinkSquare(quadrants[i]);
print(notes[i]);
await asyncDelay(3/ 6 * 1000);
originalSquares();
}//for i
} //playStuff
function draw() {
if (start==true){
originalSquares();
start=false;
}//if
loadKeys(notes,quadrants);
playStuff();
noLoop();
} //draw
Try using p5.SoundLoop to control syncing the audio with the video. It is part of the p5.sound library that you are already using to get p5.MonoSynth to work. I provided an example below that merges elements of your code with the example found on the reference link provided to give you some ideas on how to adopt it. Instead of looping an array of 30 notes, this code continuously chooses random notes from the 4 keys provided. I also made some changes so you can use less functions to create the different squares and some other minor tweaks, but of course, take what you want from this.
let keys = ["A4", "B4", "C4", "D4"];
let synth, soundLoop;
function topLeft(c){
fill(c);
rect(100,100,150,150);
}
function topRight(c){
fill(c);
rect(250,100,150,150);
}
function bottomLeft(c){
fill(c);
rect(100,250,150,150);
}
function bottomRight(c){
fill(c);
rect(250,250,150,150);
}
function originalSquares(){
topLeft('blue');
topRight('yellow');
bottomLeft('red');
bottomRight('green');
}//osqrs
function pinkSquare(n){
switch(n){
case 0:
topLeft('pink');
break;
case 1:
topRight('pink');
break;
case 2:
bottomLeft('pink');
break;
case 3:
bottomRight('pink');
}
}//ps
function setup() {
let cnv = createCanvas(500, 500);
cnv.mousePressed(canvasPressed);
background('grey');
text('tap to start/stop', 10, 20);
let intervalInSeconds = 0.5;
soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);
synth = new p5.MonoSynth();
}
function canvasPressed() {
// ensure audio is enabled
userStartAudio();
if (soundLoop.isPlaying) {
soundLoop.stop();
} else {
soundLoop.start();
}
}
function onSoundLoop(timeFromNow) {
let randomNote = random(keys);
let noteIndex = keys.indexOf(randomNote);
synth.play(randomNote, 0.5, timeFromNow);
originalSquares();
pinkSquare(noteIndex);
}
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script>
<meta charset="utf-8" />
</head>
<body>
</body>
</html>