use buffersource objects to play sounds, to fix #4

This commit is contained in:
Eric Rosenbaum 2016-11-01 16:00:43 -04:00
parent 173c243439
commit 9763acb99a

View file

@ -28,8 +28,8 @@ function AudioEngine (sounds) {
// load sounds // load sounds
this.soundPlayers = []; this.soundPlayers = this.loadSounds(sounds);
this.loadSounds(sounds); // Tone.Buffer.on('load', this._soundsLoaded.bind(this));
// soundfont setup // soundfont setup
@ -59,43 +59,46 @@ function AudioEngine (sounds) {
} }
AudioEngine.prototype.loadSounds = function (sounds) { AudioEngine.prototype.loadSounds = function (sounds) {
var soundPlayers = [];
for (var i=0; i<sounds.length; i++) { for (var i=0; i<sounds.length; i++) {
// skip adpcm form sounds since we can't load them yet // skip adpcm form sounds since we can't load them yet
if (sounds[i].format == 'adpcm') { if (sounds[i].format == 'adpcm') {
log.warn('cannot load sound in adpcm format'); log.warn('cannot load sound in adpcm format');
continue; continue;
} }
this.soundPlayers[i] = new Tone.Player(sounds[i].fileUrl);
this.soundPlayers[i].connect(this.effectsNode); var player = {};
player.buffer = new Tone.Buffer(sounds[i].fileUrl);
player.bufferSource = null;
soundPlayers[i] = player;
} }
return soundPlayers;
}; };
// AudioEngine.prototype._soundsLoaded = function() {
// console.log('all sounds loaded');
// }
AudioEngine.prototype.playSound = function (index) { AudioEngine.prototype.playSound = function (index) {
var player = this.soundPlayers[index]; // if the soundplayer exists and its buffer has loaded
if (player && player.buffer.loaded) { if (this.soundPlayers[index] && this.soundPlayers[index].buffer.loaded) {
player.start(); // stop the sound if it's already playing
return new Promise(function (resolve) { var bufferSource = this.soundPlayers[index].bufferSource;
setTimeout(function () { if (bufferSource) {
resolve(); bufferSource.stop();
}, (player.buffer.duration * 1000) / player.playbackRate);
});
} else {
// if the sound has not yet loaded, wait and try again
log.warn('sound ' + index + ' not loaded yet');
if (player) {
setTimeout(function () {
this.playSound(index);
}.bind(this), 500);
} }
} // create a new buffer source to play the sound
}; var bufferSource = new Tone.BufferSource(this.soundPlayers[index].buffer.get());
bufferSource.connect(this.effectsNode);
bufferSource.start();
bufferSource.playbackRate.value = this._getPitchRatio();
this.soundPlayers[index].bufferSource = bufferSource;
AudioEngine.prototype.getSoundDuration = function (index) { return new Promise(function(resolve) {
var player = this.soundPlayers[index]; bufferSource.onended = function(){resolve()};
if (player && player.buffer.loaded) { });
return player.buffer.duration;
} else {
return 0;
} }
}; };
@ -146,7 +149,10 @@ AudioEngine.prototype.stopAllSounds = function () {
// stop sounds triggered with playSound // stop sounds triggered with playSound
if (this.soundPlayers && this.soundPlayers.length > 0) { if (this.soundPlayers && this.soundPlayers.length > 0) {
for (var i=0; i<this.soundPlayers.length; i++) { for (var i=0; i<this.soundPlayers.length; i++) {
this.soundPlayers[i].stop(); var bufferSource = this.soundPlayers[i].bufferSource;
if (bufferSource) {
bufferSource.stop();
}
} }
} }
// stop soundfont notes // stop soundfont notes
@ -211,15 +217,20 @@ AudioEngine.prototype._setPitchShift = function (value) {
if (!this.soundPlayers) { if (!this.soundPlayers) {
return; return;
} }
var ratio = this.tone.intervalToFrequencyRatio(this.pitchEffectValue / 10);
var ratio = this._getPitchRatio();
for (var i=0; i<this.soundPlayers.length; i++) { for (var i=0; i<this.soundPlayers.length; i++) {
var s = this.soundPlayers[i]; var s = this.soundPlayers[i].bufferSource;
if (s) { if (s && s.playbackRate) {
s.playbackRate = ratio; s.playbackRate.value = ratio;
} }
} }
}; };
AudioEngine.prototype._getPitchRatio = function () {
return this.tone.intervalToFrequencyRatio(this.pitchEffectValue / 10);
};
AudioEngine.prototype.setInstrument = function (instrumentNum) { AudioEngine.prototype.setInstrument = function (instrumentNum) {
return Soundfont.instrument(Tone.context, this.instrumentNames[instrumentNum]).then( return Soundfont.instrument(Tone.context, this.instrumentNames[instrumentNum]).then(
function (inst) { function (inst) {