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
}