import React, { useEffect, useContext, useRef } from 'react'; import { TrackContext } from './Track'; import Tone from '../lib/tone'; export type EffectType = | 'autoFilter' | 'autoPanner' | 'autoWah' | 'bitCrusher' | 'distortion' | 'feedbackDelay' | 'freeverb' | 'panVol' | 'tremolo' | 'eq3'; export interface EffectProps { type?: EffectType; id?: string; delayTime?: string; feedback?: number; wet?: number; low?: number; mid?: number; high?: number; lowFrequency?: number; highFrequency?: number; } export interface EffectConsumerProps extends EffectProps { onAddToEffectsChain?: Function; onRemoveFromEffectsChain?: Function; } const EffectConsumer: React.FC = ({ type, id, delayTime = '8n', feedback = 0.5, wet = 1, low, mid, high, lowFrequency, highFrequency, onAddToEffectsChain, onRemoveFromEffectsChain, }) => { const effect = useRef<{ id: string | number; feedback?: { value: number; }; delay?: { value: number; }; delayTime?: { value: string; }; wet?: { value: number; }; low?: { value: number; }; mid?: { value: number; }; high?: { value: number; }; lowFrequency?: { value: number; }; highFrequency?: { value: number; }; }>(); useEffect(() => { // console.log(' mount'); // console.log(`id: ${id}`); if (type === 'autoFilter') { effect.current = new Tone.AutoFilter(); } else if (type === 'autoPanner') { effect.current = new Tone.AutoPanner(); } else if (type === 'autoWah') { effect.current = new Tone.AutoWah(); } else if (type === 'bitCrusher') { effect.current = new Tone.BitCrusher(); // Removed for now because delayTime has to be in ms // } else if (type === 'chorus') { // effect.current = new Tone.Chorus(); } else if (type === 'distortion') { effect.current = new Tone.Distortion(0.5); } else if (type === 'feedbackDelay') { effect.current = new Tone.FeedbackDelay(delayTime, feedback); } else if (type === 'freeverb') { effect.current = new Tone.Freeverb(); } else if (type === 'panVol') { effect.current = new Tone.PanVol(); // Needs generate() // } else if (type === 'reverb') { // effect.current = new Tone.Reverb(); } else if (type === 'tremolo') { effect.current = new Tone.Tremolo(); } else if (type === 'eq3') { effect.current = new Tone.EQ3(low, mid, high); } if (effect.current) { effect.current.id = id; // Update effects chain // TODO: Work out which index to insert current this.effect onAddToEffectsChain(effect.current); } return () => { // console.log(' unmount'); onRemoveFromEffectsChain(effect.current); }; /* eslint-disable-next-line */ }, [type]); useEffect(() => { if (effect.current && effect.current.feedback) { effect.current.feedback.value = feedback; } }, [feedback]); useEffect(() => { if (effect.current && effect.current.delayTime) { effect.current.delayTime.value = delayTime; } }, [delayTime]); useEffect(() => { if (effect.current && effect.current.wet) { effect.current.wet.value = wet; } }, [wet]); useEffect(() => { if (typeof low !== 'undefined' && effect.current && effect.current.low) { effect.current.low.value = low; } }, [low]); useEffect(() => { if (typeof mid !== 'undefined' && effect.current && effect.current.mid) { effect.current.mid.value = mid; } }, [mid]); useEffect(() => { if (typeof high !== 'undefined' && effect.current && effect.current.high) { effect.current.high.value = high; } }, [high]); useEffect(() => { if ( typeof lowFrequency !== 'undefined' && effect.current && effect.current.lowFrequency ) { effect.current.lowFrequency.value = lowFrequency; } }, [lowFrequency]); useEffect(() => { if ( typeof highFrequency !== 'undefined' && effect.current && effect.current.highFrequency ) { effect.current.highFrequency.value = highFrequency; } }, [highFrequency]); return null; }; const Effect: React.FC = (props) => { const { onAddToEffectsChain, onRemoveFromEffectsChain } = useContext( TrackContext, ); return ( ); }; export default Effect;