]> git.dabkitsch.com - m29-web-sfp.git/commitdiff
successfully added lane tracking with region generation, proper ids, etc.
authorequilet <2237372+equilet@users.noreply.github.com>
Tue, 8 Apr 2025 09:18:44 +0000 (02:18 -0700)
committerequilet <2237372+equilet@users.noreply.github.com>
Tue, 8 Apr 2025 09:18:44 +0000 (02:18 -0700)
app.js
index.html
style/style.css

diff --git a/app.js b/app.js
index 8ccfaa3321df46645ee63f00da71e2b672a2aff3..0e7ddb3b5335313c13739b4fdec0e5d3c457f3bd 100644 (file)
--- a/app.js
+++ b/app.js
@@ -8,17 +8,26 @@ let text_input, text_butt, timevalues;
 let btn_r = [];
 let btn_tp = [];
 let btn_misc = [];
-let ws;
-let wsr;
+let ws, wsr;
 let sep_window;
 let looping, in_region;
 
+//index 0: wavesurfer instances
+//index 1: ws regions
+//index 2: region count per lane
+let wsr_lanes = Array.from({ length: 3 }, () => Array(3).fill(0)); //multi-dim array for extra region lanes
+const numlanes = wsr_lanes[0].length;
+
 //initialization---------------------------------------------------------------------
 //
 
 const setup = async() => {
     initialize();
     buttons_make();
+
+    for(let i = 0; i < numlanes; i++){
+        wsr_lanes[2][i] = 2;
+    }
 }
 
 //main routine-----------------------------------------------------------------------
@@ -83,7 +92,7 @@ function linear_map(phase, imn, imx, omn, omx) {
     return (phase - imn) * (omx - omn) / (imx - imn) + omn;
 }
 
-function add_region_specified(tstart, tend, ttext, id, tcolor) {
+function region_add_specified(tstart, tend, ttext, id, tcolor) {
 
     num_regions++;
 
@@ -100,36 +109,42 @@ function add_region_specified(tstart, tend, ttext, id, tcolor) {
 
 }
 
-function add_1_region() {
+function region_add_1(lane_id) {
 
-    const gen = gen_region_startend();
-    num_regions++;
-    //console.log("adding a region with id", num_regions);
+    if(lane_id > 2 | lane_id < 0){
+        console.error("lane id is out of bounds.  Aborting...");
+        return;
+    }
 
-    wsr.addRegion({
-        channelIdx: num_regions, 
-        content: "region" + (num_regions - 1) + "text",
-        id: 'region',
-        start: gen[0], 
-        end: gen[1], 
-        loop: false, 
-        color: 'hsla(184, 32%, 72%, 0.1)'
-    });
+    const gen = gen_region_startend();
+    //let nreg = wsr_lanes[2][lane_id];
+    console.log("lane id: ", lane_id);
+    console.log("wsr value: ", wsr_lanes[2][lane_id]);
 
+        wsr_lanes[1][lane_id].addRegion({
+            channelIdx: wsr_lanes[2][lane_id], 
+            content: "lane: " + lane_id + "inc: " + wsr_lanes[2][lane_id], 
+            id: 'region',
+            start: gen[0], 
+            end: gen[1], 
+            loop: false, 
+            color: 'hsla(184, 32%, 72%, 0.1)'
+        });
+    //increment the lane region counter
+    wsr_lanes[2][lane_id]++;
 }
 
 function gen_color() {
     return Math.floor(Math.random() * 100.0);
 }
 
-function add_3_regions() {
+function region_add_3() {
     //let percent_hue = new Number();
-    for(let i = 1; i < 4; i++){
+    for(let i = 1; i < 4; i++) {
 
         const gen = gen_region_startend();
         num_regions++;
         //percent_hue = Math.floor(Math.random() * 100.0);
-
         //console.log("adding a region with id", num_regions);
         wsr.addRegion({
             channelIdx: num_regions,
@@ -141,31 +156,48 @@ function add_3_regions() {
            // color: 'hsla(' + percent_hue + '%, 100%, 50%, 0.1)'
             color: 'hsla(' + gen_color() + ', 100%, 50%, 0.1)'
         });
-
     }
 }
 
-function add_region_at_time(time){
+function region_add_at_time(time){
     num_regions++;
     //const percent_lum = Math.random() * 100.0;
     let percent_hue = Math.floor(Math.random() * 100.0);
-    const test_string = 'hsla(' + percent_hue + ', 100%, 50%, 0.1)';
+    const color_str = 'hsla(' + percent_hue + ', 100%, 50%, 0.1)';
 
     //console.log("adding a region with id", num_regions);
 
     wsr.addRegion({
         channelIdx: num_regions, 
-        content: "region" + (num_regions - 1) + "text",
+        content: "region " + (num_regions - 1) + " text",
         //id: "cue " + i, 
         id: 'region',
         start: time, 
         end: time + global_dur, 
         loop: false, 
-        color: test_string
+        color: color_str
         //color: 'hsla(' + percent_hue + '%, 100%, 50%, 0.1)'
     });
 }
 
+//add a region via a lane
+function region_add_in_lane(id, time){
+    num_regions++;
+    let percent_hue = Math.floor(Math.random() * 100.0);
+    const color_str = 'hsla(' + percent_hue + ', 100%, 50%, 0.1)';
+
+    //2nd index is region instance
+    wsr_lanes[1][id].addRegion({
+        channelIdx: num_regions, 
+        content: "region" + (num_regions - 1) + "text",
+        id: 'region', 
+        start: time, 
+        end: time + global_dur, 
+        loop: false,
+        color: color_str
+    });
+}
+
 function gen_region_startend(){
     const dur = ws.getDuration();
     const pad = 0.2;
@@ -179,12 +211,19 @@ function gen_region_startend(){
 function clear_regions() {
     wsr.clearRegions();
     num_regions = 1;
+
+    for(let i = 0; i < wsr_lanes[0].length; i++){
+        wsr_lanes[1][i].clearRegions();
+        wsr_lanes[2][i] = 2;
+    }
+
+    active_region = null;
 }
 
 function buttons_reset() {
-        btn_tp_reset();
-        btn_r_reset();
-        btn_m_reset();
+    btn_tp_reset();
+    btn_r_reset();
+    btn_m_reset();
 }
 
 function region_view_reset(){
@@ -248,7 +287,7 @@ function json_load(json) {
         tcolor = json[key].color;
 
         //tstart, tend, text, id, tcolor
-        add_region_specified(tregion[0], tregion[1], ttext, tid, tcolor);
+        region_add_specified(tregion[0], tregion[1], ttext, tid, tcolor);
         //console.log("key: ", key, 'value: ', global_dict[key]);
     }
 }
@@ -328,9 +367,8 @@ function localstorage_restore() {
 
     console.log("ls restore: reading localStorage...");
 
-    num_regions = 1;
     let inc = 0;
-    clear_regions();
+    clear_regions(); //sets num_regions to 1
 
     for(var key in localStorage) {
         let data = localStorage.getItem(key);
@@ -347,21 +385,23 @@ function localstorage_restore() {
 //Initialization
 
 function audio_load(a_path) {
-
+    
     ws = WaveSurfer.create({
-        container: '#waveform',
+        container: '#wsurfer',
         progressColor: 'rgb(150,150,150)',
         waveColor: 'rgb(200,200,200)',
         url: a_path
     });
 
-    wsr = ws.registerPlugin(WaveSurfer.Regions.create())
+    wsr = ws.registerPlugin(WaveSurfer.Regions.create());
 
-    const wf = document.getElementById("waveform");
+    
+    const wf = document.getElementById("wf-status");
     //append a div for the display of percentage loaded
     const percent_elem = document.createElement("div");
     percent_elem.id = "percent";
     percent_elem.align = "center";
+
     wf.appendChild(percent_elem);
 
     ws.on('ready', function (){
@@ -451,6 +491,23 @@ function audio_load(a_path) {
         text_update("<no region active>");
     });
 
+    //lane propagation (extra regions) ---------------------------------------------------
+    //
+
+    for(let i = 0; i < wsr_lanes[0].length; i++) {
+        //wavesurfer instances
+        wsr_lanes[0][i] = WaveSurfer.create({
+            container: '#lane-' + (i + 1), 
+            progressColor: 'rgb(150,150,150)',
+            waveColor: 'rgba(0,0,0,0.001)',
+            url: a_path
+        });
+        //regions instances
+        wsr_lanes[1][i] = wsr_lanes[0][i].registerPlugin(WaveSurfer.Regions.create());
+    }
+
+    //---------------------------------------------------
+
     /*
     wsr.on('region-out', (region, e) => {
         //console.log("region-out detected from" + region.channelIdx + "...  try to implement a loop function here");
@@ -475,20 +532,76 @@ function initialize() {
     active_region = null;
     in_region = false;
 
+    const wf = document.getElementById("wsurfer");
 
-    //keyboard events -----------------------------------------------------------
-    //
+    wf.addEventListener("mouseenter", (e) => {
+        console.log("mouse in detected on wf: ", e);
+    });
 
+    /*
+    wf.addEventListener("mouseleave", (e) => {
+        console.log("mouse leave detected on wf: ", e);
+    });
+    */
+
+    let temps = new Array(numlanes);
+
+    for(let i=0; i < numlanes; i++) { 
+        temps[i] = document.getElementById("wsurfer");
+
+        //lane detection
+        temps[i].addEventListener("mouseenter", (e) => {
+            console.log("mouse in detected on temp lane..." + i, e);
+        });
+    }
+
+    //keyboard events -----------------------------------------------------------
+    
+    //add test regions in every lane using the 'r' key
     window.addEventListener("keydown", (e) => {
         if(e.target.nodeName == "TEXTAREA") {
             //do nothing; accept input as normal
         } else {
+            //marker
+            if(!e.repeat) {
+                const time = ws.getCurrentTime();
+                switch(e.key) {
+                    case '1':
+                        //region_add_in_lane(0, time);
+                        //region_add_at_time(time); // <-- this is the first lane; should be changed
+                        region_add_in_lane(0, time);
+                        break;
+                    case '2':
+                        region_add_in_lane(1, time);
+                        break;
+                    case '3':
+                        region_add_in_lane(2, time);
+                        break;
+                    case '4':
+                        region_add_in_lane(3, time);
+                        break;
+                } 
+            }
+
             //marker
             if(!e.repeat && e.key == 'r') {
-                add_region_at_time(ws.getCurrentTime());
+
+                const time = ws.getCurrentTime();
+                region_add_at_time(time);
+
+                for(let i = 0; i < wsr_lanes[0].length; i++){
+                    region_add_in_lane(i, time);
+                }
+
                 return;
             } 
 
+            //testing the return key
+            if(!e.repeat && e.key == 'RETURN') {
+                console.log("the return key was pressed...\n");
+                return;
+            }
+
             //this needs to be cleaned up w/r/t detection of cases....
             //transport
             if(!e.repeat && e.key == ' ') {
@@ -500,6 +613,12 @@ function initialize() {
                 }
                 return;
             }
+            //focus textarea
+            if(!e.repeat && e.key == 'e') {
+                e.preventDefault();
+                text_input.focus();        
+                return;
+            }
             if(!e.repeat && e.key == 'ArrowLeft') {
                 if(!in_region) {
                     ws.skip(-skip_factor);
@@ -512,19 +631,13 @@ function initialize() {
                 }
                 return;
             }
-            //focus textarea
-            if(!e.repeat && e.key == 'e') {
-                e.preventDefault();
-                text_input.focus();        
-                return;
-            }
         }
     });
 
     //json file loading mechanism
     document.getElementById('file_input_json').addEventListener('change', function(ev) {
         const file = ev.target.files[0];
-        console.log('attempting to load JSON: ', file);
+        //console.log('attempting to load JSON: ', file);
         if(file) {
             const reader = new FileReader();
             reader.onload = function(e) {
@@ -548,7 +661,7 @@ function initialize() {
     document.getElementById('file_input_audio').addEventListener('change', function(ev) {
 
         const file = ev.target.files[0];
-        console.log('attempting to load audio: ', file);
+        //console.log('attempting to load audio: ', file);
 
         if(file) {
             const file_info = `
@@ -583,76 +696,6 @@ function initialize() {
     const brk = "\n -------------";
     const ed_cr = brk + brk + brk + "\n";
     
-    global_dict = {
-        "r2": {
-            "region": [0.07652782486802312, 1.464475134610756],
-            "text": "gesture A1\n -------------\n -------------\n -------------\nNotice how the gesture rises in pitch",
-            "id": 2,
-            "color": "hsla(0, 100%, 50%, 0.1)"
-        },
-        "r3": {
-            "region": [1.8692600113275684, 3.195274968850553],
-            "text": "gesture A2",
-            "id": 3,
-            "color": "hsla(20, 100%, 50%, 0.1)"
-        },
-        "r4": {
-            "region": [3.6112875615251694, 5.12028059605844],
-            "text": "gesture A3\n -------------\n -------------\n -------------\neach repeat of gesture A is slightly varied in duration and energy",
-            "id": 4,
-            "color": "hsla(40, 100%, 50%, 0.1)"
-        },
-        "r5": {
-            "region": [5.354219, 6.6800804962279035],
-            "text": "gesture A4",
-            "id": 5,
-            "color": "hsla(60, 100%, 50%, 0.1)"
-        },
-        "r6": {
-            "region": [7.11208, 8.456021562101203],
-            "text": "gesture A5",
-            "id": 6,
-            "color": "hsla(80, 100%, 50%, 0.1)"
-        },
-        "r7": {
-            "region": [8.869941, 10.167390964141314],
-            "text": "gesture A6",
-            "id": 7,
-            "color": "hsla(100, 100%, 50%, 0.1)"
-        },
-        "r8": {
-            "region": [10.547167, 11.990076448815238],
-            "text": "gesture A7",
-            "id": 8,
-            "color": "hsla(120, 100%, 50%, 0.1)"
-        },
-        "r9": {
-            "region": [12.288901, 13.583264123626352],
-            "text": "gesture A8",
-            "id": 9,
-            "color": "hsla(140, 100%, 50%, 0.1)"
-        },
-        "r10": {
-            "region": [13.966126, 21.307924676142115],
-            "text": "gesture B: New long phrase B.  Notice how the performer softens the energy and allows the closing of the 12-bar cycle",
-            "id": 10,
-            "color": "hsla(180, 100%, 50%, 0.1)"
-        }
-    }
-
-        /*
-        //"soundfile" : filepath,
-        //<start> <end> <textstring> <id> <colorstr>
-        "r0" : [0.07652782486802312, 1.464475134610756, "gesture A1" + ed_cr + "Notice how the gesture rises in pitch", 2, "hsla(0, 100%, 50%, 0.1)"], 
-        "r1" : [1.8692600113275684, 3.195274968850553, "gesture A2", 3, "hsla(20, 100%, 50%, 0.1)"], 
-        "r2" : [3.6112875615251694, 5.12028059605844, "gesture A3" + ed_cr + "each repeat of gesture A is slightly varied in duration and energy", 4, "hsla(40, 100%, 50%, 0.1)"],
-        "r3" : [5.354219, 6.6800804962279035, "gesture A4", 5, "hsla(60, 100%, 50%, 0.1)"], 
-        "r4" : [7.11208, 8.456021562101203, "gesture A5", 6, "hsla(80, 100%, 50%, 0.1)"],
-        "r5" : [8.869941, 10.167390964141314, "gesture A6", 7, "hsla(100, 100%, 50%, 0.1)"],
-        "r6" : [10.547167, 11.990076448815238, "gesture A7", 8, "hsla(120, 100%, 50%, 0.1)"],
-        "r7" : [12.288901, 13.583264123626352, "gesture A8", 9, "hsla(140, 100%, 50%, 0.1)"],
-        "r8" : [13.966126, 21.307924676142115, "gesture B: New long phrase B.  Notice how the performer softens the energy and allows the closing of the 12-bar cycle", 10, "hsla(180, 100%, 50%, 0.1)"]
-        */
 
     //interface data--------------------------------------------------------------
     //
@@ -746,31 +789,25 @@ function initialize() {
             text: "generate regions",
             clicked: false,
             call_action: function () {
-                add_3_regions();
+                region_add_3();
             },
         }, 
         {
-            id: "gen1", 
-            text: "generate 1 region", 
+            id: "genl1", 
+            text: "genlane1", 
             clicked: false, 
             call_action: function () {
-                add_1_region();
+                region_add_1(0);
             }
         }, 
-        /*
         {
-            id: "load", 
-            text: "load default data",
-            clicked: false,
+            id: "genl2", 
+            text: "genlane2", 
+            clicked: false, 
             call_action: function () {
-                console.log('currently unimplemented');
-                //const default_path_audio = "media/Music29_Little_Walter_Blues.wav";
-                //const default_path_json = "media/initdata.json";
-                //audio_load(default_path_audio);
-                //json_load(default_path_json);
+                region_add_1(1);
             }
-        },
-        */
+        }, 
         {
             id: "loadfile",
             text: "load JSON file", 
index 560268e39ee43a51dcd3bd634924f85e37f3c12f..09b869d688673697e3661d1b552d1b6ff877537b 100644 (file)
                </div>
 
         <div id="waveform">
+            <div id="wsurfer"></div>
+            <div id="wf-status"></div>
         </div>
+        <div id="lane-1"></div>
+        <div id="lane-2"></div>
+        <div id="lane-3"></div>
 
         <div id="marker_edit">
             <h2>Edit Marker</h2>
index 5782e48b4111c3b8a8f5e1f628dea245b9aabb1c..d797cc9bd4cfaca3d2fa97ea421614f66515d37e 100644 (file)
@@ -16,31 +16,38 @@ body {
     /* max-width: 940px; */
 }
 
-#waveform {
+/* wavesurfer */
+
+#wsurfer, #lane-1, #lane-2, #lane-3 {
     /* padding: 25px; */
-    height: 128px; 
+    margin: 10px;
+    height: 120px;
+    background-color: rgba(115,115,115,0.05);
 }
 
-#waveform ::part(wrapper) {
-    /* height: 350px; */
+#wsurfer:hover, #lane-1:hover, #lane-2:hover, #lane-3:hover {
+    background-color: rgba(0,0,115,0.05);
 }
 
-#waveform ::part(region-content) {
-    overflow-wrap: break-all;
+#wsurfer ::part(region-content) {
+    overflow-wrap: break-word;
 }
 
-#waveform ::part(region) {
+#wsurfer, #lane-1, #lane-2, #lane-3 ::part(region) {
     font-family: "Roboto Condensed", sans-serif;
     font-weight: 400;
     font-style: normal;
-    height: 100%;
+    /* height: 100%; */
 }
 
-#droparea { 
-    border: 5px solid blue;
-    width: 100%;
-    height: 100px;
+/*
+#lane-1, #lane-2, #lane-3 ::part(region) {
+    font-family: "Roboto Condensed", sans-serif;
+    font-weight: 400;
+    font-style: normal;
+    height: 100%; 
 }
+*/
 
 h1, h2, h3, p {
     font-family: "Roboto Condensed", sans-serif;