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