Reputation: 610
I'm reading audio files from the server. And I have an array for raw audio files.
const allAudio = [];
Then I play them sequentially.
var volumeSeq=1;
function playAudio(){
if(volumeSeq==allAudio.length){ volumeSeq=1;}
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
source = audioCtx.createBufferSource();
audioCtx.decodeAudioData(allAudio[volumeSeq], function(buffer) {
source.buffer = buffer;
console.log(source.buffer);
source.connect(audioCtx.destination);
source.loop = false;});
source.start(0);
source.onended = function () {
volumeSeq++;
playAudio();
}
I catch the problem. But I don't know why. Problem is, that after the decoding i.element of the array, the element in it is being deleted. I mean when I decode the allAudio[1] then allAudio[1] is empty. So I cant create a loop for these audio tracks.
What should i do?
Upvotes: 1
Views: 656
Reputation: 2010
Why don't you decode all audio files at the begining, and then loop through them? Like this:
var allAudio = [];
var audioCtx = new AudioContext();
var volumeSeq = 0;
var decodedAudio = [];
function decodeAudio() {
allAudio.forEach(function (file, index) {
audioCtx.decodeAudioData(file, function(buffer) {
decodedAudio[index] = buffer;
if (decodedAudio.length >= allAudio.length) {
play();
}
})
})
}
function play() {
if (volumeSeq >= allAudio.length){ volumeSeq=0;}
var source = audioCtx.createBufferSource();
source.buffer = decodedAudio[volumeSeq];
source.connect(audioCtx.destination);
source.start(0);
source.onended = function () {
volumeSeq++;
play();
}
}
decodeAudio();
Few more things:
AudioContext
every time.AudioBufferSourceNode.loop
is false by default. You can skip source.loop = false;
const
, let
or var
. You are missing it with source
. BTW nowadays it is beter to use const
and let
, not var
. I will show it in next "modern" example.allAudio
starting from index 1. First index in array is 0.If you don't care about old browsers like IE, you can make code cleaner by using Promises
and async/await
:
const audioCtx = new AudioContext();
async function start() {
const decodedAudio = await Promise.all(allAudio.map((file) => audioCtx.decodeAudioData(file)));
let volumeSeq = 0;
function play() {
if(volumeSeq >= allAudio.length) volumeSeq = 0;
const source = audioCtx.createBufferSource();
source.buffer = decodedAudio[volumeSeq];
source.connect(audioCtx.destination);
source.start(0);
source.addEventListener('ended', () => {
volumeSeq++;
play();
}, { once: true })
}
play();
}
start()
Upvotes: 2