Просто сохраните BufferSources где-нибудь во внешней области видимости, а затем вызовите их метод stop()
.
Я позволил себе немного переписать вашу логику загрузки, вы не должны создавать новый запрос каждый раз, когда выНачните новый трек, в этом случае вы потеряете основные преимущества AudioBuffers перед элементом Audio: их действительно быстро создать.
var active_source = null;
function stopActiveSource() {
if (active_source) {
active_source.onended = null; // manual stop, no event
active_source.stop(0);
}
}
// instead of requesting a new ArrayBuffer every time
// store them in a dictionnary
var buffers = {};
var context = new(window.AudioContext || window.webkitAudioContext)();
function playTrack(url) {
// get fom our dictionnary
var buffer = buffers[url];
// stop the active one if any
stopActiveSource();
// create a new BufferSource
var source = context.createBufferSource();
// it is now the active one
active_source = source;
source.onended = function() {
active_source = null;
};
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
}
// start by getting all AudioBuffers
var tracks = document.getElementsByClassName('track');
for (var i = 0, len = tracks.length; i < len; i++) {
tracks[i].addEventListener('click', function(e) {
playTrack(this.href);
e.preventDefault();
});
getBuffer(tracks[i].href);
}
function getBuffer(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function(evt) {
context.decodeAudioData(request.response, store);
};
request.send();
function store(buffer) {
buffers[url] = buffer;
}
}
<base href="https://dl.dropboxusercontent.com/s/">
<ul>
<li><a class="track" href="kbgd2jm7ezk3u3x/hihat.mp3">HiHat</a></li>
<li><a class="track" href="h2j6vm17r07jf03/snare.mp3">Snare</a></li>
<li><a class="track" href="1cdwpm3gca9mlo0/kick.mp3">Kick</a></li>
<li><a class="track" href="h8pvqqol3ovyle8/tom.mp3">Tom</a></li>
</ul>