I need to layer looping .wav tracks that ultimately I will need to be able to turn on and off and keep in sync.
First I load the tracks and stopped BufferLoader
from turning the loaded arraybuffer
into an AudioBuffer
(hence the false
)
function loadTracks(data) {
for (var i = 0; i < data.length; i++) {
trackUrls.push(data[i]['url']);
};
bufferLoader = new BufferLoader(context, trackUrls, finishedLoading);
bufferLoader.load(false);
return loaderDefered.promise;
}
When you click a button on screen it calls startStop()
.
function startStop(index, name, isPlaying) {
if(!activeBuffer) {
activeBuffer = bufferList[index];
}else{
activeBuffer = appendBuffer(activeBuffer, bufferList[index]);
}
context.decodeAudioData(activeBuffer, function(buffer){
audioBuffer = buffer;
play();
})
function play() {
var scheduledTime = 0.015;
try {
audioSource.stop(scheduledTime);
} catch (e) {}
audioSource = context.createBufferSource();
audioSource.buffer = audioBuffer;
audioSource.loop = true;
audioSource.connect(context.destination);
var currentTime = context.currentTime + 0.010 || 0;
audioSource.start(scheduledTime - 0.005, currentTime, audioBuffer.duration - currentTime);
audioSource.playbackRate.value = 1;
}
Most of the code I found on this guys github. In the demo you can hear he is layering AudioBuffers.
I have tried the same on my hosting.
Disregarding the argularJS
stuff, the Web Audio stuff is happening on the service.js
at:
/js/angular/service.js
If you open the console and click the buttons you can see the activeBuffer.byteLength
(type ArrayBuffer) is incrementing, however even after being decoded by the context.decodeAudioData
method it still only plays the first sound you clicked instead of a merged AudioBuffer
data.set(buffer1.getChannelData(i)); data.set(buffer2.getChannelData(i),buffer1.length);
to append two buffers. what if we want to merge them. so they play at same time – Pyoid