70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import type { Effect } from './Effect.interface'
|
|
|
|
export class ReverbEffect implements Effect {
|
|
readonly id = 'reverb'
|
|
|
|
private audioContext: AudioContext
|
|
private inputNode: GainNode
|
|
private outputNode: GainNode
|
|
private convolverNode: ConvolverNode
|
|
private wetNode: GainNode
|
|
private dryNode: GainNode
|
|
|
|
constructor(audioContext: AudioContext) {
|
|
this.audioContext = audioContext
|
|
this.inputNode = audioContext.createGain()
|
|
this.outputNode = audioContext.createGain()
|
|
this.convolverNode = audioContext.createConvolver()
|
|
this.wetNode = audioContext.createGain()
|
|
this.dryNode = audioContext.createGain()
|
|
|
|
this.wetNode.gain.value = 0
|
|
this.dryNode.gain.value = 1
|
|
|
|
this.inputNode.connect(this.dryNode)
|
|
this.inputNode.connect(this.convolverNode)
|
|
this.convolverNode.connect(this.wetNode)
|
|
this.dryNode.connect(this.outputNode)
|
|
this.wetNode.connect(this.outputNode)
|
|
|
|
this.generateImpulseResponse()
|
|
}
|
|
|
|
private generateImpulseResponse(): void {
|
|
const length = this.audioContext.sampleRate * 2
|
|
const impulse = this.audioContext.createBuffer(2, length, this.audioContext.sampleRate)
|
|
const left = impulse.getChannelData(0)
|
|
const right = impulse.getChannelData(1)
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
left[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / length, 2)
|
|
right[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / length, 2)
|
|
}
|
|
|
|
this.convolverNode.buffer = impulse
|
|
}
|
|
|
|
getInputNode(): AudioNode {
|
|
return this.inputNode
|
|
}
|
|
|
|
getOutputNode(): AudioNode {
|
|
return this.outputNode
|
|
}
|
|
|
|
updateParams(values: Record<string, number>): void {
|
|
if (values.reverbWetDry !== undefined) {
|
|
const wet = values.reverbWetDry / 100
|
|
this.wetNode.gain.value = wet
|
|
this.dryNode.gain.value = 1 - wet
|
|
}
|
|
}
|
|
|
|
dispose(): void {
|
|
this.inputNode.disconnect()
|
|
this.outputNode.disconnect()
|
|
this.convolverNode.disconnect()
|
|
this.wetNode.disconnect()
|
|
this.dryNode.disconnect()
|
|
}
|
|
} |