mirror of
https://github.com/scratchfoundation/scratch-audio.git
synced 2025-01-08 13:51:58 -05:00
commit
7dd6d557bb
2 changed files with 47 additions and 38 deletions
|
@ -2,7 +2,7 @@ const PanEffect = require('./effects/PanEffect');
|
||||||
const PitchEffect = require('./effects/PitchEffect');
|
const PitchEffect = require('./effects/PitchEffect');
|
||||||
const VolumeEffect = require('./effects/VolumeEffect');
|
const VolumeEffect = require('./effects/VolumeEffect');
|
||||||
|
|
||||||
const SoundPlayer = require('./SoundPlayer');
|
const SoundPlayer = require('./GreenPlayer');
|
||||||
|
|
||||||
class AudioPlayer {
|
class AudioPlayer {
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,7 @@ class AudioPlayer {
|
||||||
|
|
||||||
this.outputNode = this.audioEngine.audioContext.createGain();
|
this.outputNode = this.audioEngine.audioContext.createGain();
|
||||||
|
|
||||||
// Create the audio effects
|
// Create the audio effects.
|
||||||
const volumeEffect = new VolumeEffect(this.audioEngine, this, null);
|
const volumeEffect = new VolumeEffect(this.audioEngine, this, null);
|
||||||
const pitchEffect = new PitchEffect(this.audioEngine, this, volumeEffect);
|
const pitchEffect = new PitchEffect(this.audioEngine, this, volumeEffect);
|
||||||
const panEffect = new PanEffect(this.audioEngine, this, pitchEffect);
|
const panEffect = new PanEffect(this.audioEngine, this, pitchEffect);
|
||||||
|
@ -33,12 +33,11 @@ class AudioPlayer {
|
||||||
pitchEffect.connect(panEffect);
|
pitchEffect.connect(panEffect);
|
||||||
volumeEffect.connect(pitchEffect);
|
volumeEffect.connect(pitchEffect);
|
||||||
|
|
||||||
// reset effects to their default parameters
|
// Reset effects to their default parameters.
|
||||||
this.clearEffects();
|
this.clearEffects();
|
||||||
|
|
||||||
// sound players that are currently playing, indexed by the sound's
|
// SoundPlayers mapped by sound id.
|
||||||
// soundId
|
this.soundPlayers = {};
|
||||||
this.activeSoundPlayers = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +54,19 @@ class AudioPlayer {
|
||||||
* players
|
* players
|
||||||
*/
|
*/
|
||||||
getSoundPlayers () {
|
getSoundPlayers () {
|
||||||
return this.activeSoundPlayers;
|
return this.soundPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a SoundPlayer instance to soundPlayers map.
|
||||||
|
* @param {SoundPlayer} soundPlayer - SoundPlayer instance to add
|
||||||
|
*/
|
||||||
|
addSoundPlayer (soundPlayer) {
|
||||||
|
this.soundPlayers[soundPlayer.id] = soundPlayer;
|
||||||
|
|
||||||
|
for (const effectName in this.effects) {
|
||||||
|
this.effects[effectName].update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,37 +75,16 @@ class AudioPlayer {
|
||||||
* @return {Promise} a Promise that resolves when the sound finishes playing
|
* @return {Promise} a Promise that resolves when the sound finishes playing
|
||||||
*/
|
*/
|
||||||
playSound (soundId) {
|
playSound (soundId) {
|
||||||
// if this sound is not in the audio engine, return
|
|
||||||
if (!this.audioEngine.audioBuffers[soundId]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this sprite or clone is already playing this sound, stop it first
|
|
||||||
if (this.activeSoundPlayers[soundId]) {
|
|
||||||
this.activeSoundPlayers[soundId].stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a new soundplayer to play the sound
|
// create a new soundplayer to play the sound
|
||||||
const player = new SoundPlayer(this.audioEngine.audioContext);
|
if (!this.soundPlayers[soundId]) {
|
||||||
player.setBuffer(this.audioEngine.audioBuffers[soundId]);
|
this.addSoundPlayer(new SoundPlayer(
|
||||||
player.connect(this.outputNode);
|
this.audioEngine,
|
||||||
player.start();
|
{id: soundId, buffer: this.audioEngine.audioBuffers[soundId]}
|
||||||
|
));
|
||||||
// add it to the list of active sound players
|
|
||||||
this.activeSoundPlayers[soundId] = player;
|
|
||||||
for (const effectName in this.effects) {
|
|
||||||
this.effects[effectName].update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove sounds that are not playing from the active sound players
|
|
||||||
// array
|
|
||||||
for (const id in this.activeSoundPlayers) {
|
|
||||||
if (this.activeSoundPlayers.hasOwnProperty(id)) {
|
|
||||||
if (!this.activeSoundPlayers[id].isPlaying) {
|
|
||||||
delete this.activeSoundPlayers[id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const player = this.soundPlayers[soundId];
|
||||||
|
player.connect(this);
|
||||||
|
player.play();
|
||||||
|
|
||||||
return player.finished();
|
return player.finished();
|
||||||
}
|
}
|
||||||
|
@ -104,8 +94,8 @@ class AudioPlayer {
|
||||||
*/
|
*/
|
||||||
stopAllSounds () {
|
stopAllSounds () {
|
||||||
// stop all active sound players
|
// stop all active sound players
|
||||||
for (const soundId in this.activeSoundPlayers) {
|
for (const soundId in this.soundPlayers) {
|
||||||
this.activeSoundPlayers[soundId].stop();
|
this.soundPlayers[soundId].stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,18 @@ class SoundPlayer extends EventEmitter {
|
||||||
|
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
|
this.startingUntil = 0;
|
||||||
this.playbackRate = 1;
|
this.playbackRate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is plaback currently starting?
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isStarting () {
|
||||||
|
return this.isPlaying && this.startingUntil > this.audioEngine.audioContext.currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle any event we have told the output node to listen for.
|
* Handle any event we have told the output node to listen for.
|
||||||
* @param {Event} event - dom event to handle
|
* @param {Event} event - dom event to handle
|
||||||
|
@ -146,6 +155,7 @@ class SoundPlayer extends EventEmitter {
|
||||||
const taken = new SoundPlayer(this.audioEngine, this);
|
const taken = new SoundPlayer(this.audioEngine, this);
|
||||||
taken.playbackRate = this.playbackRate;
|
taken.playbackRate = this.playbackRate;
|
||||||
if (this.isPlaying) {
|
if (this.isPlaying) {
|
||||||
|
taken.startingUntil = this.startingUntil;
|
||||||
taken.isPlaying = this.isPlaying;
|
taken.isPlaying = this.isPlaying;
|
||||||
taken.initialize();
|
taken.initialize();
|
||||||
taken.outputNode.disconnect();
|
taken.outputNode.disconnect();
|
||||||
|
@ -168,6 +178,7 @@ class SoundPlayer extends EventEmitter {
|
||||||
}
|
}
|
||||||
this.volumeEffect = null;
|
this.volumeEffect = null;
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
|
this.startingUntil = 0;
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
|
|
||||||
return taken;
|
return taken;
|
||||||
|
@ -180,6 +191,10 @@ class SoundPlayer extends EventEmitter {
|
||||||
* out.
|
* out.
|
||||||
*/
|
*/
|
||||||
play () {
|
play () {
|
||||||
|
if (this.isStarting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.isPlaying) {
|
if (this.isPlaying) {
|
||||||
// Spawn a Player with the current buffer source, and play for a
|
// Spawn a Player with the current buffer source, and play for a
|
||||||
// short period until its volume is 0 and release it to be
|
// short period until its volume is 0 and release it to be
|
||||||
|
@ -198,6 +213,8 @@ class SoundPlayer extends EventEmitter {
|
||||||
|
|
||||||
this.isPlaying = true;
|
this.isPlaying = true;
|
||||||
|
|
||||||
|
this.startingUntil = this.audioEngine.audioContext.currentTime + this.audioEngine.DECAY_TIME;
|
||||||
|
|
||||||
this.emit('play');
|
this.emit('play');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +230,7 @@ class SoundPlayer extends EventEmitter {
|
||||||
this.outputNode.stop(this.audioEngine.audioContext.currentTime + this.audioEngine.DECAY_TIME);
|
this.outputNode.stop(this.audioEngine.audioContext.currentTime + this.audioEngine.DECAY_TIME);
|
||||||
|
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
|
this.startingUntil = 0;
|
||||||
|
|
||||||
this.emit('stop');
|
this.emit('stop');
|
||||||
}
|
}
|
||||||
|
@ -228,6 +246,7 @@ class SoundPlayer extends EventEmitter {
|
||||||
this.outputNode.stop();
|
this.outputNode.stop();
|
||||||
|
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
|
this.startingUntil = 0;
|
||||||
|
|
||||||
this.emit('stop');
|
this.emit('stop');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue