heading-ears/js/classes.js
2024-10-12 15:28:34 +09:00

118 lines
3.4 KiB
JavaScript

// sounds
class Sounder {
constructor(args) {
this.soundfile = args.soundfile;
this.gain = args.gain; // (dB)
this.latitude = args.location[0];
this.longitude = args.location[1];
this.spread = args.spread; // (deg)
this.distmap = args.distmap;
this.volmin = args.volmin; // (dB)
this.ramptime = args.ramptime; // (seconds)
}
async load() {
//start sound playback
this.pv = new Tone.PanVol(0, -99).toDestination();
this.snd = await AudioImport(this.soundfile); // NOTE: url with spaces didn't work here.
// this.snd.connect(this.pv).start();
this.snd.connect(this.pv);
this.snd.loop = true;
}
update() {
//
//update sound pan/volume
//
// this.ang = getBearing(latitude, longitude, this.latitude, this.longitude); (deg)
this.ang = getBearing(latitude, longitude, this.latitude, this.longitude); // (deg)
this.angerr = (((this.ang - heading + 360) % 360) + 180) % 360 - 180;
this.dist = getDistance(latitude, longitude, this.latitude, this.longitude); // (km)
//
this.distvol = map(this.dist, this.distmap[0], this.distmap[1], this.distmap[2], this.distmap[3], true); //(dB)
// (from Pure Data patch "iamyou", [eqpan2~])
// arg #1 (inlet #3): width:
// -width*(1.5) ~ -width/2 -> left fade-in
// -width/2 ~ width/2 -> cross fading
// +width/2 ~ width*(1.5) -> right fade-out
let panleft_start = this.spread * (-1.5);
let panleft_end = this.spread * (-0.5);
let panright_start = this.spread * (0.5);
let panright_end = this.spread * (1.5);
//left fade-in
if (this.angerr > panleft_start && this.angerr < panleft_end) {
this.pv.pan.value = -1; //left-full
this.pv.volume.rampTo(this.distvol + this.gain + map(this.angerr, panleft_start, panleft_end, this.volmin, 0), this.ramptime)//cross fading; //(dB)
} else if (this.angerr > panleft_end && this.angerr < panright_start) {
this.pv.pan.value = map(this.angerr, panleft_end, panright_start, -1, 1); // crossfade
this.pv.volume.rampTo(this.distvol + this.gain, this.ramptime)//right fade-out; //(dB)
} else if (this.angerr > panright_start && this.angerr < panright_end) {
this.pv.pan.value = 1; //right-full
this.pv.volume.rampTo(this.distvol + this.gain + map(this.angerr, panright_start, panright_end, 0, this.volmin), this.ramptime)//slience; //(dB)
} else {
this.pv.volume.rampTo(-99, 10); //(dB)
}
}
draw() {
//draw sound location
}
}
//
class RadioSounder extends Sounder {
//do nothing
async load() {
;
}
link(audiotag) {
//start sound playback
this.pv = new Tone.PanVol(0, -99).toDestination();
let stream = Tone.context.createMediaElementSource(audiotag);
this.snd = Tone.context.createGain();
stream.connect(this.snd);
console.log(stream);
console.log(this.snd);
console.log(this.pv);
// this.snd.connect(this.pv.input.input); a hack ...
this.snd.gain.value = 1;
this.snd.connect(Tone.context.destination);
}
}
//p5
class Compass {
constructor(size, colors) {
this.size = size;
this.colors = colors;
this.heading = 0;
}
draw() {
push();
//
scale(this.size);
//
translate(0.5, 0.5);
//
noStroke();
//
fill(this.colors[0]);
circle(0, 0, 0.9);
//
fill(this.colors[1]);
rotate(this.heading);
quad(0.1, 0.2, 0, -0.4, -0.1, 0.2, 0, 0.1);
//
fill(this.colors[2]);
circle(0, 0, 0.05);
//
pop();
}
}