slightly better
This commit is contained in:
103
public/worklets/svf-processor.js
Normal file
103
public/worklets/svf-processor.js
Normal file
@ -0,0 +1,103 @@
|
||||
class SVFProcessor extends AudioWorkletProcessor {
|
||||
static get parameterDescriptors() {
|
||||
return [
|
||||
{
|
||||
name: 'frequency',
|
||||
defaultValue: 1000,
|
||||
minValue: 20,
|
||||
maxValue: 20000,
|
||||
automationRate: 'k-rate'
|
||||
},
|
||||
{
|
||||
name: 'resonance',
|
||||
defaultValue: 0.707,
|
||||
minValue: 0.05,
|
||||
maxValue: 10,
|
||||
automationRate: 'k-rate'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
this.mode = 'lowpass'
|
||||
this.ic1eq = 0
|
||||
this.ic2eq = 0
|
||||
|
||||
this.port.onmessage = (event) => {
|
||||
const { type, value } = event.data
|
||||
if (type === 'mode') {
|
||||
this.mode = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process(inputs, outputs, parameters) {
|
||||
const input = inputs[0]
|
||||
const output = outputs[0]
|
||||
|
||||
if (input.length === 0 || output.length === 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
const inputChannel = input[0]
|
||||
const outputChannel = output[0]
|
||||
const frequency = parameters.frequency
|
||||
const resonance = parameters.resonance
|
||||
|
||||
const sampleRate = globalThis.sampleRate || 44100
|
||||
const isFreqArray = frequency.length > 1
|
||||
const isResArray = resonance.length > 1
|
||||
|
||||
for (let i = 0; i < inputChannel.length; i++) {
|
||||
const freq = isFreqArray ? frequency[i] : frequency[0]
|
||||
const res = isResArray ? resonance[i] : resonance[0]
|
||||
|
||||
const g = Math.tan(Math.PI * Math.min(freq, sampleRate * 0.49) / sampleRate)
|
||||
const k = 1 / Math.max(0.05, res)
|
||||
|
||||
const inputSample = inputChannel[i]
|
||||
|
||||
const a1 = 1 / (1 + g * (g + k))
|
||||
const a2 = g * a1
|
||||
const a3 = g * a2
|
||||
|
||||
const v3 = inputSample - this.ic2eq
|
||||
const v1 = a1 * this.ic1eq + a2 * v3
|
||||
const v2 = this.ic2eq + a2 * this.ic1eq + a3 * v3
|
||||
|
||||
this.ic1eq = 2 * v1 - this.ic1eq
|
||||
this.ic2eq = 2 * v2 - this.ic2eq
|
||||
|
||||
const lp = v2
|
||||
const bp = v1
|
||||
const hp = inputSample - k * v1 - v2
|
||||
const notch = inputSample - k * v1
|
||||
|
||||
let outSample
|
||||
switch (this.mode) {
|
||||
case 'lowpass':
|
||||
outSample = lp
|
||||
break
|
||||
case 'highpass':
|
||||
outSample = hp
|
||||
break
|
||||
case 'bandpass':
|
||||
outSample = bp
|
||||
break
|
||||
case 'notch':
|
||||
outSample = notch
|
||||
break
|
||||
default:
|
||||
outSample = lp
|
||||
}
|
||||
|
||||
outputChannel[i] = outSample
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
registerProcessor('svf-processor', SVFProcessor)
|
||||
Reference in New Issue
Block a user