dev@380
|
1 /**
|
dev@380
|
2 * Created by lucast on 31/05/2017.
|
dev@380
|
3 */
|
dev@390
|
4 import {
|
dev@394
|
5 InspectableVerticallyBoundedComponent,
|
dev@390
|
6 VerticallyBounded,
|
dev@394
|
7 VerticalScaleRenderer,
|
dev@405
|
8 VerticalValueInspectorRenderer,
|
dev@405
|
9 WavesComponent
|
dev@390
|
10 } from '../waves-base.component';
|
dev@380
|
11 import {
|
dev@380
|
12 ChangeDetectionStrategy,
|
dev@380
|
13 Component,
|
dev@380
|
14 Input,
|
dev@380
|
15 } from '@angular/core';
|
dev@380
|
16 import {Note} from '../FeatureUtilities';
|
dev@380
|
17 import Waves from 'waves-ui-piper';
|
dev@380
|
18
|
dev@380
|
19 @Component({
|
dev@380
|
20 selector: 'ugly-notes',
|
dev@380
|
21 templateUrl: '../waves-template.html',
|
dev@380
|
22 styleUrls: ['../waves-template.css'],
|
dev@390
|
23 changeDetection: ChangeDetectionStrategy.OnPush,
|
dev@392
|
24 providers: [
|
dev@392
|
25 { provide: VerticallyBounded, useExisting: NotesComponent },
|
dev@394
|
26 { provide: VerticalScaleRenderer, useExisting: NotesComponent },
|
dev@405
|
27 {provide: VerticalValueInspectorRenderer, useExisting: NotesComponent },
|
dev@405
|
28 {provide: WavesComponent, useExisting: NotesComponent}
|
dev@392
|
29 ]
|
dev@380
|
30 })
|
dev@394
|
31 export class NotesComponent extends InspectableVerticallyBoundedComponent<Note[]> {
|
dev@390
|
32 private currentVerticalRange: [number, number];
|
dev@390
|
33
|
dev@390
|
34 get range(): [number, number] {
|
dev@390
|
35 return this.currentVerticalRange;
|
dev@390
|
36 }
|
dev@380
|
37
|
dev@380
|
38 @Input() set notes(notes: Note[]) {
|
dev@383
|
39 this.feature = notes;
|
dev@380
|
40 }
|
dev@380
|
41
|
dev@383
|
42 protected get featureLayers(): Layer[] {
|
dev@390
|
43 this.currentVerticalRange = findVerticalRange(this.feature);
|
dev@383
|
44 return [
|
dev@380
|
45 new Waves.helpers.PianoRollLayer(
|
dev@383
|
46 this.feature,
|
dev@380
|
47 {
|
dev@380
|
48 height: this.height,
|
dev@380
|
49 color: this.colour,
|
dev@390
|
50 yDomain: this.currentVerticalRange
|
dev@380
|
51 }
|
dev@383
|
52 )
|
dev@383
|
53 ];
|
dev@380
|
54 }
|
dev@380
|
55 }
|
dev@380
|
56
|
dev@380
|
57 // TODO there might be scope to create a generic utility function like this
|
dev@380
|
58 function findVerticalRange(notes: Note[]): [number, number] {
|
dev@380
|
59 let [min, max] = notes.reduce((acc, note) => {
|
dev@380
|
60 const [min, max] = acc;
|
dev@380
|
61 return [Math.min (min, note.pitch), Math.max (max, note.pitch)];
|
dev@380
|
62 }, [Infinity, -Infinity]);
|
dev@380
|
63 if (min === Infinity || min < 0 || max < 0) {
|
dev@380
|
64 min = 0;
|
dev@380
|
65 max = 127;
|
dev@380
|
66 }
|
dev@380
|
67 // round min and max to octave boundaries (starting at C as in MIDI)
|
dev@380
|
68 return [
|
dev@380
|
69 12 * Math.floor(min / 12),
|
dev@380
|
70 12 * Math.ceil(max / 12)
|
dev@380
|
71 ];
|
dev@380
|
72 }
|