So I am trying to make an app that generates music, but I cant seem to figure out how to only play one sound at a time. When i click the generate button then it plays all the sounds at once instead of one at a time. Here is my code:
var melody_notes = [A3, A4, A5, A6, B3, B4, B5, B6, C3, C4, C5, C6, D3, D4, D5, D6, E3, E4, E5, E6, F3, F4, F5, F6, G3, G4, G5, G6];
function generate() {
for (var a = 0; a < 100; a ) {
for (var i = 0; i < 1; i ) {
var pick = Math.floor(Math.random() * melody_notes.length);
var note = new Audio(melody_notes[pick]);
note.play();
}
}
}
So the list up above are the sound files, then it picks a random one and plays it. The first for loop is the amount of notes in the song, and the inner for loop is the amount of notes played together. But when i press the button which activates the function plays all the notes at once. Is there any way to fix that?
CodePudding user response:
I figured it out thanks to a post that just got deleted!
async function generate() {
for (var a = 0; a < 100; a ) {
var pick = Math.floor(Math.random() * melody_notes.length);
var note = new Audio(melody_notes[pick]);
await note.play();
sleep(500);
}
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i ) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
Whoever posted that thanks a lot! I have been trying to fix this problem for a while!
CodePudding user response:
You can create a promise and start the next sound when the previous one resolves.
const audios = [
'https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3',
'https://dl.dropboxusercontent.com/s/h2j6vm17r07jf03/snare.mp3',
'https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3',
'https://dl.dropboxusercontent.com/s/h2j6vm17r07jf03/snare.mp3'
];
async function playSounds(arr) {
for (let i = 0; i < arr.length; i ) {
await new Promise((resolve) => {
sound = new Audio(arr[i]);
sound.onended = resolve;
sound.play();
});
}
}
<button onclick="playSounds(audios);">play</button>