dev@10
|
1 import {
|
dev@10
|
2 Component, OnInit, ViewChild, ElementRef,
|
dev@16
|
3 AfterViewInit, OnChanges, SimpleChanges, Input
|
dev@10
|
4 } from '@angular/core';
|
dev@8
|
5
|
dev@16
|
6 declare var wavesUI: any; // TODO non-global app scope import
|
dev@6
|
7
|
dev@6
|
8 @Component({
|
dev@6
|
9 selector: 'app-waveform',
|
dev@6
|
10 templateUrl: './waveform.component.html',
|
dev@6
|
11 styleUrls: ['./waveform.component.css']
|
dev@6
|
12 })
|
dev@16
|
13 export class WaveformComponent implements OnInit, AfterViewInit, OnChanges {
|
dev@8
|
14 @ViewChild('track') trackDiv: ElementRef;
|
dev@6
|
15
|
dev@16
|
16 private _audioBuffer: AudioBuffer = undefined;
|
dev@16
|
17
|
dev@16
|
18 @Input()
|
dev@16
|
19 set audioBuffer(buffer: AudioBuffer) {
|
dev@16
|
20 this._audioBuffer = buffer || undefined;
|
dev@16
|
21 }
|
dev@16
|
22
|
dev@16
|
23 get audioBuffer(): AudioBuffer {
|
dev@16
|
24 return this._audioBuffer;
|
dev@16
|
25 }
|
dev@16
|
26
|
dev@16
|
27
|
dev@16
|
28
|
dev@16
|
29 private timeline: any; // TODO what type is it?
|
dev@16
|
30
|
dev@6
|
31 constructor() {
|
dev@6
|
32 }
|
dev@6
|
33
|
dev@10
|
34 ngOnInit() {}
|
dev@10
|
35
|
dev@10
|
36 ngAfterViewInit(): void {
|
dev@18
|
37 const track: HTMLElement = this.trackDiv.nativeElement;
|
dev@18
|
38 const duration: number = 1.0;
|
dev@18
|
39 const height: number = track.getBoundingClientRect().height;
|
dev@18
|
40 const width: number = track.getBoundingClientRect().width;
|
dev@18
|
41 const pixelsPerSecond = width / duration;
|
dev@18
|
42 const timeline = new wavesUI.core.Timeline(pixelsPerSecond, width);
|
dev@18
|
43 timeline.createTrack(track, height, 'main');
|
dev@18
|
44
|
dev@18
|
45 // time axis
|
dev@18
|
46 const timeAxis = new wavesUI.helpers.TimeAxisLayer({
|
dev@18
|
47 height: height,
|
dev@18
|
48 top: 10,
|
dev@18
|
49 color: 'gray'
|
dev@18
|
50 });
|
dev@18
|
51
|
dev@18
|
52 timeline.addLayer(timeAxis, 'main', 'default', true);
|
dev@18
|
53 timeline.state = new wavesUI.states.CenteredZoomState(timeline);
|
dev@16
|
54 }
|
dev@16
|
55
|
dev@16
|
56 ngOnChanges(changes: SimpleChanges): void {
|
dev@16
|
57 if (changes.hasOwnProperty("audioBuffer")) { // why wouldn't it?
|
dev@16
|
58 if (changes["audioBuffer"].currentValue)
|
dev@16
|
59 this.renderWaveform(changes["audioBuffer"].currentValue);
|
dev@16
|
60 }
|
dev@16
|
61 }
|
dev@16
|
62
|
dev@16
|
63 renderWaveform(buffer: AudioBuffer) {
|
dev@16
|
64 // TODO reduce dupe from original timeline state, anyway to actually not instantiate new timeline?
|
dev@10
|
65 const track: HTMLElement = this.trackDiv.nativeElement;
|
dev@17
|
66 track.innerHTML = "";
|
dev@16
|
67 const duration: number = buffer.duration;
|
dev@10
|
68 const height: number = track.getBoundingClientRect().height;
|
dev@10
|
69 const width: number = track.getBoundingClientRect().width;
|
dev@10
|
70 const pixelsPerSecond = width / duration;
|
dev@16
|
71 const timeline = new wavesUI.core.Timeline(pixelsPerSecond, width);
|
dev@10
|
72 timeline.createTrack(track, height, 'main');
|
dev@16
|
73
|
dev@10
|
74 // time axis
|
dev@10
|
75 const timeAxis = new wavesUI.helpers.TimeAxisLayer({
|
dev@10
|
76 height: height,
|
dev@10
|
77 top: 10,
|
dev@10
|
78 color: 'gray'
|
dev@10
|
79 });
|
dev@16
|
80
|
dev@10
|
81 timeline.addLayer(timeAxis, 'main', 'default', true);
|
dev@10
|
82 timeline.state = new wavesUI.states.CenteredZoomState(timeline);
|
dev@16
|
83 // TODO dispose of the existing layer?
|
dev@16
|
84 const waveformLayer = new wavesUI.helpers.WaveformLayer(buffer, {
|
dev@16
|
85 height: 600,
|
dev@16
|
86 color: 'darkblue'
|
dev@16
|
87 });
|
dev@16
|
88 timeline.addLayer(waveformLayer, 'main');
|
dev@6
|
89 }
|
dev@16
|
90
|
dev@6
|
91 }
|