source: gs3-installations/mars/trunk/sites/mars/collect/amc-essentia/js/av_document.js@ 36963

Last change on this file since 36963 was 36963, checked in by davidb, 17 months ago

AV values now returned for each recommendation as data attributes; function added on calculate min-max range of AV vals

File size: 8.9 KB
Line 
1var AMC_SONG_DURATION = 30;
2
3var currentPosIsZero = true;
4var currentPosRunup = 0;
5
6
7function AVEnsurePaused()
8{
9 if (!wavesurfer.backend.isPaused()) {
10 $('#ws-pause-icon').hide();
11 $('#ws-play-icon' ).show();
12 $('#ws-playpause-label').html("Play");
13 }
14
15 wavesurfer.pause();
16}
17
18function AVPlay()
19{
20 $('#ws-play-icon' ).hide();
21 $('#ws-pause-icon').show();
22 $('#ws-playpause-label').html("Pause");
23
24 if (currentPosRunup>0) {
25 var skip_amount = -1 * currentPosRunup;
26 wavesurfer.skip(skip_amount);
27 currentPosRunup = 0;
28 }
29
30 wavesurfer.play();
31
32}
33
34function AVPlayPause()
35{
36 if (wavesurfer.backend.isPaused()) {
37 AVPlay();
38 }
39 else {
40 AVEnsurePaused();
41 }
42
43 //return wavesurfer.backend.isPaused() ? wavesurfer.play() : wavesurfer.pause();
44}
45
46function AVSeekTo(progressPos)
47{
48 wavesurfer.seekTo(progressPos);
49
50 if (progressPos == 0) {
51 recommendFromStart();
52 }
53}
54
55
56
57/*
58 function playFromOffset(id,frameOffset)
59 {
60 var msecOffset = 250 * frameOffset;
61 idElem = document.getElementById(id);
62 pagePlayer.handleClick({target:idElem}); // fake a click
63 soundManager.stopAll();
64 // soundManager.setPosition(id,5000);
65 soundManager.play(id,{position: msecOffset});
66 }
67 */
68
69function preSubmit(form)
70{
71 // Note, the Arousal and Valence feature window values used is:
72 // 6 secs + 50% overlap
73 // So the Weka computed AV values are spaced out:
74 // 6s, 9s, 12s, ...
75
76 // clamp to ensure >= 6.0 secs
77 var current_time = Math.max(6.0,wavesurfer.getCurrentTime());
78 var current_time_1dp = current_time.toFixed(1);
79 AVEnsurePaused();
80
81 weka_segment = Math.round(current_time/3) * 3;
82 form.elements["s1.offset"].value = weka_segment;
83
84 var arousal_val = parseFloat($('#arousal-val').text());
85 var valence_val = parseFloat($('#valence-val').text());
86
87 $('#makeRecommendationFrom-AV').html(`(@${current_time_1dp} secs: arousal=${arousal_val}, valence=${valence_val})`);
88
89 return submitAVRecommendation(form, arousal_val,valence_val, current_time);
90}
91
92function AVPlotRecommendations()
93{
94 var $av_recommendations = $('.AVRecommendation');
95
96 var min_arousal_val = +1.0;
97 var max_arousal_val = -1.0;
98
99 var min_valence_val = +1.0;
100 var max_valence_val = -1.0;
101
102 $av_recommendations.each(function(index_unused) {
103 var arousal_val = $(this).data("arousalval");
104 var valence_val = $(this).data("valenceval");
105
106 if (arousal_val < min_arousal_val) {
107 min_arousal_val = arousal_val;
108 }
109 if (arousal_val > max_arousal_val) {
110 max_arousal_val = arousal_val;
111 }
112
113
114 if (valence_val < min_valence_val) {
115 min_valence_val = valence_val;
116 }
117 if (valence_val > max_valence_val) {
118 max_valence_val = valence_val;
119 }
120
121 });
122
123 console.log(`AVRecommendations Arousal limits: ${min_arousal_val} <-> ${max_arousal_val}`);
124 console.log(`AVRecommendations Valence limits: ${min_valence_val} <-> ${max_valence_val}`);
125
126}
127
128function submitAVRecommendation(form, arousal_val,valence_val, current_time)
129{
130 form.elements["s1.arousal"].value = arousal_val;
131 form.elements["s1.valence"].value = valence_val;
132
133 var args = {
134 "a": "q",
135 "rt": "rd",
136 "s": "AudioQuery",
137 "sa": "",
138 "c": gs.cgiParams["c"],
139 "q": gs.cgiParams["d"],
140 "s1.query": gs.cgiParams["d"],
141 "s1.maxDocs": form.elements["s1.maxDocs"].value,
142 "s1.hitsPerPage": form.elements["s1.hitsPerPage"].value,
143 "s1.offset": form.elements["s1.offset"].value,
144 "s1.length": form.elements["s1.length"].value,
145 "s1.arousal": arousal_val,
146 "s1.valence": valence_val,
147 "startPage": 1,
148 "excerptid": "resultsArea"
149 };
150
151
152 var url = "https://mars.so-we-must-think.space/greenstone3/library";
153
154 $('#recommendationArea').css("cursor","wait");
155 $('#resultsAreaDiv').slideDown();
156 $('#resultsAreaDiv').html("Retrieving recommendation ...");
157
158 $.ajax({
159 method: "GET",
160 url: url,
161 data: args
162 })
163 .always(function() {
164 $('#recommendationArea').css("cursor","revert");
165 })
166 .fail(function(jqXHR,textStatus) {
167 console.error( "Request failed: " + textStatus);
168 })
169 .done(function(html_result) {
170 $('#resultsAreaDiv').html("<div>Recommendations:</div>"+html_result);
171 $('#av-chart-div').show();
172
173 AVPlotRecommendations();
174
175 if (current_time) {
176 const updated_url = new URL(window.location);
177 updated_url.searchParams.set('p.frameOffset', current_time);
178 //window.history.pushState({}, '', url + "?p.frameOffset=" + current_time);
179 //window.history.pushState({}, '', updated_url);
180 window.history.replaceState({}, '', updated_url);
181 }
182 });
183
184 // stop submit
185 return false;
186
187 // force GET method request to go ahead
188 //return true;
189}
190
191
192
193function recommendFromStart()
194{
195 currentPosIsZero = true;
196 $('#makeRecommendationFrom').html("Based on the start of this musical/sound art work: ");
197}
198
199
200function recommendFromPos()
201{
202 currentPosIsZero = false;
203 $('#makeRecommendationFrom').html("Based on the current timeline position of this musical/sound art work: ");
204}
205
206
207
208function postInitWavesurfer(wavesurfer)
209{
210 console.log("postInitWavesurfer called with wavesufer = " + wavesurfer);
211
212 wavesurfer.load(gs.variables.mp3url);
213
214 wavesurfer.on('audioprocess', function () {
215 var current_time = wavesurfer.getCurrentTime();
216 var current_time_rounded = Math.round(current_time * 10) / 10
217 var current_time_rounded = current_time.toFixed(1);
218 $('#audioCurrentPos').html(current_time_rounded + " secs");
219
220 if (current_time == 0) {
221 recommendFromStart();
222 }
223 else if ((currentPosIsZero) && (current_time > 0)) {
224 recommendFromPos();
225 }
226 });
227
228 wavesurfer.on('ready', function () {
229
230 console.log("**** wavesurfer ready()");
231
232 if ('p_frameOffset' in gs.cgiParams) {
233 var frameOffset = gs.cgiParams['p_frameOffset'];
234 //console.log("**** starting play @ " + frameOffset);
235 //wavesurfer.play(frameOffset);
236 //console.log("**** setting play seek @ " + frameOffset);
237 wavesurfer.seekTo(frameOffset/AMC_SONG_DURATION);
238
239 console.log("av_document.js keeping 'currentPosRunup' at 0");
240 /*if (frameOffset>1.0) {
241 currentPosRunup = 1.0; // 1 second
242 }*/
243 }
244 });
245
246}
247
248/*
249
250y-top: 146
251
252Centre: 412,443
253
254y-bot:735
255
256x-left: 120
257
258x-right 710
259
260
261Full image:
262 911 x 825 pxs
263
264
265
266 AV centre: 412,443
267
268delta x/y: from centre: 292 <-> 298
269-1 <-> 0 <-> +1
270 295 295
271
272
273SVG:
274
275 241 x 248
276 scaled
277 0.26458
278
279*/
280
281var av_chart_orig_r = 295;
282
283var av_chart_orig_x_org = 412;
284var av_chart_orig_y_org = 443;
285
286var av_chart_orig_x_dim = 911;
287var av_chart_orig_y_dim = 825;
288
289var av_chart_disp_x_dim = 300; // ****
290var av_chart_disp_x_mid = av_chart_disp_x_dim/2.0;
291
292var av_chart_scale = av_chart_orig_x_dim / av_chart_disp_x_dim;
293
294function display_to_av_coord(disp_x,disp_y)
295{
296 var scaled_disp_x = disp_x * av_chart_scale;
297 var scaled_disp_y = disp_y * av_chart_scale;
298
299 var orig_av_x = scaled_disp_x - av_chart_orig_x_org;
300 var orig_av_y = -1 * (scaled_disp_y - av_chart_orig_y_org); // flip y axis
301
302 var av_x = orig_av_x / av_chart_orig_r;
303 var av_y = orig_av_y / av_chart_orig_r;
304
305 var capped_av_x = Math.max(Math.min(av_x,1.0),-1.0);
306 var capped_av_y = Math.max(Math.min(av_y,1.0),-1.0);
307
308 return { "x": capped_av_x, "y": capped_av_y };
309}
310
311function av_chart_click(elem,e)
312{
313 var offset = $(elem).offset();
314
315 var elem_x_org = offset.left;
316 var elem_y_org = offset.top;
317
318 var disp_x = e.pageX - elem_x_org;
319 var disp_y = e.pageY - elem_y_org;
320
321 /*
322 var scaled_disp_x = disp_x * av_chart_scale;
323 var scaled_disp_y = disp_y * av_chart_scale;
324
325 var orig_av_x = scaled_disp_x - av_chart_orig_x_org;
326 var orig_av_y = -1 * (scaled_disp_y - av_chart_orig_y_org); // flip y axis
327
328 var av_x = orig_av_x / av_chart_orig_r;
329 var av_y = orig_av_y / av_chart_orig_r;
330
331 var capped_av_x = Math.max(Math.min(av_x,1.0),-1.0);
332 var capped_av_y = Math.max(Math.min(av_y,1.0),-1.0);
333 */
334
335 av_coord = display_to_av_coord(disp_x,disp_y);
336 var capped_av_x = av_coord.x;
337 var capped_av_y = av_coord.y;
338
339 console.log(`av x,y: (${capped_av_x},${capped_av_y})`);
340
341 var form = $('#av-query-form')[0];
342
343 submitAVRecommendation(form, capped_av_x, capped_av_y, null);
344
345}
346
347$(document).ready(function() {
348
349 const doc_url = new URL(window.location);
350 var renderWave = doc_url.searchParams.get('renderWave');
351
352 if (renderWave && (renderWave == 1)) {
353 // showing the waveform => offer link to spectrogram
354 const sts_url = new URL(window.location);
355 sts_url.searchParams.set('renderWave', 0);
356 $('#switch-to-spectrogram').attr("href",sts_url);
357 $('#switch-to-waveform').hide();
358
359 $('#av-timelinebar-help').hide();
360 }
361 else {
362 // show the spectrogram => offer link to waveform
363
364 const stw_url = new URL(window.location);
365 stw_url.searchParams.set('renderWave', 1);
366 $('#switch-to-waveform').attr("href",stw_url);
367 $('#switch-to-spectrogram').hide();
368
369 $('#av-timelinebar-help').show();
370 }
371
372 $('#av-chart-img').on("click",function(e) { av_chart_click(this,e) } );
373});
374
Note: See TracBrowser for help on using the repository browser.