xxxxxxxxxx
142
//Visualize & audible landing angles by connecting to two ORPHE COREs on the left and right
let landCircles = []; // array of cirlcle objects
let foot_print_left;
let foot_print_right;
let logo;
//for sound
let osc, envelope;
let scaleArray = [60, 62, 64, 65, 67, 69, 71, 72];
//ORPHE CORE BLE
var bles = [new Orphe(0), new Orphe(1)]; //ORPHE接続用のBLE変数
var foot_angles = [0, 0];
function setup() {
// ORPHE CORE Init
for (ble of bles) {
ble.setup();
//Register an event listener when a FootAngle is received.
ble.gotFootAngle = function (foot_angle) {
foot_angles[this.id] = foot_angle.value;
landCircles.push(new LandingPoint(this.id, foot_angle.value)); //Generates a circle based on the angle of landing
};
ble.onConnectGATT = function (uuid) {
osc.start();
envelope.play(osc, 0, 0.5);
};
}
createCanvas(400, 800);
textAlign(CENTER, CENTER);
//background image
foot_print_left = loadImage("foot_print_left.png");
foot_print_right = loadImage("foot_print_right.png");
logo = loadImage("orphe_logo_horizontal_white.png");
//sound
osc = new p5.TriOsc();
// Instantiate the envelope
envelope = new p5.Env();
// set attackTime, decayTime, sustainRatio, releaseTime
envelope.setADSR(0.001, 0.1, 0.1, 0.1);
// set attackLevel, releaseLevel
envelope.setRange(1, 0);
}
function draw() {
background(55);
fill(255);
//draw background image
image(
foot_print_left,
width * 0.0,
height * 0.0,
width * 0.5,
(width * 0.5 * 320) / 120
);
image(
foot_print_right,
width * 0.5,
height * 0.0,
width * 0.5,
(width * 0.5 * 320) / 120
);
image(
logo,
width * 0.1,
height * 0.95,
width * 0.2,
(width * 0.2 * 384) / 1308
);
for (let i = 0; i < landCircles.length; i++) {
landCircles[i].update();
landCircles[i].display();
fill(255);
text(
`${landCircles[i].footAngle.toFixed(3)}`,
width * 0.15 + width * 0.5 * landCircles[i].left_or_right,
height * 0.7 + height * 0.03 * i
);
}
if (landCircles.length >= 10) {
//delete the first one when the number of arrays increases beyond 10
landCircles.shift();
}
text(`foot_angle:` + foot_angles[0].toFixed(3), 100, 20);
text(`foot_angle:` + foot_angles[1].toFixed(3), 300, 20);
}
// LandingPoint class
class LandingPoint {
constructor(_left_or_right, _footAngle) {
this.left_or_right = _left_or_right;
this.footAngle = _footAngle;
this.diameter = 100;
this.transparency = 100;
this.x = _left_or_right == 0 ? width * 0.27 : width * 0.73;
if (_footAngle > 30) _footAngle = 30; //set the upper limit
if (_footAngle < -30) _footAngle = -30; //set the lower limit
this.y = map(
_footAngle,
-30,
30,
(width * 0.5 * 320) / 120 - this.diameter * 0.5,
this.diameter * 0.5
);
//Sound
let freqValue = midiToFreq(scaleArray[int(map(_footAngle, -30, 30, 0, 7))]); //8 levels of scale depending on the angle of landing
osc.freq(freqValue);
envelope.play(osc, 0, 0.1);
}
update() {
if (this.diameter > 0) this.diameter--;
if (this.transparency > 0) this.transparency--;
}
display() {
fill(255, this.transparency);
ellipse(this.x, this.y, this.diameter, this.diameter);
}
}
//to Debug
function keyPressed() {
if (keyCode === UP_ARROW) {
landCircles.push(new LandingPoint(0, 20));
} else if (keyCode === RIGHT_ARROW) {
landCircles.push(new LandingPoint(0, 10));
} else if (keyCode === DOWN_ARROW) {
landCircles.push(new LandingPoint(1, -20));
} else if (keyCode === LEFT_ARROW) {
landCircles.push(new LandingPoint(1, -10));
}
}