p5(sketch => {
let ready = false;
const type = "square";
let filter, effect;
const filterMin = 100;
const filterMax = 5000;
let fxU = 0.5;
let fxV = 0.5;
const notes = ["C5", "A3", "D4", "G4", "A4", "F4"];
let synth
let PI = sketch.PI
const dim = Math.min(width, height)
sketch.setup = async function() {
sketch.createCanvas(width, height);
sketch.background("#001b42");
Tone.Master.volume.value = volume;
// Setup a reverb with ToneJS
const reverb = new Tone.Reverb({
decay: 5,
wet: 0.5,
preDelay: 0.2,
});
// Load the reverb
await reverb.generate();
effect = new Tone.FeedbackDelay(0.4, 0.85); // Create an effect node that creates a feedback delay
// Create a new filter for the X slider
filter = new Tone.Filter();
filter.type = "lowpass";
// Setup a synth with ToneJS
synth = new Tone.Synth({
oscillator: { // We prefix 'fat' so we can spread the oscillator over multiple frequencies
type: `fat${type}`,
count: 3,
spread: 30,
},
envelope: {
attack: 0.001,
decay: 0.1,
sustain: 0.5,
release: 0.1,
attackCurve: 'exponential' ,
// decayCurve: 'exponential' ,
// releaseCurve: 'exponential',
},
});
// Now lets wire up our stack like so: synth->effect->reverb->filter->master
synth.connect(effect);
effect.connect(reverb);
reverb.connect(filter);
filter.connect(Tone.Master);
// Now we're ready for drawing!
ready = true;
}
//---------------------------------------------------------------------
// Render loop that draws shapes with p5
sketch.draw = function() {
// Make sure async setup() is done before we draw
if (!ready) return;
filter.frequency.value = sketch.lerp(filterMin, filterMax, fxU);
effect.wet.value = fxV;
// Black background
// sketch.background(0, 0, 0, 20);
sketch.background("#001b4214");
// draw the two FX knobs
if (sketch.mouseIsPressed) {
sketch.noFill();
sketch.strokeWeight(dim * 0.0175);
sketch.stroke(255);
drawEffectKnob(dim * 0.4, fxU);
drawEffectKnob(dim * 0.6, fxV);
}
// Draw a 'play' button
sketch.noStroke();
sketch.fill(255);
polygon(width / 2, height / 2, dim * 0.1, 3);
}
//------------------------------------------------------------------------------------------
// Draws an arc with the given amount of 'strength'
function drawEffectKnob(radius, t) {
if (t <= 0) return;
sketch.arc(width / 2, height / 2, radius, radius, 0, PI * 2 * t);
}
// Update FX values based on mouse position
function updateEffects() {
fxU = sketch.max(0, sketch.min(1, sketch.mouseX / width));
fxV = sketch.max(0, sketch.min(1, sketch.mouseY / height));
}
// ----------------------------------------------------------
// Update the FX values
sketch.mouseDragged = function () {
updateEffects();
}
// Trigger synth OFF
sketch.mouseReleased = function () {
if (synth) synth.triggerRelease();
}
// Update the FX and trigger synth ON
sketch.mousePressed = function () {
updateEffects();
if (synth) synth.triggerAttack(sketch.random(notes));
}
// -----------------------------------------------------------------------------------
// Draw a basic polygon, handles triangles, squares, pentagons, etc
function polygon(x, y, radius, sides = 3, angle = 0) {
sketch.beginShape();
for (let i = 0; i < sides; i++) {
const a = angle + sketch.TWO_PI * (i / sides);
let sx = x + Math.cos(a) * radius;
let sy = y + Math.sin(a) * radius;
sketch.vertex(sx, sy);
}
sketch.endShape(sketch.CLOSE);
}
})