From 7bbe5f0589473d0f333284731fc6b855b44b6427 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Tue, 9 Jul 2019 10:42:53 -0400 Subject: [PATCH] Add fade in, fade out and mute effects --- src/components/sound-editor/icon--fade-in.svg | 34 ++++++++++++++++ .../sound-editor/icon--fade-out.svg | 34 ++++++++++++++++ src/components/sound-editor/icon--mute.svg | 18 +++++++++ src/components/sound-editor/sound-editor.jsx | 39 +++++++++++++++++++ src/containers/sound-editor.jsx | 3 ++ src/lib/audio/audio-effects.js | 19 ++++++++- src/lib/audio/effects/fade-effect.js | 27 +++++++++++++ src/lib/audio/effects/mute-effect.js | 22 +++++++++++ 8 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 src/components/sound-editor/icon--fade-in.svg create mode 100644 src/components/sound-editor/icon--fade-out.svg create mode 100644 src/components/sound-editor/icon--mute.svg create mode 100644 src/lib/audio/effects/fade-effect.js create mode 100644 src/lib/audio/effects/mute-effect.js diff --git a/src/components/sound-editor/icon--fade-in.svg b/src/components/sound-editor/icon--fade-in.svg new file mode 100644 index 000000000..6bd9e6974 --- /dev/null +++ b/src/components/sound-editor/icon--fade-in.svg @@ -0,0 +1,34 @@ + + + + Sound/Effects/Fade-in + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/sound-editor/icon--fade-out.svg b/src/components/sound-editor/icon--fade-out.svg new file mode 100644 index 000000000..d6704bc0e --- /dev/null +++ b/src/components/sound-editor/icon--fade-out.svg @@ -0,0 +1,34 @@ + + + + Sound/Effects/Fade-out + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/sound-editor/icon--mute.svg b/src/components/sound-editor/icon--mute.svg new file mode 100644 index 000000000..1fcbbd559 --- /dev/null +++ b/src/components/sound-editor/icon--mute.svg @@ -0,0 +1,18 @@ + + + + Sound/Effects/Mute + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/sound-editor/sound-editor.jsx b/src/components/sound-editor/sound-editor.jsx index 57fc2149e..cbd731f14 100644 --- a/src/components/sound-editor/sound-editor.jsx +++ b/src/components/sound-editor/sound-editor.jsx @@ -26,6 +26,9 @@ import louderIcon from './icon--louder.svg'; import softerIcon from './icon--softer.svg'; import robotIcon from './icon--robot.svg'; import reverseIcon from './icon--reverse.svg'; +import fadeOutIcon from './icon--fade-out.svg'; +import fadeInIcon from './icon--fade-in.svg'; +import muteIcon from './icon--mute.svg'; const BufferedInput = BufferedInputHOC(Input); @@ -99,6 +102,21 @@ const messages = defineMessages({ id: 'gui.soundEditor.reverse', description: 'Title of the button to apply the reverse effect', defaultMessage: 'Reverse' + }, + fadeOut: { + id: 'gui.soundEditor.fadeOut', + description: 'Title of the button to apply the fade out effect', + defaultMessage: 'Fade out' + }, + fadeIn: { + id: 'gui.soundEditor.fadeIn', + description: 'Title of the button to apply the fade in effect', + defaultMessage: 'Fade in' + }, + mute: { + id: 'gui.soundEditor.mute', + description: 'Title of the button to apply the mute effect', + defaultMessage: 'Mute' } }); @@ -237,12 +255,30 @@ const SoundEditor = props => ( title={} onClick={props.onSofter} /> + } + onClick={props.onMute} + /> } onClick={props.onReverse} /> + } + onClick={props.onFadeOut} + /> + } + onClick={props.onFadeIn} + /> ); @@ -257,8 +293,11 @@ SoundEditor.propTypes = { onChangeName: PropTypes.func.isRequired, onContainerClick: PropTypes.func.isRequired, onEcho: PropTypes.func.isRequired, + onFadeIn: PropTypes.func.isRequired, + onFadeOut: PropTypes.func.isRequired, onFaster: PropTypes.func.isRequired, onLouder: PropTypes.func.isRequired, + onMute: PropTypes.func.isRequired, onPlay: PropTypes.func.isRequired, onRedo: PropTypes.func.isRequired, onReverse: PropTypes.func.isRequired, diff --git a/src/containers/sound-editor.jsx b/src/containers/sound-editor.jsx index 67ba3a1ae..24c0758d3 100644 --- a/src/containers/sound-editor.jsx +++ b/src/containers/sound-editor.jsx @@ -227,8 +227,11 @@ class SoundEditor extends React.Component { onContainerClick={this.handleContainerClick} onDelete={this.handleDelete} onEcho={this.effectFactory(effectTypes.ECHO)} + onFadeIn={this.effectFactory(effectTypes.FADEIN)} + onFadeOut={this.effectFactory(effectTypes.FADEOUT)} onFaster={this.effectFactory(effectTypes.FASTER)} onLouder={this.effectFactory(effectTypes.LOUDER)} + onMute={this.effectFactory(effectTypes.MUTE)} onPlay={this.handlePlay} onRedo={this.handleRedo} onReverse={this.effectFactory(effectTypes.REVERSE)} diff --git a/src/lib/audio/audio-effects.js b/src/lib/audio/audio-effects.js index 5dae9cf13..b6b78f5b0 100644 --- a/src/lib/audio/audio-effects.js +++ b/src/lib/audio/audio-effects.js @@ -1,6 +1,8 @@ import EchoEffect from './effects/echo-effect.js'; import RobotEffect from './effects/robot-effect.js'; import VolumeEffect from './effects/volume-effect.js'; +import FadeEffect from './effects/fade-effect.js'; +import MuteEffect from './effects/mute-effect.js'; const effectTypes = { ROBOT: 'robot', @@ -9,7 +11,10 @@ const effectTypes = { SOFTER: 'lower', FASTER: 'faster', SLOWER: 'slower', - ECHO: 'echo' + ECHO: 'echo', + FADEIN: 'fade in', + FADEOUT: 'fade out', + MUTE: 'mute' }; class AudioEffects { @@ -117,6 +122,18 @@ class AudioEffects { ({input, output} = new RobotEffect(this.audioContext, this.adjustedTrimStartSeconds, this.adjustedTrimEndSeconds)); break; + case effectTypes.FADEIN: + ({input, output} = new FadeEffect(this.audioContext, true, + this.adjustedTrimStartSeconds, this.adjustedTrimEndSeconds)); + break; + case effectTypes.FADEOUT: + ({input, output} = new FadeEffect(this.audioContext, false, + this.adjustedTrimStartSeconds, this.adjustedTrimEndSeconds)); + break; + case effectTypes.MUTE: + ({input, output} = new MuteEffect(this.audioContext, + this.adjustedTrimStartSeconds, this.adjustedTrimEndSeconds)); + break; } if (input && output) { diff --git a/src/lib/audio/effects/fade-effect.js b/src/lib/audio/effects/fade-effect.js new file mode 100644 index 000000000..5a13c5c16 --- /dev/null +++ b/src/lib/audio/effects/fade-effect.js @@ -0,0 +1,27 @@ +class FadeEffect { + constructor (audioContext, fadeIn, startSeconds, endSeconds) { + this.audioContext = audioContext; + + this.input = this.audioContext.createGain(); + this.output = this.audioContext.createGain(); + + this.gain = this.audioContext.createGain(); + + this.gain.gain.setValueAtTime(1, 0); + + if (fadeIn) { + this.gain.gain.setValueAtTime(0, startSeconds); + this.gain.gain.linearRampToValueAtTime(1, endSeconds); + } else { + this.gain.gain.setValueAtTime(1, startSeconds); + this.gain.gain.linearRampToValueAtTime(0, endSeconds); + } + + this.gain.gain.setValueAtTime(1, endSeconds); + + this.input.connect(this.gain); + this.gain.connect(this.output); + } +} + +export default FadeEffect; diff --git a/src/lib/audio/effects/mute-effect.js b/src/lib/audio/effects/mute-effect.js new file mode 100644 index 000000000..c2a2e68d5 --- /dev/null +++ b/src/lib/audio/effects/mute-effect.js @@ -0,0 +1,22 @@ +class MuteEffect { + constructor (audioContext, startSeconds, endSeconds) { + this.audioContext = audioContext; + + this.input = this.audioContext.createGain(); + this.output = this.audioContext.createGain(); + + this.gain = this.audioContext.createGain(); + + // Smoothly ramp the gain down before the start time, and up after the end time. + this.rampLength = 0.001; + this.gain.gain.setValueAtTime(1.0, Math.max(0, startSeconds - this.rampLength)); + this.gain.gain.linearRampToValueAtTime(0, startSeconds); + this.gain.gain.setValueAtTime(0, endSeconds); + this.gain.gain.linearRampToValueAtTime(1.0, endSeconds + this.rampLength); + + this.input.connect(this.gain); + this.gain.connect(this.output); + } +} + +export default MuteEffect;