source: gs3-extensions/mars-src/trunk/src/wavesurfer-renderer/drawer.spectrummulticanvas.js@ 37247

Last change on this file since 37247 was 37247, checked in by davidb, 15 months ago

Debug and hard-wired fixes added in for demo to Roger

File size: 24.3 KB
Line 
1import MultiCanvas from './drawer.multicanvas';
2import * as util from './util';
3import CanvasEntry from './drawer.canvasentry';
4
5/**
6 * Calculate FFT - Based on https://github.com/corbanbrook/dsp.js
7 */
8/* eslint-disable complexity, no-redeclare, no-var, one-var */
9const FFT = function(bufferSize, sampleRate, windowFunc, alpha) {
10 this.bufferSize = bufferSize;
11 this.sampleRate = sampleRate;
12 this.bandwidth = (2 / bufferSize) * (sampleRate / 2);
13
14 this.sinTable = new Float32Array(bufferSize);
15 this.cosTable = new Float32Array(bufferSize);
16 this.windowValues = new Float32Array(bufferSize);
17 this.reverseTable = new Uint32Array(bufferSize);
18
19 this.peakBand = 0;
20 this.peak = 0;
21
22 var i;
23 switch (windowFunc) {
24 case 'bartlett':
25 for (i = 0; i < bufferSize; i++) {
26 this.windowValues[i] =
27 (2 / (bufferSize - 1)) *
28 ((bufferSize - 1) / 2 - Math.abs(i - (bufferSize - 1) / 2));
29 }
30 break;
31 case 'bartlettHann':
32 for (i = 0; i < bufferSize; i++) {
33 this.windowValues[i] =
34 0.62 -
35 0.48 * Math.abs(i / (bufferSize - 1) - 0.5) -
36 0.38 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1));
37 }
38 break;
39 case 'blackman':
40 alpha = alpha || 0.16;
41 for (i = 0; i < bufferSize; i++) {
42 this.windowValues[i] =
43 (1 - alpha) / 2 -
44 0.5 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1)) +
45 (alpha / 2) *
46 Math.cos((4 * Math.PI * i) / (bufferSize - 1));
47 }
48 break;
49 case 'cosine':
50 for (i = 0; i < bufferSize; i++) {
51 this.windowValues[i] = Math.cos(
52 (Math.PI * i) / (bufferSize - 1) - Math.PI / 2
53 );
54 }
55 break;
56 case 'gauss':
57 alpha = alpha || 0.25;
58 for (i = 0; i < bufferSize; i++) {
59 this.windowValues[i] = Math.pow(
60 Math.E,
61 -0.5 *
62 Math.pow(
63 (i - (bufferSize - 1) / 2) /
64 ((alpha * (bufferSize - 1)) / 2),
65 2
66 )
67 );
68 }
69 break;
70 case 'hamming':
71 for (i = 0; i < bufferSize; i++) {
72 this.windowValues[i] =
73 0.54 -
74 0.46 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1));
75 }
76 break;
77 case 'hann':
78 case undefined:
79 for (i = 0; i < bufferSize; i++) {
80 this.windowValues[i] =
81 0.5 * (1 - Math.cos((Math.PI * 2 * i) / (bufferSize - 1)));
82 }
83 break;
84 case 'lanczoz':
85 for (i = 0; i < bufferSize; i++) {
86 this.windowValues[i] =
87 Math.sin(Math.PI * ((2 * i) / (bufferSize - 1) - 1)) /
88 (Math.PI * ((2 * i) / (bufferSize - 1) - 1));
89 }
90 break;
91 case 'rectangular':
92 for (i = 0; i < bufferSize; i++) {
93 this.windowValues[i] = 1;
94 }
95 break;
96 case 'triangular':
97 for (i = 0; i < bufferSize; i++) {
98 this.windowValues[i] =
99 (2 / bufferSize) *
100 (bufferSize / 2 - Math.abs(i - (bufferSize - 1) / 2));
101 }
102 break;
103 default:
104 throw Error("No such window function '" + windowFunc + "'");
105 }
106
107 var limit = 1;
108 var bit = bufferSize >> 1;
109 var i;
110
111 while (limit < bufferSize) {
112 for (i = 0; i < limit; i++) {
113 this.reverseTable[i + limit] = this.reverseTable[i] + bit;
114 }
115
116 limit = limit << 1;
117 bit = bit >> 1;
118 }
119
120 for (i = 0; i < bufferSize; i++) {
121 this.sinTable[i] = Math.sin(-Math.PI / i);
122 this.cosTable[i] = Math.cos(-Math.PI / i);
123 }
124
125 this.calculateSpectrum = function(buffer) {
126 // Locally scope variables for speed up
127 var bufferSize = this.bufferSize,
128 cosTable = this.cosTable,
129 sinTable = this.sinTable,
130 reverseTable = this.reverseTable,
131 real = new Float32Array(bufferSize),
132 imag = new Float32Array(bufferSize),
133 bSi = 2 / this.bufferSize,
134 sqrt = Math.sqrt,
135 rval,
136 ival,
137 mag,
138 spectrum = new Float32Array(bufferSize / 2);
139
140 var k = Math.floor(Math.log(bufferSize) / Math.LN2);
141
142 if (Math.pow(2, k) !== bufferSize) {
143 throw 'Invalid buffer size, must be a power of 2.';
144 }
145 if (bufferSize !== buffer.length) {
146 throw 'Supplied buffer is not the same size as defined FFT. FFT Size: ' +
147 bufferSize +
148 ' Buffer Size: ' +
149 buffer.length;
150 }
151
152 var halfSize = 1,
153 phaseShiftStepReal,
154 phaseShiftStepImag,
155 currentPhaseShiftReal,
156 currentPhaseShiftImag,
157 off,
158 tr,
159 ti,
160 tmpReal;
161
162 for (var i = 0; i < bufferSize; i++) {
163 real[i] =
164 buffer[reverseTable[i]] * this.windowValues[reverseTable[i]];
165 imag[i] = 0;
166 }
167
168 while (halfSize < bufferSize) {
169 phaseShiftStepReal = cosTable[halfSize];
170 phaseShiftStepImag = sinTable[halfSize];
171
172 currentPhaseShiftReal = 1;
173 currentPhaseShiftImag = 0;
174
175 for (var fftStep = 0; fftStep < halfSize; fftStep++) {
176 var i = fftStep;
177
178 while (i < bufferSize) {
179 off = i + halfSize;
180 tr =
181 currentPhaseShiftReal * real[off] -
182 currentPhaseShiftImag * imag[off];
183 ti =
184 currentPhaseShiftReal * imag[off] +
185 currentPhaseShiftImag * real[off];
186
187 real[off] = real[i] - tr;
188 imag[off] = imag[i] - ti;
189 real[i] += tr;
190 imag[i] += ti;
191
192 i += halfSize << 1;
193 }
194
195 tmpReal = currentPhaseShiftReal;
196 currentPhaseShiftReal =
197 tmpReal * phaseShiftStepReal -
198 currentPhaseShiftImag * phaseShiftStepImag;
199 currentPhaseShiftImag =
200 tmpReal * phaseShiftStepImag +
201 currentPhaseShiftImag * phaseShiftStepReal;
202 }
203
204 halfSize = halfSize << 1;
205 }
206
207 for (var i = 0, N = bufferSize / 2; i < N; i++) {
208 rval = real[i];
209 ival = imag[i];
210 mag = bSi * sqrt(rval * rval + ival * ival);
211
212 if (mag > this.peak) {
213 this.peakBand = i;
214 this.peak = mag;
215 }
216 spectrum[i] = mag;
217 }
218 return spectrum;
219 };
220};
221/* eslint-enable complexity, no-redeclare, no-var, one-var */
222
223
224/**
225 * Experimental SpectrumMultiCanvas renderer for wavesurfer.
226 *
227 * A `SpectrumMultiCanvas` consists of one or more `CanvasEntry` instances, depending
228 * on the zoom level.
229 */
230export default class SpectrumMultiCanvas extends MultiCanvas {
231 /**
232 * @param {HTMLElement} container The container node of the wavesurfer instance
233 * @param {WavesurferParams} params The wavesurfer initialisation options
234 */
235 constructor(container, params) {
236 super(container, params);
237
238 if (params.colorMap) {
239 if (params.colorMap.length < 256) {
240 throw new Error('Colormap must contain 256 elements');
241 }
242 for (let i = 0; i < params.colorMap.length; i++) {
243 const cmEntry = params.colorMap[i];
244 if ((cmEntry.length !== 4) && (cmEntry.length !== 3)) {
245 throw new Error(
246 'ColorMap entries must contain 3 (rgb) or 4 (rgba) values'
247 );
248 }
249 }
250 this.colorMap = params.colorMap;
251 } else {
252 this.colorMap = [];
253 for (let i = 0; i < 256; i++) {
254 const val = (255 - i) / 256;
255 this.colorMap.push([val, val, val, 1]);
256 }
257 }
258
259 if (params.avDataUrl) {
260 this.avDataUrl = params.avDataUrl;
261 }
262 }
263
264 /**
265 * Initialize the drawer
266 */
267 init() {
268 super.init();
269
270 if (this.avDataUrl) {
271 this.loadFrequenciesData(this.avDataUrl);
272 } else {
273 console.error("No Arousal+Valence (AV) Data URL provided");
274 }
275 }
276
277 normaliseAVVals(vals)
278 {
279 var norm_vals = new Array(vals.length);
280
281 var max_val = 0;
282 for (var i=0; i<vals.length; i++) {
283 var abs_val = Math.abs(vals[i]);
284 if (abs_val > max_val) {
285 max_val = abs_val;
286 }
287 }
288
289 var scale_factor = (max_val < 0.8) ? 0.8 : max_val;
290
291 for (var i=0; i<vals.length; i++) {
292 var val = vals[i];
293 var norm_val = scale_factor * val / max_val;
294 norm_vals[i] = norm_val;
295 }
296
297 return norm_vals;
298 }
299
300 createAVProgressTimelineData(arousal_vals,valence_vals, my)
301 {
302 //console.log("**** createAVProgressTimelineData");
303 var canvas_width = this.canvases[0].wave.width;
304 console.log("**** canvas width = " + canvas_width);
305 console.log("**** width = " + this.width);
306
307 if (canvas_width != 1045) {
308 console.log("!!!! overriding canvas width to be: 1045");
309 canvas_width = 1045;
310 }
311
312 //console.log(" arousal_val = " + JSON.stringify(arousal_vals));
313 //console.log("this.arousal_val = " + JSON.stringify(this.arousal_vals));
314
315 //this.arousal_vals = arousal_vals;
316 //this.valence_vals = valence_vals;
317
318 this.arousal_vals.unshift(0);
319 this.valence_vals.unshift(0);
320
321 this.norm_arousal_vals = this.normaliseAVVals(this.arousal_vals);
322 this.norm_valence_vals = this.normaliseAVVals(this.valence_vals);
323
324 const time_slice = 6; // 6 secs
325 const frame_overlap = 3; // 3 secs
326
327 this.timeline_steps = new Array();
328 this.timeline_steps.unshift(0);
329
330 var num_vals = this.arousal_vals.length;
331 var t = time_slice;
332 var n = 1;
333
334 while (n<num_vals) {
335 this.timeline_steps[n] = t;
336 t += frame_overlap;
337 n++;
338 }
339 const total_duration = t;
340 console.log("*** n = " + n);
341 console.log("*** total duration = " + total_duration);
342
343 this.timeline_steps[n] = total_duration;
344 this.arousal_vals[n] = 0;
345 this.valence_vals[n] = 0;
346 this.norm_arousal_vals[n] = 0;
347 this.norm_valence_vals[n] = 0;
348 num_vals++;
349
350 this.arousal_progress_timeline = new Array();
351 this.valence_progress_timeline = new Array();
352
353 this.norm_arousal_progress_timeline = new Array();
354 this.norm_valence_progress_timeline = new Array();
355
356 for (var i=1; i<num_vals; i++) {
357 const start_t = this.timeline_steps[i-1];
358 const end_t = this.timeline_steps[i];
359 const start_ts = Math.round((start_t / total_duration) * canvas_width);
360 const end_ts = Math.round((end_t / total_duration) * canvas_width);
361
362 const start_arousal = this.arousal_vals[i-1];
363 const start_valence = this.valence_vals[i-1];
364 const end_arousal = this.arousal_vals[i];
365 const end_valence = this.valence_vals[i];
366
367 const norm_start_arousal = this.norm_arousal_vals[i-1];
368 const norm_start_valence = this.norm_valence_vals[i-1];
369 const norm_end_arousal = this.norm_arousal_vals[i];
370 const norm_end_valence = this.norm_valence_vals[i];
371
372 const ts_diff = end_ts - start_ts;
373 const arousal_diff = end_arousal - start_arousal;
374 const valence_diff = end_valence - start_valence;
375 const norm_arousal_diff = norm_end_arousal - norm_start_arousal;
376 const norm_valence_diff = norm_end_valence - norm_start_valence;
377
378 var local_ts = 0;
379 console.log("*** start_ts = " + start_ts + ", end_ts = " + end_ts + " (ts_diff = " + ts_diff +")");
380 console.log("*** start_arousal = " + start_arousal + ", end_arousal = " + end_arousal);
381 console.log("*** norm_start_arousal = " + norm_start_arousal + ", norm_end_arousal = " + norm_end_arousal);
382
383 for (var ts=start_ts; ts<end_ts; ts++) {
384 var local_proportion = local_ts / ts_diff;
385 var interpolated_arousal = start_arousal + (local_proportion * arousal_diff);
386 var interpolated_valence = start_valence + (local_proportion * valence_diff);
387 var norm_interpolated_arousal = norm_start_arousal + (local_proportion * norm_arousal_diff);
388 var norm_interpolated_valence = norm_start_valence + (local_proportion * norm_valence_diff);
389
390 this.arousal_progress_timeline[ts] = interpolated_arousal;
391 this.valence_progress_timeline[ts] = interpolated_valence;
392
393 this.norm_arousal_progress_timeline[ts] = norm_interpolated_arousal;
394 this.norm_valence_progress_timeline[ts] = norm_interpolated_valence;
395
396 local_ts++;
397 }
398 }
399
400 console.log(this.arousal_progress_timeline);
401 //console.log(this);
402 console.log("Generated interpolated AV progress timeline");
403 }
404
405 loadFrequenciesData(url) {
406 //var that = this;
407
408 const request = this.wavesurfer.util.fetchFile({ url: url });
409
410 request.on('success', data => {
411 console.log("loadFrequenceisData: Retrieved AV URL data");
412 console.log(data);
413 //console.log("*** this = ");
414 //console.log(this);
415 //console.log("*** that = ");
416 //console.log(that);
417 //this.arousal_vals = data.arousal.slice(); // **** slice() does array copy
418 //this.valence_vals = data.valence.slice(); // **** slice() does array copy
419
420 // The following two lines use map() to both:
421 // convert the JSON string vals to numbers
422 // generate a fresh array of values (rather than a shared ref) which is what we want
423 this.arousal_vals = data.arousal.map((v) => Number(v));
424 this.valence_vals = data.valence.map((v) => Number(v));
425
426 //this.createAVProgressTimelineData(arousal_vals, valence_vals, this); // **** need to pass in 'this' ??
427 });
428
429 request.on('error', e => this.fireEvent('error', e));
430
431 return request;
432 }
433
434 /**
435 * Update cursor style
436 */
437
438 updateCursor() {
439 if (this.params.renderWave == 1) {
440 super.updateCursor();
441 }
442 else {
443 this.style(this.progressWave, {
444 //borderRightWidth: this.params.cursorSpectrumWidth + 'px',
445 //borderRightColor: this.params.cursorSpectrumColor
446 borderRightWidth: '4px',
447 borderRightColor: 'rgba(255,255,255,0.3)'
448 });
449 }
450 }
451
452
453
454 drawPeaks(peaks, length, start, end) {
455 if (this.params.renderWave == 1) {
456 super.drawPeaks(peaks,length,start,end);
457 if ($( "#av-display" ).length) {
458 $( "#av-display" ).show();
459 }
460 //this.createAVProgressTimelineData(this.arousal_vals, this.valence_vals, this); // **** need to pass in 'this' ??
461 }
462 else {
463 if (!this.setWidth(length)) {
464 this.clearWave();
465 }
466
467 this.getFrequencies(this.drawSpectrogram);
468 }
469 }
470
471 resample(oldMatrix) {
472 const columnsNumber = this.width;
473 const newMatrix = [];
474
475 const oldPiece = 1 / oldMatrix.length;
476 const newPiece = 1 / columnsNumber;
477 let i;
478
479 for (i = 0; i < columnsNumber; i++) {
480 const column = new Array(oldMatrix[0].length);
481 let j;
482
483 for (j = 0; j < oldMatrix.length; j++) {
484 const oldStart = j * oldPiece;
485 const oldEnd = oldStart + oldPiece;
486 const newStart = i * newPiece;
487 const newEnd = newStart + newPiece;
488
489 const overlap =
490 oldEnd <= newStart || newEnd <= oldStart
491 ? 0
492 : Math.min(
493 Math.max(oldEnd, newStart),
494 Math.max(newEnd, oldStart)
495 ) -
496 Math.max(
497 Math.min(oldEnd, newStart),
498 Math.min(newEnd, oldStart)
499 );
500 let k;
501 /* eslint-disable max-depth */
502 if (overlap > 0) {
503 for (k = 0; k < oldMatrix[0].length; k++) {
504 if (column[k] == null) {
505 column[k] = 0;
506 }
507 column[k] += (overlap / newPiece) * oldMatrix[j][k];
508 }
509 }
510 /* eslint-enable max-depth */
511 }
512
513 const intColumn = new Uint8Array(oldMatrix[0].length);
514 let m;
515
516 for (m = 0; m < oldMatrix[0].length; m++) {
517 intColumn[m] = column[m];
518 }
519
520 newMatrix.push(intColumn);
521 }
522
523 return newMatrix;
524 }
525
526 drawSpectrogram(frequenciesData, my) {
527 console.log("*** spectrummultican as::drawSpectrum() spec ....spec.length = " + frequenciesData.length)
528 console.log(frequenciesData);
529 //const spectrCc = my.spectrCc;
530 //const length = my.wavesurfer.backend.getDuration();
531 //const height = my.height;
532 //const pixels = my.resample(frequenciesData);
533 //const heightFactor = my.buffer ? 2 / my.buffer.numberOfChannels : 1;
534
535 const canvas = my.canvases[0].wave;
536 const spectrCc = canvas.getContext('2d');
537 const length = my.wavesurfer.backend.getDuration();
538 const height = canvas.height;
539 const pixels = my.resample(frequenciesData);
540 const heightFactor = my.buffer ? 2 / my.buffer.numberOfChannels : 1;
541
542 // now double it!
543 const scaledHeightFactor = heightFactor * 2;
544
545
546 let i;
547 let j;
548
549 for (i = 0; i < pixels.length; i++) {
550 for (j = 0; j < pixels[i].length; j++) {
551 const colorMap = my.colorMap[pixels[i][j]]; // ****
552 if (colorMap.length == 4) {
553 //my.spectrCc.fillStyle =
554 spectrCc.fillStyle =
555 'rgba(' +
556 colorMap[0] * 256 +
557 ', ' +
558 colorMap[1] * 256 +
559 ', ' +
560 colorMap[2] * 256 +
561 ',' +
562 colorMap[3] +
563 ')';
564 }
565 else {
566 //my.spectrCc.fillStyle =
567 spectrCc.fillStyle =
568 'rgb(' +
569 colorMap[0] * 256 +
570 ', ' +
571 colorMap[1] * 256 +
572 ', ' +
573 colorMap[2] * 256 +
574 ')';
575 }
576
577 //my.spectrCc.fillRect(
578 spectrCc.fillRect(
579 i,
580 height - j * scaledHeightFactor,
581 1,
582 scaledHeightFactor
583 );
584 }
585 }
586
587 my.createAVProgressTimelineData(my.arousal_vals, my.valence_vals, my); // **** need to pass in 'this' ??
588 }
589
590 getFrequencies(callback) {
591 const fftSamples = this.fftSamples || 512;
592 const buffer = (this.buffer = this.wavesurfer.backend.buffer);
593 if (buffer == null) return; // **** GS3 edit
594 const channelOne = buffer.getChannelData(0);
595 const bufferLength = buffer.length;
596 const sampleRate = buffer.sampleRate;
597 const frequencies = [];
598
599 if (!buffer) {
600 this.fireEvent('error', 'Web Audio buffer is not available');
601 return;
602 }
603
604 let noverlap = this.noverlap;
605 if (!noverlap) {
606 const uniqueSamplesPerPx = buffer.length / this.canvases[0].wave.width; // **** GS3 edit
607 noverlap = Math.max(0, Math.round(fftSamples - uniqueSamplesPerPx));
608 }
609
610 const fft = new FFT(
611 fftSamples,
612 sampleRate,
613 this.windowFunc,
614 this.alpha
615 );
616 const maxSlicesCount = Math.floor(
617 bufferLength / (fftSamples - noverlap)
618 );
619 let currentOffset = 0;
620
621 while (currentOffset + fftSamples < channelOne.length) {
622 const segment = channelOne.slice(
623 currentOffset,
624 currentOffset + fftSamples
625 );
626 const spectrum = fft.calculateSpectrum(segment);
627 const array = new Uint8Array(fftSamples / 2);
628 let j;
629 for (j = 0; j < fftSamples / 2; j++) {
630 array[j] = Math.max(-255, Math.log10(spectrum[j]) * 45);
631 }
632 frequencies.push(array);
633 currentOffset += fftSamples - noverlap;
634 }
635 callback(frequencies, this);
636 }
637
638
639 /**
640 * Draw a rectangle on the multi-canvas
641 *
642 * @param {number} x X-position of the rectangle
643 * @param {number} y Y-position of the rectangle
644 * @param {number} width Width of the rectangle
645 * @param {number} height Height of the rectangle
646 * @param {number} radius Radius of the rectangle
647 */
648 /*
649 fillRect(x, y, width, height, radius) {
650 const startCanvas = Math.floor(x / this.maxCanvasWidth);
651 const endCanvas = Math.min(
652 Math.ceil((x + width) / this.maxCanvasWidth) + 1,
653 this.canvases.length
654 );
655 let i = startCanvas;
656 for (i; i < endCanvas; i++) {
657 const entry = this.canvases[i];
658 const leftOffset = i * this.maxCanvasWidth;
659
660 const intersection = {
661 x1: Math.max(x, i * this.maxCanvasWidth),
662 y1: y,
663 x2: Math.min(
664 x + width,
665 i * this.maxCanvasWidth + entry.wave.width
666 ),
667 y2: y + height
668 };
669
670 if (intersection.x1 < intersection.x2) {
671 this.setFillStyles(entry);
672
673 entry.fillRects(
674 intersection.x1 - leftOffset,
675 intersection.y1,
676 intersection.x2 - intersection.x1,
677 intersection.y2 - intersection.y1,
678 radius
679 );
680 }
681 }
682 }
683 */
684
685
686 /**
687 * Render the new progress
688 *
689 * @param {number} position X-offset of progress position in pixels
690 */
691 /*
692 updateProgress(position) {
693 this.style(this.progressWave, { width: position + 'px' });
694 }
695 */
696
697 /**
698 * Render the new progress
699 *
700 * @param {number} position X-offset of progress position in pixels
701 */
702 updateProgress(position) {
703
704 if (!this.arousal_progress_timeline) {
705 this.createAVProgressTimelineData(this.arousal_vals, this.valence_vals, this); // **** need to pass in 'this' ??
706 }
707
708 var pixel_ratio = this.params.pixelRatio
709 var floor_position = Math.floor(position);
710 //var scaled_floor_position = Math.floor(position * pixel_ratio);
711 console.log("position = " + position);
712 //console.log("scaled_floor_position = " + scaled_floor_position);
713
714 var canvas_width = this.canvases[0].wave.width;
715 console.log("updateProgress(): canvas_width = " + canvas_width + " (not currently used in this fn)");
716
717 if (this.params.renderWave == 1) {
718 super.updateProgress(position);
719 }
720 else {
721
722 //var scaled_canvas_width = canvas_width * pixel_ratio;
723
724 // ****
725 //console.log("position = " + position + "/" + canvas_width);
726 //console.log(this);
727
728 var norm_arousal_val = this.norm_arousal_progress_timeline[floor_position];
729 var norm_valence_val = this.norm_valence_progress_timeline[floor_position];
730
731 // ****
732 //console.log("floor_position = " + floor_position + ", arousal = " + arousal_val + ", valence = " + valence_val);
733
734 // shift [-1,1] scale
735 /*
736 var css_norm_valence_alpha = 0.5 + (norm_arousal_val + 1.0)/4.0;
737 var css_norm_arousal_width = (norm_valence_val + 1.0) * 20;
738
739 this.style(this.progressWave, {
740 borderRightWidth: css_norm_arousal_width+'px',
741 borderRightColor: 'rgba(255,255,255,'+css_norm_valence_alpha+')'
742 });
743*/
744
745
746 var css_norm_arousal_alpha = 0.5 + (norm_arousal_val + 1.0)/4.0;
747 var css_norm_valence_width = (norm_valence_val + 1.0) * 20;
748
749 this.style(this.progressWave, {
750 borderRightWidth: css_norm_valence_width+'px',
751 borderRightColor: 'rgba(255,255,255,'+css_norm_arousal_alpha+')'
752 });
753
754 super.updateProgress(position);
755 }
756
757 var arousal_val = this.arousal_progress_timeline[floor_position];
758 var valence_val = this.valence_progress_timeline[floor_position];
759
760 console.log("*** arousal_val [" + floor_position + "]" + " = " + arousal_val);
761
762 var arousal_val_3dp = Math.round(arousal_val*1000)/1000;
763 var valence_val_3dp = Math.round(valence_val*1000)/1000;
764
765 if (arousal_val_3dp >= 0) {
766 arousal_val_3dp = "&nbsp;" + arousal_val_3dp;
767 }
768
769 if (valence_val_3dp >= 0) {
770 valence_val_3dp = "&nbsp;" + valence_val_3dp;
771 }
772
773 if ($('#arousal-val').length) {
774 $('#arousal-val').html(arousal_val_3dp);
775 }
776 if ($('#valence-val').length) {
777 $('#valence-val').html(valence_val_3dp);
778 }
779
780 }
781
782}
Note: See TracBrowser for help on using the repository browser.