Compare commits
No commits in common. "rehersal_v1" and "main" have entirely different histories.
rehersal_v
...
main
25 changed files with 132 additions and 681 deletions
BIN
audio/03.mp3
BIN
audio/03.mp3
Binary file not shown.
BIN
audio/04.mp3
BIN
audio/04.mp3
Binary file not shown.
BIN
audio/05.mp3
BIN
audio/05.mp3
Binary file not shown.
BIN
audio/06.mp3
BIN
audio/06.mp3
Binary file not shown.
BIN
audio/07.mp3
BIN
audio/07.mp3
Binary file not shown.
BIN
audio/delayecho.mp3
Normal file
BIN
audio/delayecho.mp3
Normal file
Binary file not shown.
BIN
audio/minok01.mp3
Normal file
BIN
audio/minok01.mp3
Normal file
Binary file not shown.
BIN
audio/minok02.mp3
Normal file
BIN
audio/minok02.mp3
Normal file
Binary file not shown.
BIN
audio/minok03.mp3
Normal file
BIN
audio/minok03.mp3
Normal file
Binary file not shown.
BIN
audio/minok04.mp3
Normal file
BIN
audio/minok04.mp3
Normal file
Binary file not shown.
Binary file not shown.
BIN
audio/minok1frequency.mp3
Normal file
BIN
audio/minok1frequency.mp3
Normal file
Binary file not shown.
BIN
audio/minok2transpose.mp3
Normal file
BIN
audio/minok2transpose.mp3
Normal file
Binary file not shown.
BIN
audio/minok3delay.mp3
Normal file
BIN
audio/minok3delay.mp3
Normal file
Binary file not shown.
BIN
audio/minok4eq.mp3
Normal file
BIN
audio/minok4eq.mp3
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
audio/집중호우와멜로디언.mp3
Normal file
BIN
audio/집중호우와멜로디언.mp3
Normal file
Binary file not shown.
|
|
@ -1,22 +1,14 @@
|
|||
@font-face {
|
||||
font-family: 'ACCchildrenfall';
|
||||
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_2112-2@1.0/ACCchildrenfall.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'ACCchildrenfall';
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.fullscreen {
|
||||
.overlay-userinput {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
|
@ -25,55 +17,8 @@ canvas {
|
|||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
#overlay-userinput {
|
||||
/* display: none; */
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: white;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#announcements {
|
||||
/* display: none; */
|
||||
/* background-color: lime; */
|
||||
color: white;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#radio {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#radiostart-userinput {
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
right: 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#scene-minok {
|
||||
position: fixed;
|
||||
top: 100px;
|
||||
right: 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#scene-wonjung {
|
||||
position: fixed;
|
||||
top: 150px;
|
||||
right: 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#scene-all {
|
||||
position: fixed;
|
||||
top: 200px;
|
||||
right: 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
/* Styles go here */
|
||||
.animationStripes{
|
||||
background-image: repeating-linear-gradient(-45deg, gold, gold 1em, blue 1em, blue 2em);
|
||||
-webkit-animation:progress 2s linear infinite;
|
||||
-moz-animation:progress 2s linear infinite;
|
||||
-ms-animation:progress 2s linear infinite;
|
||||
animation:progress 2s linear infinite;
|
||||
background-size: 150% 100%;
|
||||
|
||||
display: none;
|
||||
color: white;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@-webkit-keyframes progress{
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -3em 0em;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes progress{
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -3em 0em;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes progress{
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -3em 0em;
|
||||
}
|
||||
}
|
||||
@keyframes progress{
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -2.8em 0em;
|
||||
}
|
||||
}
|
||||
614
index.html
614
index.html
|
|
@ -8,51 +8,22 @@
|
|||
<script src="js/p5.min.js"></script>
|
||||
<script src="js/Tone.min.js"></script>
|
||||
<!-- css -->
|
||||
<link type="text/css" rel="stylesheet" href="css/default.css">
|
||||
<link type="text/css" rel="stylesheet" href="css/loading-animation.css" />
|
||||
<!-- <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> -->
|
||||
<link rel="stylesheet" href="css/default.css">
|
||||
<!-- script -->
|
||||
<script>
|
||||
// const AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||
// let audioCtx;
|
||||
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||
let audioCtx;
|
||||
</script>
|
||||
<script src="js/util.js"></script>
|
||||
<script src="js/classes.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id='overlay-userinput' class='fullscreen' onclick='initialize();'>
|
||||
<div style='width:100%;'>
|
||||
<div style='text-align: left;'>터치하고-</div>
|
||||
<div style='text-align: right;'>시작하기!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='loading-veil' class='fullscreen animationStripes'>
|
||||
<div>로~~~~~딩⏳</div>
|
||||
</div>
|
||||
|
||||
<div id='announcements' class='fullscreen announcements'>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
<button id='radiostart-userinput' onclick='document.querySelector("#radio").play();'>
|
||||
<span style='font-size:3em;'>📻</span>
|
||||
<button class='overlay-userinput' onclick='initialize();'>
|
||||
<div>터치하고-시작하기!</div>
|
||||
</button>
|
||||
|
||||
<button id='scene-minok' onclick='scene=10;sceneChanger();'>
|
||||
<span style='font-size:3em;'>🍇</span>
|
||||
</button>
|
||||
|
||||
<button id='scene-wonjung' onclick='scene=20;sceneChanger();'>
|
||||
<span style='font-size:3em;'>🥑</span>
|
||||
</button>
|
||||
|
||||
<button id='scene-all' onclick='scene=scene+1;sceneChanger();'>
|
||||
<span style='font-size:3em;'>🥥</span>
|
||||
</button>
|
||||
|
||||
<audio id="radio" controls crossorigin="anonymous">
|
||||
<!-- iOS bug... you must add <source> later! -->
|
||||
<audio controls crossorigin="anonymous" style="display:none;">
|
||||
<!-- <source src="https://radio.dianaband.in:8000/stream" type="audio/aac" /> -->
|
||||
</audio>
|
||||
|
||||
|
|
@ -62,6 +33,8 @@
|
|||
let heading = 0;
|
||||
let latitude = 37.574973;
|
||||
let longitude = 126.925708;
|
||||
// let latitude = 37.576774;
|
||||
// let longitude = 126.931232;
|
||||
|
||||
// 맞는 결과 (예) : 작업실 -> 베지스
|
||||
// p1 = [37.574973, 126.925708]
|
||||
|
|
@ -75,15 +48,7 @@
|
|||
let silence;
|
||||
let clap;
|
||||
let radio;
|
||||
//scene
|
||||
let scene = -1;
|
||||
//sounders' list
|
||||
let scenes = {};
|
||||
let minok_sounds = [];
|
||||
let wonjung_sounds = [];
|
||||
scenes.minok_sounds = minok_sounds;
|
||||
scenes.wonjung_sounds = wonjung_sounds;
|
||||
//all ready flag
|
||||
//all ready flag (not used)
|
||||
let ready = false;
|
||||
|
||||
//clear all permissions
|
||||
|
|
@ -94,237 +59,69 @@
|
|||
requestOrientationPermission();
|
||||
}
|
||||
|
||||
// remove the 'userinput' veil
|
||||
document.querySelector("#overlay-userinput").style.display = 'none';
|
||||
|
||||
// show loading screen.
|
||||
document.querySelector("#loading-veil").style.display = 'grid';
|
||||
|
||||
// unfreeze Tone.js with userinput
|
||||
await Tone.start();
|
||||
|
||||
// start audiocontext
|
||||
// audioCtx = new AudioContext;
|
||||
// audioCtx = Tone.getContext();
|
||||
audioCtx = new AudioContext;
|
||||
|
||||
// some sounds for check-in
|
||||
silence = (await AudioImport("./audio/_silence.wav")).toDestination();
|
||||
clap = (await AudioImport("./audio/clap01.mp3")).toDestination();
|
||||
|
||||
// start loading for all sounds
|
||||
sounds.forEach(async item => await item.load());
|
||||
|
||||
// unfreeze audio playback for Tone.js
|
||||
silence.start();
|
||||
// clap.start();
|
||||
|
||||
// register sounders to the list
|
||||
minok_sounds.push(new Sounder({
|
||||
name: '주파수 구간',
|
||||
location: [37.575451, 126.926939],
|
||||
soundfile: "./audio/minok_01.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
minok_sounds.push(new Sounder({
|
||||
name: 'Transpose',
|
||||
location: [37.575009, 126.926373],
|
||||
soundfile: "./audio/minok_02.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
minok_sounds.push(new Sounder({
|
||||
name: 'Delay',
|
||||
location: [37.574383, 126.925500],
|
||||
soundfile: "./audio/minok_03.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
minok_sounds.push(new Sounder({
|
||||
name: 'EQ',
|
||||
location: [37.573562, 126.924426],
|
||||
soundfile: "./audio/minok_04.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
minok_sounds.push(new Sounder({
|
||||
name: '모든 효과가 다 섞인 뇌절 of 뇌절 트랙',
|
||||
location: [37.572931, 126.923612],
|
||||
soundfile: "./audio/minok_05.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
minok_sounds.push(new Sounder({
|
||||
name: '뇌절 트랙 (끝!)',
|
||||
location: [37.571918, 126.922360],
|
||||
soundfile: "./audio/minok_05.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
// remove the veil
|
||||
let veil = document.querySelector(".overlay-userinput");
|
||||
veil.style.display = 'none';
|
||||
|
||||
wonjung_sounds.push(new Sounder({
|
||||
name: '푸르지오 앞 데크길 밑 운동기구',
|
||||
location: [37.576013, 126.927912],
|
||||
soundfile: "./audio/01.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
wonjung_sounds.push(new Sounder({
|
||||
name: '연리지',
|
||||
location: [37.574409, 126.925210],
|
||||
soundfile: "./audio/02.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
wonjung_sounds.push(new Sounder({
|
||||
name: '폭우와 멜로디혼',
|
||||
location: [37.573430, 126.923445],
|
||||
soundfile: "./audio/03.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
wonjung_sounds.push(new Sounder({
|
||||
name: '농구대',
|
||||
location: [37.573149, 126.922870],
|
||||
soundfile: "./audio/04.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
wonjung_sounds.push(new Sounder({
|
||||
name: '물소리 조각',
|
||||
location: [37.574623, 126.924903],
|
||||
soundfile: "./audio/05.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
wonjung_sounds.push(new Sounder({
|
||||
name: '좌우패닝 벤치-지나가는 무게들',
|
||||
location: [37.577172, 126.922993],
|
||||
soundfile: "./audio/06.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
wonjung_sounds.push(new Sounder({
|
||||
name: '귀뚜라미',
|
||||
location: [37.576753, 126.929252],
|
||||
soundfile: "./audio/07.mp3",
|
||||
gain: 0,
|
||||
spread: 20,
|
||||
distmap: [0.01, 0.08, 0, -20], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
|
||||
// start loading for all soundfile-based sounders.
|
||||
//N.B. for 'await', watch out 'forEach' ... https://stackoverflow.com/a/37576787
|
||||
for (const item of scenes.wonjung_sounds) await item.load();
|
||||
for (const item of scenes.minok_sounds) await item.load();
|
||||
|
||||
// activate radio by injecting <source> tag
|
||||
const audiotag = document.querySelector('#radio');
|
||||
// activate radio by adding source tag
|
||||
const audiotag = document.querySelector('audio'); // N.B. assuming there's only 1 audio tag for streaming...
|
||||
const sourcetag = document.createElement('source');
|
||||
sourcetag.setAttribute('src', 'https://radio.dianaband.in:8000/stream');
|
||||
sourcetag.setAttribute('type', 'audio/aac');
|
||||
audiotag.appendChild(sourcetag);
|
||||
audiotag.play();
|
||||
|
||||
//link a sounder object to radio streaming..
|
||||
radio = new RadioSounder({
|
||||
name: "베짜-📻",
|
||||
location: [37.574973, 126.925708],
|
||||
gain: 0,
|
||||
spread: 90,
|
||||
distmap: [0.01, 2, 0, -10], // (km) -> (dB)
|
||||
//testing
|
||||
volmin: -30,
|
||||
});
|
||||
radio.link(audiotag);
|
||||
// audiotag.play(); // this doesn't work.. for some buggy iOS versions. another userinput needed..
|
||||
// //link a sounder object to radio streaming..
|
||||
// radio = new Sounder({
|
||||
// // location: [37.576013, 126.927912],
|
||||
// location: [37.574973, 126.935708],
|
||||
// soundfile: "./audio/clap01.mp3",
|
||||
// gain: 6,
|
||||
// spread: 15,
|
||||
// distmap: [0.005, 0.05, 0, -10],
|
||||
// //testing
|
||||
// volmin: -30,
|
||||
// });
|
||||
// // radio.radiolink(audiotag);
|
||||
// radio.load();
|
||||
|
||||
// remove loading screen.
|
||||
document.querySelector("#loading-veil").style.display = 'none';
|
||||
|
||||
// remove loading screen.
|
||||
document.querySelector("#announcements").style.display = 'grid';
|
||||
//
|
||||
ready = true;
|
||||
|
||||
//
|
||||
scene = 0;
|
||||
sceneChanger();
|
||||
}
|
||||
|
||||
async function sceneChanger() {
|
||||
switch (scene) {
|
||||
case 0:
|
||||
await fullscreenSplasher('<div>스테이지</div>', 1000); // some *splashes*
|
||||
await fullscreenSplasher('<div>0</div>', 1000);
|
||||
await fullscreenSplasher('<div>시작~~~</div>', 3000);
|
||||
await fullscreenSplasher('', 0);
|
||||
break;
|
||||
case 10:
|
||||
await fullscreenSplasher('<div>스테이지</div>', 1000); // some *splashes*
|
||||
await fullscreenSplasher('<div>1</div>', 1000);
|
||||
await fullscreenSplasher('<div>시작~~~</div>', 3000);
|
||||
await fullscreenSplasher('', 0);
|
||||
break;
|
||||
case 20:
|
||||
await fullscreenSplasher('<div>스테이지</div>', 1000); // some *splashes*
|
||||
await fullscreenSplasher('<div>2</div>', 1000);
|
||||
await fullscreenSplasher('<div>시작~~~</div>', 3000);
|
||||
await fullscreenSplasher('', 0);
|
||||
break;
|
||||
case 30:
|
||||
await fullscreenSplasher('<div>스테이지</div>', 1000); // some *splashes*
|
||||
await fullscreenSplasher('<div>3</div>', 1000);
|
||||
await fullscreenSplasher('<div>시작~~~</div>', 3000);
|
||||
await fullscreenSplasher('', 0);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
async function fullscreenSplasher(html, timeout) {
|
||||
let element = document.querySelector('#announcements');
|
||||
// element.style.display = 'grid';
|
||||
element.innerHTML = html;
|
||||
await asyncTimeout(timeout);
|
||||
}
|
||||
let compass_target;
|
||||
let compass_north;
|
||||
let sounds = [];
|
||||
|
||||
function setup() {
|
||||
createCanvas(windowWidth, windowHeight);
|
||||
compass_target = new Compass(200, ['#97FFFF', '#33A1DE', 'white']);
|
||||
compass_north = new Compass(40, ['yellow', 'navy', 'white']);
|
||||
angleMode(DEGREES);
|
||||
|
||||
// register sounders to the list
|
||||
sounds.push(new Sounder({
|
||||
location: [37.576774, 126.931232],
|
||||
soundfile: "./audio/01.mp3",
|
||||
gain: 6,
|
||||
spread: 15,
|
||||
distmap: [0.005, 0.05, 0, -10],
|
||||
//testing
|
||||
volmin: -30,
|
||||
}));
|
||||
}
|
||||
|
||||
function draw() {
|
||||
|
|
@ -335,279 +132,82 @@
|
|||
if (ready) {
|
||||
|
||||
//update sounders
|
||||
scenes.wonjung_sounds.forEach(item => item.update_location());
|
||||
scenes.minok_sounds.forEach(item => item.update_location());
|
||||
sounds.forEach(async item => await item.update());
|
||||
// radio.update();
|
||||
|
||||
//update radio
|
||||
radio.update_location();
|
||||
radio.pv.pan.value = 0;
|
||||
radio.pv.volume.rampTo(radio.gain, radio.ramptime);
|
||||
//
|
||||
let target = sounds[0];
|
||||
|
||||
////main group
|
||||
|
||||
//a tabular compass closet.
|
||||
let compass_table;
|
||||
//(push)
|
||||
push();
|
||||
|
||||
//scene logic
|
||||
if (scene == 0) {
|
||||
//compass (the North)
|
||||
translate(20, 20, 0);
|
||||
compass_target.heading = target.angerr; //target #0
|
||||
compass_target.draw();
|
||||
|
||||
// tutorial stage
|
||||
//(pop)
|
||||
pop();
|
||||
|
||||
scenes.wonjung_sounds.forEach(item => item.update_panvol());
|
||||
//
|
||||
compass_table = [];
|
||||
Sounder.allStart(scenes.wonjung_sounds);
|
||||
Sounder.allStop(scenes.minok_sounds);
|
||||
// draw sth.
|
||||
push();
|
||||
let sounder = scenes.wonjung_sounds[0];
|
||||
let compass_target = new Compass(250, ['#003456', '#77AAAA', 'navy']);
|
||||
compass_target.pointer = sounder.angerr;
|
||||
translate((windowWidth - compass_target.size) / 2, (windowHeight - compass_target.size) / 2, 0);
|
||||
compass_target.draw();
|
||||
fill('white');
|
||||
Textline.restart();
|
||||
Textline.put(sounder.name);
|
||||
Textline.put(sounder.latitude.toFixed(4) + ', ' + sounder.longitude.toFixed(4));
|
||||
Textline.put(sounder.angerr.toFixed(2) + ', ' + (sounder.dist * 1000).toFixed(2));
|
||||
Textline.put(sounder.pv.pan.value.toFixed(2) + ', ' + sounder.distvol.toFixed(2) + ', ' + sounder.pv.volume.value.toFixed(2));
|
||||
Textline.put(sounder.zone);
|
||||
pop();
|
||||
//(push)
|
||||
push();
|
||||
//debug
|
||||
fill('white');
|
||||
translate(30, 200, 0);
|
||||
Textline.restart();
|
||||
Textline.put('heading');
|
||||
Textline.put(heading);
|
||||
Textline.put('ang');
|
||||
Textline.put(target.ang);
|
||||
Textline.put('angerr');
|
||||
Textline.put(target.angerr);
|
||||
Textline.put('distance');
|
||||
Textline.put(target.dist);
|
||||
// Textline.put('pan');
|
||||
// Textline.put(target.pv.pan.value);
|
||||
// Textline.put('distvol');
|
||||
// Textline.put(target.distvol);
|
||||
// Textline.put('vol');
|
||||
// Textline.put(target.pv.volume.value);
|
||||
Textline.put('target_lat');
|
||||
Textline.put(target.latitude);
|
||||
Textline.put('target_lon');
|
||||
Textline.put(target.longitude);
|
||||
|
||||
} else if (scene == 10) {
|
||||
|
||||
//no sound
|
||||
|
||||
//N.B. assumption: change all locations to 'trigger' locations!
|
||||
//minok scene
|
||||
// approaching to the spot. **before** reaching the first trigger location.
|
||||
compass_table = scenes.minok_sounds;
|
||||
Sounder.allSilent(scenes.minok_sounds);
|
||||
Sounder.allStart(scenes.minok_sounds);
|
||||
Sounder.allStop(scenes.wonjung_sounds);
|
||||
//
|
||||
let next = scenes.minok_sounds[0];
|
||||
if (next.dist < 0.05) {
|
||||
//fade-in
|
||||
// console.log(next.snd.state);
|
||||
next.pv.pan.value = 0;
|
||||
next.pv.volume.rampTo(next.gain, next.ramptime);
|
||||
scene = 11;
|
||||
sceneChanger();
|
||||
}
|
||||
|
||||
} else if (scene == 11) {
|
||||
|
||||
//minok scene
|
||||
//listening to track #1
|
||||
|
||||
compass_table = scenes.minok_sounds;
|
||||
//
|
||||
let current = scenes.minok_sounds[0];
|
||||
current.pv.volume.rampTo(current.gain, current.ramptime);
|
||||
let next = scenes.minok_sounds[1];
|
||||
if (next.dist < 0.05) {
|
||||
//N.B. assumption: change location to 'playstart' location!
|
||||
//cross-fade
|
||||
current.pv.volume.rampTo(-99, current.ramptime);
|
||||
next.pv.volume.rampTo(next.gain, next.ramptime);
|
||||
scene = 12;
|
||||
sceneChanger();
|
||||
}
|
||||
|
||||
} else if (scene == 12) {
|
||||
|
||||
//minok scene
|
||||
//listening to track #2
|
||||
|
||||
compass_table = scenes.minok_sounds;
|
||||
//
|
||||
let current = scenes.minok_sounds[1];
|
||||
current.pv.volume.rampTo(current.gain, current.ramptime);
|
||||
let next = scenes.minok_sounds[2];
|
||||
if (next.dist < 0.05) {
|
||||
//N.B. assumption: change location to 'playstart' location!
|
||||
//cross-fade
|
||||
current.pv.volume.rampTo(-99, current.ramptime);
|
||||
next.pv.volume.rampTo(next.gain, next.ramptime);
|
||||
scene = 13;
|
||||
sceneChanger();
|
||||
}
|
||||
|
||||
} else if (scene == 13) {
|
||||
|
||||
//minok scene
|
||||
//listening to track #3
|
||||
|
||||
compass_table = scenes.minok_sounds;
|
||||
//
|
||||
let current = scenes.minok_sounds[2];
|
||||
current.pv.volume.rampTo(current.gain, current.ramptime);
|
||||
let next = scenes.minok_sounds[3];
|
||||
if (next.dist < 0.05) {
|
||||
//N.B. assumption: change location to 'playstart' location!
|
||||
//cross-fade
|
||||
current.pv.volume.rampTo(-99, current.ramptime);
|
||||
next.pv.volume.rampTo(next.gain, next.ramptime);
|
||||
scene = 14;
|
||||
sceneChanger();
|
||||
}
|
||||
|
||||
} else if (scene == 14) {
|
||||
|
||||
//minok scene
|
||||
//listening to track #4
|
||||
|
||||
compass_table = scenes.minok_sounds;
|
||||
//
|
||||
let current = scenes.minok_sounds[3];
|
||||
current.pv.volume.rampTo(current.gain, current.ramptime);
|
||||
let next = scenes.minok_sounds[4];
|
||||
if (next.dist < 0.05) {
|
||||
//N.B. assumption: change location to 'playstart' location!
|
||||
//cross-fade
|
||||
current.pv.volume.rampTo(-99, current.ramptime);
|
||||
next.pv.volume.rampTo(next.gain, next.ramptime);
|
||||
scene = 15;
|
||||
sceneChanger();
|
||||
}
|
||||
|
||||
} else if (scene == 15) {
|
||||
|
||||
//minok scene
|
||||
//listening to track #5
|
||||
|
||||
compass_table = scenes.minok_sounds;
|
||||
//
|
||||
let current = scenes.minok_sounds[4];
|
||||
current.pv.volume.rampTo(current.gain, current.ramptime);
|
||||
let next = scenes.minok_sounds[5]; // <-- dummy location, no sound. ending waypoint.
|
||||
if (next.dist < 0.05) {
|
||||
//N.B. assumption: change location to 'playstart' location!
|
||||
//fade-out
|
||||
current.pv.volume.rampTo(-99, current.ramptime);
|
||||
next.pv.volume.rampTo(-99, next.ramptime);
|
||||
scene = 16;
|
||||
sceneChanger();
|
||||
}
|
||||
|
||||
} else if (scene == 16) {
|
||||
|
||||
//minok scene
|
||||
//No-no zone.
|
||||
|
||||
compass_table = [];
|
||||
Sounder.allStop(scenes.minok_sounds);
|
||||
Sounder.allStop(scenes.minok_sounds);
|
||||
|
||||
} else if (scene == 20) {
|
||||
|
||||
//wonjung scene
|
||||
|
||||
compass_table = scenes.wonjung_sounds;
|
||||
Sounder.allStart(scenes.wonjung_sounds);
|
||||
Sounder.allStop(scenes.minok_sounds);
|
||||
scenes.wonjung_sounds.forEach(item => item.update_panvol());
|
||||
|
||||
} else {
|
||||
|
||||
//everything else
|
||||
// nothing to show/playback.
|
||||
|
||||
compass_table = [];
|
||||
Sounder.allStop(scenes.wonjung_sounds);
|
||||
Sounder.allStop(scenes.minok_sounds);
|
||||
}
|
||||
|
||||
//
|
||||
push(); // +1
|
||||
translate(20, 90, 0);
|
||||
|
||||
//
|
||||
let compass_offsets = [
|
||||
createVector(0, 0),
|
||||
createVector(0, 110),
|
||||
createVector(0, 220),
|
||||
createVector(0, 330),
|
||||
createVector(150, 0),
|
||||
createVector(150, 110),
|
||||
createVector(150, 220),
|
||||
createVector(150, 330),
|
||||
];
|
||||
for (const [i, sounder] of compass_table.entries()) {
|
||||
|
||||
push(); // +2
|
||||
translate(compass_offsets[i].x, compass_offsets[i].y, 0);
|
||||
|
||||
//compass targeting the location
|
||||
// let compass_target = new Compass(120, ['#33A1DE', '#97FFFF', 'navy']);
|
||||
let compass_target = new Compass(120, ['#003456', '#77AAAA', 'navy']);
|
||||
compass_target.pointer = sounder.angerr;
|
||||
compass_target.draw();
|
||||
|
||||
//debug
|
||||
// translate(0, 120, 0);
|
||||
translate(0, 0, 0);
|
||||
fill('white');
|
||||
Textline.restart();
|
||||
Textline.put(sounder.name);
|
||||
Textline.put(sounder.latitude.toFixed(4) + ', ' + sounder.longitude.toFixed(4));
|
||||
Textline.put(sounder.angerr.toFixed(2) + ', ' + (sounder.dist * 1000).toFixed(2));
|
||||
Textline.put(sounder.pv.pan.value.toFixed(2) + ', ' + sounder.distvol.toFixed(2) + ', ' + sounder.pv.volume.value.toFixed(2));
|
||||
|
||||
pop(); // -2
|
||||
}
|
||||
|
||||
pop(); // -1
|
||||
|
||||
// ////radio
|
||||
// push(); // +2
|
||||
// translate(windowWidth - 120, windowHeight - 200, 0);
|
||||
//
|
||||
// //compass targeting the location
|
||||
// // let compass_target = new Compass(120, ['#33A1DE', '#97FFFF', 'navy']);
|
||||
// let compass_radio = new Compass(120, ['#003456', '#77AAAA', 'navy']);
|
||||
// compass_radio.pointer = radio.angerr;
|
||||
// compass_radio.draw();
|
||||
//
|
||||
// //debug
|
||||
// // translate(0, 120, 0);
|
||||
// translate(0, 0, 0);
|
||||
// fill('white');
|
||||
// Textline.restart();
|
||||
// Textline.put(radio.name);
|
||||
// Textline.put(radio.latitude.toFixed(4) + ', ' + radio.longitude.toFixed(4));
|
||||
// Textline.put(radio.angerr.toFixed(2) + ', ' + (radio.dist * 1000).toFixed(2));
|
||||
// Textline.put(radio.pv.pan.value.toFixed(2) + ', ' + radio.distvol.toFixed(2) + ', ' + radio.pv.volume.value.toFixed(2));
|
||||
//
|
||||
// pop(); // -2
|
||||
//(pop)
|
||||
pop();
|
||||
|
||||
////status-left group
|
||||
|
||||
push(); // +1
|
||||
//(push)
|
||||
push();
|
||||
|
||||
//
|
||||
translate(20, windowHeight - 100, 0);
|
||||
fill('white');
|
||||
Textline.restart();
|
||||
Textline.put('current location');
|
||||
Textline.put(latitude.toFixed(6) + ', ' + longitude.toFixed(6));
|
||||
Textline.put('scene');
|
||||
Textline.put(scene);
|
||||
pop(); // -1
|
||||
Textline.put(latitude);
|
||||
Textline.put(longitude);
|
||||
|
||||
//(pop)
|
||||
pop();
|
||||
|
||||
|
||||
////status-right group
|
||||
|
||||
push(); // +1
|
||||
translate(windowWidth - 50, windowHeight - 100, 0);
|
||||
let compass_north = new Compass(40, ['yellow', 'navy', 'white']);
|
||||
compass_north.pointer = heading * -1; // the North pole azimuth is opposite of my heading.
|
||||
//(push)
|
||||
push();
|
||||
|
||||
//
|
||||
translate(windowWidth - 50, windowHeight - 50, 0);
|
||||
compass_north.heading = heading;
|
||||
compass_north.draw();
|
||||
translate(0, 40, 0);
|
||||
fill('white');
|
||||
Textline.restart();
|
||||
Textline.put('N');
|
||||
Textline.put(heading.toFixed(2));
|
||||
pop(); // -1
|
||||
|
||||
//(pop)
|
||||
pop();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// sounds
|
||||
class Sounder {
|
||||
constructor(args) {
|
||||
this.name = args.name;
|
||||
this.soundfile = args.soundfile;
|
||||
this.gain = args.gain; // (dB)
|
||||
this.latitude = args.location[0];
|
||||
|
|
@ -10,30 +9,27 @@ class Sounder {
|
|||
this.distmap = args.distmap;
|
||||
this.volmin = args.volmin; // (dB)
|
||||
this.ramptime = args.ramptime; // (seconds)
|
||||
this.zone = 0;
|
||||
}
|
||||
|
||||
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.start();
|
||||
this.snd.loop = true;
|
||||
}
|
||||
|
||||
update_location() {
|
||||
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)
|
||||
}
|
||||
update_panvol() {
|
||||
// console.log('pv');
|
||||
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 = (heading - this.ang + 360) % 360;
|
||||
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:
|
||||
|
|
@ -41,35 +37,22 @@ class Sounder {
|
|||
// -width/2 ~ width/2 -> cross fading
|
||||
// +width/2 ~ width*(1.5) -> right fade-out
|
||||
|
||||
//if close enough. don't do pan/vol, but just playback with full volume.
|
||||
this.zone = 0;
|
||||
if (this.dist < 0.07) {
|
||||
this.zone = 1;
|
||||
this.pv.pan.rampTo(0, this.ramptime);
|
||||
this.pv.volume.rampTo(this.gain, this.ramptime); //(dB)
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//pan & volume
|
||||
//left fade-in
|
||||
if (this.angerr > panleft_start && this.angerr < panleft_end) {
|
||||
//left fade-in
|
||||
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); //(dB)
|
||||
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) {
|
||||
//cross fading; //(dB)
|
||||
this.pv.pan.value = map(this.angerr, panleft_end, panright_start, -1, 1);
|
||||
this.pv.volume.rampTo(this.distvol + this.gain, this.ramptime); //(dB)
|
||||
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) {
|
||||
//right fade-out
|
||||
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); //(dB)
|
||||
this.pv.volume.rampTo(this.distvol + this.gain + map(this.angerr, panright_start, panright_end, 0, this.volmin), this.ramptime)//slience; //(dB)
|
||||
} else {
|
||||
//slience
|
||||
this.pv.volume.rampTo(-99, 10); //(dB)
|
||||
}
|
||||
}
|
||||
|
|
@ -77,33 +60,11 @@ class Sounder {
|
|||
draw() {
|
||||
//draw sound location
|
||||
}
|
||||
|
||||
static allStart(array) {
|
||||
array.forEach(item => {
|
||||
if (item.snd.state != 'started') item.snd.start();
|
||||
});
|
||||
}
|
||||
|
||||
static allStop(array) {
|
||||
array.forEach(item => {
|
||||
if (item.snd.state != 'stopped') item.snd.stop();
|
||||
});
|
||||
}
|
||||
|
||||
static allSilent(array) {
|
||||
array.forEach(item => {
|
||||
item.pv.volume.rampTo(-99, item.ramptime);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
class RadioSounder extends Sounder {
|
||||
|
||||
constructor(args) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
//do nothing
|
||||
async load() {
|
||||
;
|
||||
|
|
@ -112,21 +73,15 @@ class RadioSounder extends Sounder {
|
|||
link(audiotag) {
|
||||
//start sound playback
|
||||
this.pv = new Tone.PanVol(0, -99).toDestination();
|
||||
|
||||
//native webaudio
|
||||
this.source = Tone.context.createMediaElementSource(audiotag);
|
||||
this.snd = undefined;
|
||||
this.gainnode = Tone.context.createGain();
|
||||
this.gainnode.gain.value = 1; // 1 == max. volume
|
||||
|
||||
//a hacky native-to-Tonejs connection(?!)
|
||||
this.source.connect(this.gainnode).connect(this.pv.input.input);
|
||||
}
|
||||
|
||||
update() {
|
||||
super.update();
|
||||
|
||||
// console.log('hi!');
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +90,7 @@ class Compass {
|
|||
constructor(size, colors) {
|
||||
this.size = size;
|
||||
this.colors = colors;
|
||||
this.pointer = 0;
|
||||
this.heading = 0;
|
||||
}
|
||||
|
||||
draw() {
|
||||
|
|
@ -151,7 +106,7 @@ class Compass {
|
|||
circle(0, 0, 0.9);
|
||||
//
|
||||
fill(this.colors[1]);
|
||||
rotate(this.pointer);
|
||||
rotate(this.heading * -1);
|
||||
quad(0.1, 0.2, 0, -0.4, -0.1, 0.2, 0, 0.1);
|
||||
//
|
||||
fill(this.colors[2]);
|
||||
|
|
|
|||
|
|
@ -86,9 +86,6 @@ function AudioImport(url) {
|
|||
});
|
||||
}
|
||||
|
||||
//promisified 'setTimeout' from https://stackoverflow.com/a/74004853
|
||||
const asyncTimeout = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
// some p5 tools
|
||||
class Textline {
|
||||
static #lines = 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue