comparison src/app/waveform/waveform.component.ts @ 180:a1983e30cdd7

WIP - allow for using a provided TimelineTimeContext, and a few other small changes relating to instantiating the Timeline. Comment out some things for trying out single layer without spectrogram.
author Lucas Thompson <dev@lucas.im>
date Wed, 22 Mar 2017 11:17:12 +0000
parents 28cb8530300b
children 376f56200aa1
comparison
equal deleted inserted replaced
179:dadde8a1648c 180:a1983e30cdd7
14 } from "piper/HigherLevelUtilities"; 14 } from "piper/HigherLevelUtilities";
15 import {toSeconds} from "piper"; 15 import {toSeconds} from "piper";
16 import {FeatureList, Feature} from "piper/Feature"; 16 import {FeatureList, Feature} from "piper/Feature";
17 import * as Hammer from 'hammerjs'; 17 import * as Hammer from 'hammerjs';
18 import {WavesSpectrogramLayer} from "../spectrogram/Spectrogram"; 18 import {WavesSpectrogramLayer} from "../spectrogram/Spectrogram";
19 19 import {PartialEventEmitter} from "../notebook-feed/notebook-feed.component";
20 type Timeline = any; // TODO what type actually is it.. start a .d.ts for waves-ui? 20
21 type Layer = any; 21 type Layer = any;
22 type Track = any; 22 type Track = any;
23 type Colour = string; 23 type Colour = string;
24 24
25 @Component({ 25 @Component({
29 }) 29 })
30 export class WaveformComponent implements OnInit, AfterViewInit, OnDestroy { 30 export class WaveformComponent implements OnInit, AfterViewInit, OnDestroy {
31 31
32 @ViewChild('track') trackDiv: ElementRef; 32 @ViewChild('track') trackDiv: ElementRef;
33 33
34 @Input() timeContext: TimelineTimeContext & PartialEventEmitter;
34 private _audioBuffer: AudioBuffer; 35 private _audioBuffer: AudioBuffer;
35 private timeline: Timeline; 36 private timeline: Timeline;
36 private cursorLayer: any; 37 private cursorLayer: any;
37 38
38 @Input() 39 @Input()
39 set audioBuffer(buffer: AudioBuffer) { 40 set audioBuffer(buffer: AudioBuffer) {
40 this._audioBuffer = buffer || undefined; 41 this._audioBuffer = buffer || undefined;
41 if (this.audioBuffer) { 42 if (this.audioBuffer) {
42 this.renderWaveform(this.audioBuffer); 43 this.renderWaveform(this.audioBuffer);
43 this.renderSpectrogram(this.audioBuffer); 44 // this.renderSpectrogram(this.audioBuffer);
44 } 45 }
45 } 46 }
46 47
47 get audioBuffer(): AudioBuffer { 48 get audioBuffer(): AudioBuffer {
48 return this._audioBuffer; 49 return this._audioBuffer;
98 99
99 ngOnInit() { 100 ngOnInit() {
100 } 101 }
101 102
102 ngAfterViewInit(): void { 103 ngAfterViewInit(): void {
103 this.timeline = this.renderTimeline(); 104 this.renderTimeline();
104 } 105 }
105 106
106 renderTimeline(duration: number = 1.0): Timeline { 107 renderTimeline(duration: number = 1.0): Timeline {
107 const track: HTMLElement = this.trackDiv.nativeElement; 108 const track: HTMLElement = this.trackDiv.nativeElement;
108 track.innerHTML = ""; 109 track.innerHTML = "";
109 const height: number = track.getBoundingClientRect().height; 110 const height: number = track.getBoundingClientRect().height;
110 const width: number = track.getBoundingClientRect().width; 111 const width: number = track.getBoundingClientRect().width;
111 const pixelsPerSecond = width / duration; 112 const pixelsPerSecond = width / duration;
112 const timeline = new wavesUI.core.Timeline(pixelsPerSecond, width); 113 if (this.timeline instanceof wavesUI.core.Timeline) {
113 timeline.createTrack(track, height/2, 'wave'); 114 this.timeline.pixelsPerSecond = pixelsPerSecond;
114 timeline.createTrack(track, height/2, 'grid'); 115 this.timeline.visibleWidth = width;
115 return timeline; 116 } else {
117 this.timeline = new wavesUI.core.Timeline(pixelsPerSecond, width);
118 }
119 if (this.timeContext instanceof wavesUI.core.TimelineTimeContext) {
120 console.warn('Has shared timeline');
121 this.timeline.timeContext = this.timeContext;
122 this.timeContext.on('zoom', () => {
123 this.timeline.tracks.update();
124 });
125 this.timeContext.on('offset', () => {
126 this.timeline.tracks.update();
127 });
128 }
129 this.timeline.createTrack(track, height, 'wave');
130 // this.timeline.createTrack(track, height/2, 'wave');
131 // this.timeline.createTrack(track, height/2, 'grid');
116 } 132 }
117 133
118 estimatePercentile(matrix, percentile) { 134 estimatePercentile(matrix, percentile) {
119 // our sample is not evenly distributed across the whole data set: 135 // our sample is not evenly distributed across the whole data set:
120 // it is guaranteed to include at least one sample from every 136 // it is guaranteed to include at least one sample from every
249 } 265 }
250 } 266 }
251 } 267 }
252 268
253 renderWaveform(buffer: AudioBuffer): void { 269 renderWaveform(buffer: AudioBuffer): void {
254 const height: number = this.trackDiv.nativeElement.getBoundingClientRect().height / 2; 270 // const height: number = this.trackDiv.nativeElement.getBoundingClientRect().height / 2;
271 const height: number = this.trackDiv.nativeElement.getBoundingClientRect().height;
255 const waveTrack = this.timeline.getTrackById('wave'); 272 const waveTrack = this.timeline.getTrackById('wave');
256 if (this.timeline) { 273 if (this.timeline) {
257 // resize 274 // resize
258 const width = this.trackDiv.nativeElement.getBoundingClientRect().width; 275 const width = this.trackDiv.nativeElement.getBoundingClientRect().width;
259 276
261 278
262 this.timeline.visibleWidth = width; 279 this.timeline.visibleWidth = width;
263 this.timeline.pixelsPerSecond = width / buffer.duration; 280 this.timeline.pixelsPerSecond = width / buffer.duration;
264 waveTrack.height = height; 281 waveTrack.height = height;
265 } else { 282 } else {
266 this.timeline = this.renderTimeline(buffer.duration) 283 this.renderTimeline(buffer.duration)
267 } 284 }
268 this.timeline.timeContext.offset = 0.5 * this.timeline.timeContext.visibleDuration; 285 this.timeline.timeContext.offset = 0.5 * this.timeline.timeContext.visibleDuration;
269 286
270 // time axis 287 // time axis
271 const timeAxis = new wavesUI.helpers.TimeAxisLayer({ 288 const timeAxis = new wavesUI.helpers.TimeAxisLayer({
585 // this kinda logic should also be tested 602 // this kinda logic should also be tested
586 const mustPageForward = offsetTimestamp > visibleDuration; 603 const mustPageForward = offsetTimestamp > visibleDuration;
587 const mustPageBackward = currentTime < -currentOffset; 604 const mustPageBackward = currentTime < -currentOffset;
588 605
589 if (mustPageForward) { 606 if (mustPageForward) {
607 console.warn('page forward', mustPageForward, offsetTimestamp, visibleDuration);
590 const hasSkippedMultiplePages = offsetTimestamp - visibleDuration > visibleDuration; 608 const hasSkippedMultiplePages = offsetTimestamp - visibleDuration > visibleDuration;
591 609
592 this.timeline.timeContext.offset = hasSkippedMultiplePages ? 610 this.timeline.timeContext.offset = hasSkippedMultiplePages ?
593 -currentTime + 0.5 * visibleDuration : 611 -currentTime + 0.5 * visibleDuration :
594 currentOffset - visibleDuration; 612 currentOffset - visibleDuration;
595 this.timeline.tracks.update(); 613 this.timeline.tracks.update();
614 } else {
615 console.warn('no page', mustPageForward, offsetTimestamp, visibleDuration);
596 } 616 }
597 617
598 if (mustPageBackward) { 618 if (mustPageBackward) {
619 console.warn('page back');
599 const hasSkippedMultiplePages = currentTime + visibleDuration < -currentOffset; 620 const hasSkippedMultiplePages = currentTime + visibleDuration < -currentOffset;
600 this.timeline.timeContext.offset = hasSkippedMultiplePages ? 621 this.timeline.timeContext.offset = hasSkippedMultiplePages ?
601 -currentTime + 0.5 * visibleDuration : 622 -currentTime + 0.5 * visibleDuration :
602 currentOffset + visibleDuration; 623 currentOffset + visibleDuration;
603 this.timeline.tracks.update(); 624 this.timeline.tracks.update();