dev@460
|
1 /**
|
dev@460
|
2 * Created by lucast on 08/06/2017.
|
dev@460
|
3 */
|
dev@460
|
4 import {
|
dev@460
|
5 Item,
|
dev@460
|
6 RootAudioItem
|
dev@460
|
7 } from './analysis-item/AnalysisItem';
|
dev@460
|
8
|
dev@460
|
9 export const exampleSession: SerialisedNotebook = {
|
dev@460
|
10 root: {
|
dev@460
|
11 id: '1',
|
dev@460
|
12 hasSharedTimeline: true,
|
dev@460
|
13 title: 'Drum Loop',
|
dev@460
|
14 description: 'Remotely hosted audio file',
|
dev@460
|
15 uri: 'https://piper-audio.github.io/waves-ui-piper/examples/assets/drum-loop.wav'
|
dev@460
|
16 },
|
dev@460
|
17 analyses: [
|
dev@460
|
18 {
|
dev@460
|
19 id: '2',
|
dev@460
|
20 hasSharedTimeline: true,
|
dev@460
|
21 extractorKey: 'vamp-example-plugins:amplitudefollower',
|
dev@460
|
22 outputId: 'amplitude',
|
dev@460
|
23 title: 'Amplitude',
|
dev@460
|
24 description: 'amplitude'
|
dev@460
|
25 },
|
dev@460
|
26 {
|
dev@460
|
27 id: '3',
|
dev@460
|
28 hasSharedTimeline: true,
|
dev@460
|
29 extractorKey: 'vamp-example-plugins:powerspectrum',
|
dev@460
|
30 outputId: 'powerspectrum',
|
dev@460
|
31 title: 'Simple Power Spectrum',
|
dev@460
|
32 description: 'powerspectrum'
|
dev@460
|
33 },
|
dev@460
|
34
|
dev@460
|
35 ]
|
dev@460
|
36 };
|
dev@460
|
37
|
dev@460
|
38 export interface SerialisedAnalysisItem extends Item {
|
dev@460
|
39 extractorKey: string;
|
dev@460
|
40 outputId: string;
|
dev@460
|
41 }
|
dev@460
|
42
|
dev@460
|
43 export interface SerialisedNotebook {
|
dev@460
|
44 root: RootAudioItem;
|
dev@460
|
45 analyses: SerialisedAnalysisItem[];
|
dev@460
|
46 }
|
dev@460
|
47
|
dev@460
|
48 export type ResourceRetriever = (url: string) => Promise<Blob>;
|
dev@460
|
49
|
dev@460
|
50 export const downloadResource: ResourceRetriever = async (url) => {
|
dev@460
|
51 const response = await fetch(url);
|
dev@460
|
52 const mimeType = response.headers.get('content-type');
|
dev@460
|
53 // Safari's fetch.blob implementation doesn't populate the type property
|
dev@460
|
54 // causing the audio player to fail due to an unsupported type.
|
dev@460
|
55 // Manually create a blob from an array buffer and the content type in
|
dev@460
|
56 // the response object
|
dev@460
|
57 const arrayBufferToBlob = async () => {
|
dev@460
|
58 const arrayBuffer = await response.arrayBuffer();
|
dev@460
|
59 return new Blob([arrayBuffer], {type: mimeType});
|
dev@460
|
60 };
|
dev@460
|
61 return mimeType ? arrayBufferToBlob() : response.blob();
|
dev@460
|
62 };
|
dev@460
|
63
|
dev@460
|
64 export class PersistentStack<T> {
|
dev@460
|
65 private stack: T[];
|
dev@460
|
66 private history: T[][];
|
dev@462
|
67 private historyOffset: number;
|
dev@460
|
68
|
dev@460
|
69 constructor() {
|
dev@460
|
70 this.stack = [];
|
dev@462
|
71 this.history = [[]];
|
dev@462
|
72 this.historyOffset = 0;
|
dev@460
|
73 }
|
dev@460
|
74
|
dev@465
|
75 shiftMutating(): T {
|
dev@460
|
76 const item = this.stack[0];
|
dev@460
|
77 this.stack = this.stack.slice(1);
|
dev@465
|
78 return item;
|
dev@465
|
79 }
|
dev@465
|
80
|
dev@465
|
81 shift(): T {
|
dev@465
|
82 const item = this.shiftMutating();
|
dev@462
|
83 this.history.push([...this.stack]);
|
dev@460
|
84 return item;
|
dev@460
|
85 }
|
dev@460
|
86
|
dev@465
|
87 unshiftMutating(item: T): number {
|
dev@465
|
88 this.stack = [item, ...this.stack];
|
dev@465
|
89 return this.stack.length;
|
dev@465
|
90 }
|
dev@465
|
91
|
dev@460
|
92 unshift(item: T): number {
|
dev@465
|
93 const newLength = this.unshift(item);
|
dev@460
|
94 this.history.push([...this.stack]);
|
dev@465
|
95 return newLength;
|
dev@460
|
96 }
|
dev@460
|
97
|
dev@460
|
98 findIndex(predicate: (value: T,
|
dev@460
|
99 index: number,
|
dev@460
|
100 array: T[]) => boolean): number {
|
dev@460
|
101 return this.stack.findIndex(predicate);
|
dev@460
|
102 }
|
dev@460
|
103
|
dev@460
|
104 filter(predicate: (value: T, index: number, array: T[]) => boolean): T[] {
|
dev@460
|
105 return this.stack.filter(predicate);
|
dev@460
|
106 }
|
dev@460
|
107
|
dev@460
|
108 get(index: number): T {
|
dev@460
|
109 return this.stack[index];
|
dev@460
|
110 }
|
dev@460
|
111
|
dev@460
|
112 set(index: number, value: T) {
|
dev@465
|
113 this.setMutating(index, value);
|
dev@465
|
114 this.history.push([...this.stack]);
|
dev@465
|
115 }
|
dev@465
|
116
|
dev@465
|
117 setMutating(index: number, value: T) {
|
dev@460
|
118 this.stack = [
|
dev@460
|
119 ...this.stack.slice(0, index),
|
dev@460
|
120 value,
|
dev@460
|
121 ...this.stack.slice(index + 1)
|
dev@460
|
122 ];
|
dev@460
|
123 }
|
dev@460
|
124
|
dev@460
|
125 map<U>(transform: (value: T, index: number, array: T[]) => U): U[] {
|
dev@460
|
126 return this.stack.map(transform);
|
dev@460
|
127 }
|
dev@460
|
128
|
dev@460
|
129 reduce<U>(reducer: (previousValue: U,
|
dev@460
|
130 currentValue: T,
|
dev@460
|
131 currentIndex: number,
|
dev@460
|
132 array: T[]) => U,
|
dev@460
|
133 initialValue: U): U {
|
dev@460
|
134 return this.stack.reduce(reducer, initialValue);
|
dev@460
|
135 }
|
dev@460
|
136
|
dev@460
|
137 remove(...indices: number[]) {
|
dev@460
|
138 this.stack = this.stack.reduce((acc, item, i) => {
|
dev@460
|
139 if (!indices.includes(i)) {
|
dev@460
|
140 acc.push(item);
|
dev@460
|
141 }
|
dev@460
|
142 return acc;
|
dev@460
|
143 }, [] as T[]);
|
dev@462
|
144 this.history.push([...this.stack]);
|
dev@462
|
145 }
|
dev@462
|
146
|
dev@462
|
147 stepBack(): void {
|
dev@462
|
148 const latest = this.history.length - 1;
|
dev@462
|
149 if (++this.historyOffset <= latest) {
|
dev@462
|
150 this.stack = this.history[latest - this.historyOffset];
|
dev@462
|
151 } else {
|
dev@462
|
152 this.historyOffset = latest;
|
dev@462
|
153 }
|
dev@462
|
154 }
|
dev@462
|
155
|
dev@462
|
156 stepForward(): void {
|
dev@462
|
157 const latest = this.history.length - 1;
|
dev@462
|
158 if (--this.historyOffset >= 0) {
|
dev@462
|
159 this.stack = this.history[latest - this.historyOffset];
|
dev@462
|
160 } else {
|
dev@462
|
161 this.historyOffset = 0;
|
dev@462
|
162 }
|
dev@460
|
163 }
|
dev@460
|
164
|
dev@460
|
165 toIterable(): Iterable<T> {
|
dev@460
|
166 return this.stack;
|
dev@460
|
167 }
|
dev@460
|
168 }
|