xxxxxxxxxx
106
// adapted from: https://github.com/ml5js/ml5-next-gen/blob/main/examples/Facemesh-parts/sketch.js#L42 and other examples in ml5-next gen
// https://p5js.org/reference/#/p5.PolySynth
let handpose;
let video;
let hands = [];
let synth;
let finger;
let firstHand;
// Tone.js Effects
const chorus = new Tone.Chorus(4, 2.5, 0.5).toMaster();
chorus.wet.value = 0.5;
const pitchShift = new Tone.PitchShift();
const pingPong = new Tone.PingPongDelay("4n", 0.2);
pingPong.wet.value = 0.1;
const dist = new Tone.BitCrusher(8);
dist.wet.value = 0;
//Create Synths
const mainSynth = new Tone.Synth().chain(pitchShift, dist, pingPong, chorus);
const membraneSynth = new Tone.MembraneSynth().chain(pitchShift, dist, pingPong, chorus);
const amSynth = new Tone.AMSynth().connect(pitchShift, dist, pingPong, chorus);
const duoSynth = new Tone.DuoSynth().connect(pitchShift, dist, pingPong, chorus);
function preload() {
// Load the handpose model.
handpose = ml5.handpose();
}
function setup() {
createCanvas(640, 480);
// Create the webcam video and hide it
video = createCapture(VIDEO);
video.size(width, height);
video.hide();
// start detecting hands from the webcam video
handpose.detectStart(video, gotHands)
duoSynth.toMaster(); // play synth, can update this to be one of the synths above
}
function draw() {
// Styling
let c = color(100, 100, 200); // purple background
c.setAlpha(100); // set lower alpha on background for transparency effect
background(c);
noStroke();
// Flip the camera
translate(width, 1);
scale(-1, 1)
// If there is at least one hand
if (hands.length > 0) {
firstHand = hands[0];
let { keypoints } = firstHand;
// Draw hand keypoints
for (let i = 0; i < keypoints.length - 1; i++) {
circle(keypoints[i].x, keypoints[i].y, 30);
}
// Assign finger to a variable to use for playing synth
let finger = hands[0].index_finger_mcp;
// split screen into quadrants
if (finger.y > height / 2 && finger.x < width / 2) {
mainSynth.triggerAttackRelease("C4", "8n");
} else if (finger.y > height / 2 && finger.x > width / 2) {
mainSynth.triggerAttackRelease("E4", "8n");
} else if (finger.y < height / 2 && finger.x > width / 2) {
mainSynth.triggerAttackRelease("G4", "8n");
} else {
mainSynth.triggerAttackRelease("B4", "8n");
}
}
}
// Callback function for when handpose outputs data
function gotHands(results) {
// save the output to the hands variable
hands = results;
lastNotePlayedTime = millis();
}
function mousePressed() {
// for debugging
console.log(hands);
}