dot-audio
Version:
A simple web audio library for making synthesizers
103 lines (88 loc) • 2.93 kB
JavaScript
import DotAudioNode from 'nodes/core/DotAudioNode'
import Gain from 'nodes/core/Gain'
import WaveShaper from 'nodes/core/WaveShaper'
const defaultProps = {
amount: 0,
distortion: 0,
}
/**
* A Distortion effect used to clip/distort the incoming signal.
*
* @example
* const synth = new Dot.Synth(AC)
* const distortion = new Dot.Distortion(AC, { distortion: 10, amount: 0.1 })
*
* Dot.chain(synth, distortion, AC.destination)
*
* @extends DotAudioNode
* @param {AudioContext} AC - Audio context
* @param {Object} opts - Initialization options
* @param {Number} opts.amount - The dry/wet amount for the node (default: 0)
* @param {Number} opts.distortion - The distortion amount to generate the waveshaping curve (default: 0)
* @returns {Distortion} Distortion Node
*/
class Distortion extends DotAudioNode {
constructor(AC, opts = {}) {
super(AC)
this.name = 'Distortion'
this.dryGain = new Gain(this.AC)
this.waveShaper = new WaveShaper(this.AC)
this.wetGain = new Gain(this.AC)
this.distortion = 0
this.params = {}
this.inputs = [this.dryGain, this.waveShaper]
this.outputs = [this.dryGain, this.wetGain]
// Initialize
const initProps = { ...defaultProps, ...opts }
this.setAmount(initProps.amount)
this.setDistortion(initProps.distortion)
// Connections
this.waveShaper.connect(this.wetGain)
return this
}
// - Getters -
/**
* Get the dry/wet amount level of the node.
* @returns {Number} Dry/wet amount
*/
getAmount = () => this.wetGain.getGain()
/**
* Get the distortion value of the node.
* @returns {Number} Distortion value
*/
getDistortion = () => this.distortion
// - Setters -
/**
* Set the dry/wet amount of the node.
* Uses linearFadeUpdate method to evenly fade and to allow for changes over time.
* @param {Number} val - Dry/set amount
* @param {Number} [time] - update time in seconds (optional)
*/
setAmount = (val, time) => {
this._linearFadeUpdate(
this.dryGain.getParam('gain'),
this.wetGain.getParam('gain'),
val,
time,
)
}
/**
* Set the distortion value of the node.
* @param {Number} val - Distortion value
*/
setDistortion = (val) => {
this.waveShaper.setCurve(this._createDistCurve(val))
this.distortion = val
}
// --- Private Methods ---
// Generate distortion curve
_createDistCurve = (gain = 0) => {
const sampleNum = this.AC.sampleRate
const curve = new Float32Array(sampleNum)
return curve.map((_, i) => {
const x = i * 2 / sampleNum - 1
return (3 + gain) * Math.atan(Math.sinh(x * 0.25) * 5) / (Math.PI + gain * Math.abs(x))
})
}
}
export default Distortion