--- /dev/null
+const num_slots = 16;
+let num_regions = 0;
+let phase;
+let curr_region = -1;
+//let filepath = "media/basic-break.wav";
+let filepath = "media/Berio-criesoflondon.wav";
+let global_dict = new Object();
+let text_input, text_butt;
+let btn_r = [];
+let btn_tp = [];
+let btn_misc = [];
+let ws;
+let wsr;
+
+//https://medium.com/analytics-vidhya/local-storage-with-vanilla-javascript-c87e3923163a
+
+//initialization---------------------------------------------------------------------
+//
+
+//REGIONS ISSUE:
+//https://wavesurfer.xyz/example/regions/
+//https://wavesurfer.xyz/example/plugin-system/
+
+const setup = async() => {
+ initialize();
+ buttons_make();
+}
+
+//main routine-----------------------------------------------------------------------
+//
+
+document.addEventListener('DOMContentLoaded', function(){
+ setup();
+});
+
+//functions--------------------------------------------------------------------------
+//
+// dynamic loading
+// ws.load('/some/path/to/wave.wav');
+//
+
+
+function add_one_region() {
+ const dur = ws.getDuration();
+ const pad = 0.2;
+ const currtime = ws.getCurrentTime();
+
+ //let randstart = (Math.random() * dur) - pad;
+ //let randend = randstart + 3;
+
+ wsr.addRegion({
+ channelIdx: num_regions,
+ content: "region" + num_regions + "text",
+ //id: "cue " + i,
+ id: 'region',
+ start: currtime,
+ end: currtime + pad,
+ loop: false,
+ color: 'hsla(184, 32%, 72%, 0.1)'
+ });
+ num_regions++;
+}
+function add_3_regions() {
+ const dur = ws.getDuration();
+ const pad = 0.2;
+
+ for(let i=0; i<3; i++){
+
+ let randstart = (Math.random() * dur) - pad;
+ let randend = randstart + 3;
+
+ wsr.addRegion({
+ channelIdx: i,
+ content: "region" + i + "text",
+ //id: "cue " + i,
+ id: 'region',
+ start: randstart,
+ end: randend,
+ loop: false,
+ color: 'hsla(184, 32%, 72%, 0.1)'
+ });
+ num_regions++;
+ }
+}
+
+function buttons_reset() {
+ btn_tp_reset();
+ btn_r_reset();
+ btn_m_reset();
+ marker_reset();
+}
+
+function marker_add() {
+ num_regions++;
+
+}
+
+function marker_reset(){
+ curr_region = -1;
+ text_input.value = "no marker selected";
+}
+
+//-------------------------------------------------------------
+//localStorage read/write/clear/etc
+function localstorage_get() {
+ return JSON.stringify(localStorage);
+}
+
+function localstorage_write(data) {
+ Object.keys(data).forEach( function(key) {
+ localStorage.setItem(key, data[key])
+ });
+}
+
+//-------------------------------------------------------------
+
+function initialize(){
+
+ let activeregion = null;
+
+ ws = WaveSurfer.create({
+ container: '#waveform',
+ waveColor: 'hsla(184, 32%, 72%, 0.5)',
+ progressColor: 'hsla(184, 0%, 72%, 0.5)',
+ url: filepath
+ /*
+ , plugins: [
+ WaveSurfer.Regions.create({})
+ ]
+ */
+ });
+
+ //let RegionsPlugin = window.WaveSurfer.regions;
+ //wsr = window.WaveSurfer.regions;
+ wsr = ws.registerPlugin(WaveSurfer.Regions.create())
+
+ ws.on('ready', function (){
+ console.log("wavesurfer ready.");
+ });
+
+ //put a text element over the ws while this is loading
+ ws.on('loading', (percent) => {
+ console.log('loading', percent, '%');
+ });
+
+ ws.on('click', (relativeX) => {
+ ws.seekTo(relativeX);
+ ws.play();
+ buttons_reset();
+ });
+
+ wsr.on('region-updated', (region) => {
+ console.log("a region with id", region.channelIdx, "was updated.");
+ console.log("the new start:", region.start);
+ console.log("the new end:", region.end);
+ //do something here to update json or re-popuplate all marker data
+ });
+
+ wsr.on('region-clicked', (region, e) => {
+ e.stopPropagation();
+ activeregion = region;
+ region.play();
+ buttons_reset();
+
+ text_input.value = region.content.innerHTML;
+ curr_region = region.channelIdx; //zero-based
+
+ console.log("a region with id", region.channelIdx, "was clicked.");
+ console.log("this region's start time is", region.start);
+ //console.log("this region's text:", region.content.innerHTML);
+ });
+
+ //key events -----------------------------------------------------------------
+ //
+
+ window.addEventListener("keydown", (e) => {
+ if(!e.repeat && e.key == 'm') {
+ //console.log('the m key was pressed');
+ add_one_region();
+ }
+ });
+
+ //user data ------------------------------------------------------------------
+ //
+
+ global_dict = {
+ "soundfile" : filepath,
+ "m0" : [2.4, 3., "m1 label"],
+ "m1" : [8.2, 3., "m2 label"],
+ "m2" : [11.7, 3., "m3 label"],
+ "m3" : [14.9, 3., "m4 label"]
+ };
+
+ text_input = document.getElementById("textinput");
+ text_butt = document.getElementById("textsubmit");
+
+ //marker text
+ text_butt.addEventListener('click', () => {
+ console.log("the text entered was", text_input.value);
+
+ if(curr_region){
+ //wsr[curr_region].content.innerHTML = text_input.value;
+ //do stuff here to display region text
+ }
+
+ });
+ //interface data--------------------------------------------------------------
+ //
+
+ //generate cue marker section
+ for(let i=0; i<num_slots; i++){
+ let temp = {
+ id: "button-" + i,
+ text: (i + 1),
+ clicked: false,
+ call_action: function(){
+ btn_r_reset();
+ console.log('recall button', i, 'clicked');
+ },
+ };
+ btn_r.push(temp);
+ }
+
+ btn_tp = [
+ {
+ id: "button1",
+ text: "play/resume",
+ clicked: false,
+ call_action: function () {
+ ws.play();
+ },
+ },
+ {
+ id: "button2",
+ text: "pause",
+ clicked: false,
+ call_action: function () {
+ ws.pause();
+ },
+ },
+ {
+ id: "button3",
+ text: "stop [+ cue]",
+ clicked: false,
+ call_action: function () {
+ ws.stop();
+ },
+ }
+ ];
+
+ btn_misc = [
+ {
+ id: "generate",
+ text: "generate markers",
+ clicked: false,
+ call_action: function () {
+ console.log("generate button clicked");
+ wsr.clearRegions();
+ add_3_regions();
+ },
+ },
+ {
+ id: "clear",
+ text: "clear markers",
+ clicked: false,
+ call_action: function () {
+ wsr.clearRegions();
+ num_regions = -1;
+ },
+ }
+ ];
+}
+
+function linear_map(phase, imn, imx, omn, omx){
+ return (phase - imn) * (omx - omn) / (imx - imn) + omn;
+}
+
+function file_to_server() {
+ //let dictstr = JSON.stringify(global_dict);
+ //fs = new File("media/test.json", dictstr);
+ //fs.writeFile();
+}
+
+//try to abstract this to be one function
+function btn_tp_reset() {
+
+ btn_tp.forEach((button, index) => {
+
+ btn_tp[index].clicked = false;
+ const elem = document.getElementById(button.id);
+
+ if (elem) {
+ elem.classList.remove("clicked");
+ }
+
+ });
+}
+
+//try to abstract this to be one function
+function btn_r_reset() {
+
+ btn_r.forEach((button, index) => {
+
+ btn_r[index].clicked = false;
+ const elem = document.getElementById(button.id);
+
+ if (elem) {
+ elem.classList.remove("clicked");
+ }
+
+ });
+}
+
+function btn_m_reset() {
+ console.log('btn_m_reset() called');
+
+ btn_misc.forEach((button, index) => {
+ btn_misc[index].clicked = false;
+ const elem = document.getElementById(button.id);
+
+ if (elem) {
+ elem.classList.remove("clicked");
+ }
+ });
+}
+
+function buttons_make() {
+
+ const cont_tp = document.getElementById("container_tp");
+ const cont_cue = document.getElementById("container_cue");
+ const cont_misc = document.getElementById("container_misc");
+
+ //transport button area -----------------------------------------------
+ //
+ btn_tp.forEach((button) => {
+ const button_elem = document.createElement("div");
+
+ button_elem.id = button.id;
+ button_elem.classList.add("buttons");
+ button_elem.innerHTML = `<h2>${button.text}</h2>`;
+
+ button_elem.addEventListener("click", () => {
+
+ if (!button.clicked) {
+ btn_tp_reset();
+ button.clicked = true;
+ button.call_action();
+ button_elem.classList.add("clicked");
+ }
+
+ });
+
+ cont_tp.appendChild(button_elem);
+ });
+
+ //cue marker area -----------------------------------------------------
+ btn_r.forEach((button) => {
+
+ const button_elem = document.createElement("div");
+
+ button_elem.id = button.id;
+ button_elem.classList.add("buttons");
+ button_elem.innerHTML = `<h2>${button.text}</h2>`;
+
+ button_elem.addEventListener("click", () => {
+
+ if (!button.clicked) {
+ btn_r_reset();
+ button.clicked = true;
+ button.call_action();
+ button_elem.classList.add("clicked");
+ }
+
+ });
+
+ cont_cue.appendChild(button_elem);
+ });
+
+ //misc button area ----------------------------------------------------
+ //
+
+ btn_misc.forEach((button) => {
+ const button_elem = document.createElement("div");
+
+ button_elem.id = button.id;
+ button_elem.classList.add("buttons");
+ button_elem.innerHTML = `<h2>${button.text}</h2>`;
+
+ button_elem.addEventListener("mousedown", () => {
+ if (!button.clicked) {
+ btn_m_reset();
+ button.clicked = true;
+ button.call_action();
+ button_elem.classList.add("clicked");
+ }
+ });
+ button_elem.addEventListener("mouseup", () => {
+ if (button.clicked) {
+ button.clicked = false;
+ button_elem.classList.remove("clicked");
+ }
+ });
+ cont_misc.appendChild(button_elem);
+ });
+
+}