Hi svan, here is the code. Thanks for taking the time to investigate this. I can’t get the combined frequencies of both LFOs at a given moment. Click and hold the gray canvas to play a random frequency. Keep clicking to get one where you can hear both filters simultaneously. (It will be an audible pattern of uneven intervals due to the difference in LFO frequencies.)

```
let amplitude, fft, peakDetect, fundamental, toneMachines, playing, freq, amp;
let useFundamentalForFreq = true
let randFundamentalFreqMin = 40
let randFundamentalFreqMax = 140
function setup()
{
amplitude = new p5.Amplitude();
let cnv = createCanvas(300, 100);
cnv.mousePressed(playOscillator);
//set lowest fundamental
fundamental = random(randFundamentalFreqMin, randFundamentalFreqMax);
toneMachines = []
toneMachines.push(newToneMachine(true))
amplitude.setInput(toneMachines[0].lfo);
fft = new p5.FFT();
peakDetect = new p5.PeakDetect(20,20000,0.02,20);
// chain
toneMachines.forEach(function(toneMachine)
{
toneMachine.lfo.disconnect();
toneMachine.lfo2.disconnect();
toneMachine.osc.disconnect();
toneMachine.osc.connect(toneMachine.filter);
});
}
function draw()
{
background(220)
if(useFundamentalForFreq)
{
freq = fundamental
}
else
{
freq = constrain(map(mouseX, 0, width, 40, 140), 40, 140);
}
amp = .2
if (playing)
{
smoothOscStart()
// connect the lfo
toneMachines.forEach(function(toneMachine)
{
toneMachine.filter.freq(toneMachine.lfo);
toneMachine.filter.freq(toneMachine.lfo2);
});
drawSpectrum()
drawWaveform()
}
drawInfoText()
}
function playOscillator()
{
if(useFundamentalForFreq)
{
fundamental = random(randFundamentalFreqMin, randFundamentalFreqMax);
}
toneMachines.forEach(function(toneMachine)
{
if(!toneMachine.muted)
{
toneMachine.osc.start();
toneMachine.lfo.start();
toneMachine.lfo2.start();
}
});
playing = true;
}
function mouseReleased()
{
toneMachines.forEach(function(toneMachine)
{
toneMachine.osc.amp(0, 0.2);
});
playing = false;
}
function smoothOscStart()
{
var freqMult = 1
toneMachines.forEach(function(toneMachine)
{
let toneMachineID = toneMachine.id
// needs to reset the res to default first
let resDefault = toneMachine.resDefault
let lfoCurrentAmp = toneMachine.lfo.getAmp()
toneMachine.osc.freq(freq, 0.1);
toneMachine.osc.amp(amp, 0.1);
toneMachine.filter.res(resDefault, 0.1);
});
}
function drawSpectrum()
{
//note: spectrum stretched out, because highest freqs not likely to be used.
let spectrum = fft.analyze();
noStroke();
fill(255, 0, 255);
for (let i = 0; i<spectrum.length; i++)
{
let x = map(i, 0, spectrum.length, 0, width*5);
let h = -height + map(spectrum[i], 0, 255, height, 0);
rect(x, height, width / spectrum.length, h )
}
}
function drawWaveform()
{
let waveform = fft.waveform();
noFill();
beginShape();
stroke(255, 100, 0);
for (let i = 0; i < waveform.length; i++)
{
let x = map(i, 0, waveform.length, 0, width);
let y = map( waveform[i], -1, 1, 0, height);
vertex(x,y);
}
endShape();
}
function drawInfoText()
{
fill(0, 0, 0);
noStroke();
text('tap to play', 20, 10);
text('freq: ' + freq, 20, 20);
text('amp: ' + amp, 20, 40);
text('lfo1 freq: ' + toneMachines[0].lfo.getFreq(), 20, 60);
text('lfo1 amp: ' + toneMachines[0].lfo.getAmp(), 20, 80);
text('lfo2 amp: ' + toneMachines[0].lfo2.getAmp(), 20, 100);
}
function newToneMachine(shouldPlay)
{
let osc = new p5.Oscillator('sine')
let lfo = new p5.Oscillator('sine');
let lfo2 = new p5.Oscillator('sine');
let resDefault = 14
lfo.freq(2.9);
lfo2.freq(3.9);
lfo.amp(1200);
lfo2.amp(1300);
let filter = new p5.Filter();
filter.freq(1200);
filter.res(resDefault);
let obj =
{
osc:osc,
lfo:lfo,
lfo2:lfo2,
filter:filter,
resDefault:resDefault,
id:toneMachines.length,
muted:!shouldPlay,
}
return obj
}
```