mirror of
https://github.com/scratchfoundation/scratch-audio.git
synced 2024-12-22 14:02:29 -05:00
make EffectChain standalone
- EffectChain knows of audioEngine so it can create Effects - EffectChain connects to the target specified by .connect(target) - EffectChain can connect to other Effects or EffectChains - EffectChain can clone itself and connect to the original's target - Add EffectChain.update to mirror Effects API - Use deepest setting first in setEffectsFromTarget
This commit is contained in:
parent
f5c219ceb3
commit
d40564d61a
1 changed files with 33 additions and 19 deletions
|
@ -1,32 +1,35 @@
|
||||||
class EffectChain {
|
class EffectChain {
|
||||||
constructor (audioEngine) {
|
constructor (audioEngine, effects) {
|
||||||
this.audioEngine = audioEngine;
|
this.audioEngine = audioEngine;
|
||||||
|
|
||||||
this.outputNode = this.audioEngine.audioContext.createGain();
|
this.inputNode = this.audioEngine.audioContext.createGain();
|
||||||
|
|
||||||
|
this.effects = effects;
|
||||||
|
|
||||||
this.lastEffect = null;
|
this.lastEffect = null;
|
||||||
|
|
||||||
this._effects = audioEngine.effects.map(Effect => {
|
this._effects = effects.map(Effect => {
|
||||||
const effect = new Effect(audioEngine, this, this.lastEffect);
|
const effect = new Effect(audioEngine, this, this.lastEffect);
|
||||||
this[effect.name] = effect;
|
this[effect.name] = effect;
|
||||||
this.lastEffect = effect;
|
this.lastEffect = effect;
|
||||||
return effect;
|
return effect;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Walk backwards through effects connecting the last output to audio engine,
|
|
||||||
// then each effect's output to the input of the next effect.
|
|
||||||
this._effects.reduceRight((nextNode, effect) => {
|
|
||||||
effect.connect(nextNode);
|
|
||||||
return effect;
|
|
||||||
}, this.audioEngine);
|
|
||||||
|
|
||||||
this._soundPlayers = new Set();
|
this._soundPlayers = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clone () {
|
||||||
|
const chain = new EffectChain(this.audioEngine, this.effects);
|
||||||
|
if (this.target === target) {
|
||||||
|
chain.connect(target);
|
||||||
|
}
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
|
||||||
addSoundPlayer (soundPlayer) {
|
addSoundPlayer (soundPlayer) {
|
||||||
if (!this._soundPlayers.has(soundPlayer)) {
|
if (!this._soundPlayers.has(soundPlayer)) {
|
||||||
this._soundPlayers.add(soundPlayer);
|
this._soundPlayers.add(soundPlayer);
|
||||||
this._effects.forEach(effect => effect.update());
|
this.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ class EffectChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
getInputNode () {
|
getInputNode () {
|
||||||
return this.outputNode;
|
return this.inputNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,8 +46,17 @@ class EffectChain {
|
||||||
* @param {object} target - target whose node to should be connected
|
* @param {object} target - target whose node to should be connected
|
||||||
*/
|
*/
|
||||||
connect (target) {
|
connect (target) {
|
||||||
this.outputNode.disconnect();
|
const {lastEffect} = this;
|
||||||
this.outputNode.connect(target.getInputNode());
|
if (target === lastEffect) {
|
||||||
|
this.inputNode.disconnect();
|
||||||
|
this.inputNode.connect(lastEffect.getInputNode());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.target = target;
|
||||||
|
|
||||||
|
this._effects[0].connect(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,12 +66,10 @@ class EffectChain {
|
||||||
|
|
||||||
setEffectsFromTarget (target) {
|
setEffectsFromTarget (target) {
|
||||||
this._effects.forEach(effect => {
|
this._effects.forEach(effect => {
|
||||||
if (effect.name in target) {
|
if ('soundEffects' in target && effect.name in target.soundEffects) {
|
||||||
effect.set(target[effect.name]);
|
|
||||||
} else if ('soundEffects' in target && effect.name in target.soundEffects) {
|
|
||||||
effect.set(target.soundEffects[effect.name]);
|
effect.set(target.soundEffects[effect.name]);
|
||||||
} else {
|
} else if (effect.name in target) {
|
||||||
effect.set(effect.DEFAULT_VALUE);
|
effect.set(target[effect.name]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -70,6 +80,10 @@ class EffectChain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update () {
|
||||||
|
this._effects.forEach(effect => effect.update());
|
||||||
|
}
|
||||||
|
|
||||||
clear () {
|
clear () {
|
||||||
this._effects.forEach(effect => effect.clear());
|
this._effects.forEach(effect => effect.clear());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue