changeset 54:5fb857f8553b

Add a number of ad-hoc workarounds for bugs / quirks with waves-ui - regarding removing layers and avoiding ghost listeners. Still work to be done here.
author Lucas Thompson <dev@lucas.im>
date Thu, 08 Dec 2016 15:09:03 +0000
parents ccfbce214751
children 214e41418460
files src/app/waveform/waveform.component.ts
diffstat 1 files changed, 50 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/app/waveform/waveform.component.ts	Wed Dec 07 13:56:22 2016 +0000
+++ b/src/app/waveform/waveform.component.ts	Thu Dec 08 15:09:03 2016 +0000
@@ -10,6 +10,8 @@
 import {toSeconds} from "piper";
 
 type Timeline = any; // TODO what type actually is it.. start a .d.ts for waves-ui?
+type Layer = any;
+type Track = any;
 
 @Component({
   selector: 'app-waveform',
@@ -20,9 +22,10 @@
 
   @ViewChild('track') trackDiv: ElementRef;
 
-  private _audioBuffer: AudioBuffer = undefined;
-  private timeline: Timeline = undefined;
-  private cursorLayer: any = undefined;
+  private _audioBuffer: AudioBuffer;
+  private timeline: Timeline;
+  private cursorLayer: any;
+  private disposableLayers: Layer[];
 
   @Input()
   set audioBuffer(buffer: AudioBuffer) {
@@ -43,6 +46,10 @@
   constructor(private audioService: AudioPlayerService,
               private piperService: FeatureExtractionService,
               public ngZone: NgZone) {
+    this.disposableLayers = [];
+    this._audioBuffer = undefined;
+    this.timeline = undefined;
+    this.cursorLayer = undefined;
     this.isPlaying = false;
     this.featureExtractionSubscription = piperService.featuresExtracted$.subscribe(
       features => {
@@ -76,32 +83,48 @@
     const timeline = new wavesUI.core.Timeline(pixelsPerSecond, width);
     timeline.timeContext.offset = 0.5 * timeline.timeContext.visibleDuration;
     timeline.createTrack(track, height, 'main');
+    return timeline;
+  }
 
+  renderWaveform(buffer: AudioBuffer): void {
+    const height: number = this.trackDiv.nativeElement.getBoundingClientRect().height;
+    const mainTrack = this.timeline.getTrackById('main');
+    if (this.timeline) {
+      // resize
+      const width = this.trackDiv.nativeElement.getBoundingClientRect().width;
+      // loop through layers and remove them, waves-ui provides methods for this but it seems to not work properly
+      for (let i = 0; i < this.disposableLayers.length; ++i) {
+        let layer = this.disposableLayers.pop();
+        mainTrack.remove(layer);
+        layer.destroy();
+      }
+      this.timeline.visibleWidth = width;
+      this.timeline.pixelsPerSecond = width / buffer.duration;
+      mainTrack.height = height;
+    } else {
+      this.timeline = this.renderTimeline(buffer.duration)
+    }
     // time axis
     const timeAxis = new wavesUI.helpers.TimeAxisLayer({
       height: height,
       color: 'gray'
     });
+    this.addLayer(timeAxis, mainTrack, this.timeline.timeContext, true);
 
-    timeline.addLayer(timeAxis, 'main', 'default', true);
-    return timeline;
-  }
-
-  renderWaveform(buffer: AudioBuffer): void {
-    const height: number = this.trackDiv.nativeElement.getBoundingClientRect().height;
-    this.timeline = this.renderTimeline(buffer.duration);
     const waveformLayer = new wavesUI.helpers.WaveformLayer(buffer, {
       top: 10,
       height: height * 0.9,
       color: 'darkblue'
     });
-    (this.timeline as any).addLayer(waveformLayer, 'main');
+    this.addLayer(waveformLayer, mainTrack, this.timeline.timeContext);
 
     this.cursorLayer = new wavesUI.helpers.CursorLayer({
       height: height
     });
-    this.timeline.addLayer(this.cursorLayer, 'main');
+    this.addLayer(this.cursorLayer, mainTrack, this.timeline.timeContext);
     this.timeline.state = new wavesUI.states.CenteredZoomState(this.timeline);
+    mainTrack.render();
+    mainTrack.update();
     this.animate();
   }
 
@@ -113,9 +136,10 @@
         cy: feature.featureValues[0]
       };
     });
-    this.timeline.addLayer(
+    this.addLayer(
       new wavesUI.helpers.BreakpointLayer(plotData, {color: 'green'}),
-      'main'
+      this.timeline.getTrackById('main'),
+      this.timeline.timeContext
     );
   }
 
@@ -161,6 +185,18 @@
     });
   }
 
+  private addLayer(layer: Layer, track: Track, timeContext: any, isAxis: boolean = false): void {
+    timeContext.zoom = 1.0;
+    if (!layer.timeContext) {
+      layer.setTimeContext(isAxis ?
+        timeContext : new wavesUI.core.LayerTimeContext(timeContext));
+    }
+    this.disposableLayers.push(layer);
+    track.add(layer);
+    layer.render();
+    layer.update();
+  }
+
   ngOnDestroy(): void {
     this.featureExtractionSubscription.unsubscribe();
     this.playingStateSubscription.unsubscribe();