Adding new FM synthesis mode
This commit is contained in:
90
src/domain/audio/effects/FMSourceEffect.ts
Normal file
90
src/domain/audio/effects/FMSourceEffect.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import type { Effect } from './Effect.interface'
|
||||
import type { FMAlgorithm } from '../../../config/fmAlgorithms'
|
||||
|
||||
export class FMSourceEffect implements Effect {
|
||||
readonly id = 'fm-source'
|
||||
|
||||
private inputNode: GainNode
|
||||
private outputNode: GainNode
|
||||
private processorNode: AudioWorkletNode | null = null
|
||||
|
||||
constructor(audioContext: AudioContext) {
|
||||
this.inputNode = audioContext.createGain()
|
||||
this.outputNode = audioContext.createGain()
|
||||
}
|
||||
|
||||
async initialize(audioContext: AudioContext): Promise<void> {
|
||||
this.processorNode = new AudioWorkletNode(audioContext, 'fm-processor')
|
||||
this.processorNode.connect(this.outputNode)
|
||||
}
|
||||
|
||||
getInputNode(): AudioNode {
|
||||
return this.inputNode
|
||||
}
|
||||
|
||||
getOutputNode(): AudioNode {
|
||||
return this.outputNode
|
||||
}
|
||||
|
||||
setBypass(): void {
|
||||
// Source node doesn't support bypass
|
||||
}
|
||||
|
||||
updateParams(): void {
|
||||
// Parameters handled via specific methods
|
||||
}
|
||||
|
||||
setAlgorithm(algorithm: FMAlgorithm, lfoRates?: number[]): void {
|
||||
if (!this.processorNode) return
|
||||
this.processorNode.port.postMessage({
|
||||
type: 'algorithm',
|
||||
value: {
|
||||
id: algorithm.id,
|
||||
ratios: algorithm.frequencyRatios,
|
||||
lfoRates: lfoRates || [0.37, 0.53, 0.71, 0.43]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setOperatorLevels(a: number, b: number, c: number, d: number): void {
|
||||
if (!this.processorNode) return
|
||||
this.processorNode.port.postMessage({
|
||||
type: 'operatorLevels',
|
||||
value: { a, b, c, d }
|
||||
})
|
||||
}
|
||||
|
||||
setBaseFrequency(freq: number): void {
|
||||
if (!this.processorNode) return
|
||||
this.processorNode.port.postMessage({ type: 'baseFreq', value: freq })
|
||||
}
|
||||
|
||||
setFeedback(amount: number): void {
|
||||
if (!this.processorNode) return
|
||||
this.processorNode.port.postMessage({ type: 'feedback', value: amount })
|
||||
}
|
||||
|
||||
setLoopLength(sampleRate: number, duration: number): void {
|
||||
if (!this.processorNode) return
|
||||
const loopLength = sampleRate * duration
|
||||
this.processorNode.port.postMessage({ type: 'loopLength', value: loopLength })
|
||||
}
|
||||
|
||||
setPlaybackRate(rate: number): void {
|
||||
if (!this.processorNode) return
|
||||
this.processorNode.port.postMessage({ type: 'playbackRate', value: rate })
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
if (!this.processorNode) return
|
||||
this.processorNode.port.postMessage({ type: 'reset' })
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
if (this.processorNode) {
|
||||
this.processorNode.disconnect()
|
||||
}
|
||||
this.inputNode.disconnect()
|
||||
this.outputNode.disconnect()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user