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@460
|
67
|
dev@460
|
68 constructor() {
|
dev@460
|
69 this.stack = [];
|
dev@460
|
70 this.history = [];
|
dev@460
|
71 }
|
dev@460
|
72
|
dev@460
|
73 shift(): T {
|
dev@460
|
74 this.history.push([...this.stack]);
|
dev@460
|
75 const item = this.stack[0];
|
dev@460
|
76 this.stack = this.stack.slice(1);
|
dev@460
|
77 return item;
|
dev@460
|
78 }
|
dev@460
|
79
|
dev@460
|
80 unshift(item: T): number {
|
dev@460
|
81 this.history.push([...this.stack]);
|
dev@460
|
82 this.stack = [item, ...this.stack];
|
dev@460
|
83 return this.stack.length;
|
dev@460
|
84 }
|
dev@460
|
85
|
dev@460
|
86 findIndex(predicate: (value: T,
|
dev@460
|
87 index: number,
|
dev@460
|
88 array: T[]) => boolean): number {
|
dev@460
|
89 return this.stack.findIndex(predicate);
|
dev@460
|
90 }
|
dev@460
|
91
|
dev@460
|
92 filter(predicate: (value: T, index: number, array: T[]) => boolean): T[] {
|
dev@460
|
93 return this.stack.filter(predicate);
|
dev@460
|
94 }
|
dev@460
|
95
|
dev@460
|
96 get(index: number): T {
|
dev@460
|
97 return this.stack[index];
|
dev@460
|
98 }
|
dev@460
|
99
|
dev@460
|
100 set(index: number, value: T) {
|
dev@460
|
101 this.history.push([...this.stack]);
|
dev@460
|
102 this.stack = [
|
dev@460
|
103 ...this.stack.slice(0, index),
|
dev@460
|
104 value,
|
dev@460
|
105 ...this.stack.slice(index + 1)
|
dev@460
|
106 ];
|
dev@460
|
107 }
|
dev@460
|
108
|
dev@460
|
109 map<U>(transform: (value: T, index: number, array: T[]) => U): U[] {
|
dev@460
|
110 return this.stack.map(transform);
|
dev@460
|
111 }
|
dev@460
|
112
|
dev@460
|
113 reduce<U>(reducer: (previousValue: U,
|
dev@460
|
114 currentValue: T,
|
dev@460
|
115 currentIndex: number,
|
dev@460
|
116 array: T[]) => U,
|
dev@460
|
117 initialValue: U): U {
|
dev@460
|
118 return this.stack.reduce(reducer, initialValue);
|
dev@460
|
119 }
|
dev@460
|
120
|
dev@460
|
121 remove(...indices: number[]) {
|
dev@460
|
122 this.history.push([...this.stack]);
|
dev@460
|
123 this.stack = this.stack.reduce((acc, item, i) => {
|
dev@460
|
124 if (!indices.includes(i)) {
|
dev@460
|
125 acc.push(item);
|
dev@460
|
126 }
|
dev@460
|
127 return acc;
|
dev@460
|
128 }, [] as T[]);
|
dev@460
|
129 }
|
dev@460
|
130
|
dev@460
|
131 toIterable(): Iterable<T> {
|
dev@460
|
132 return this.stack;
|
dev@460
|
133 }
|
dev@460
|
134 }
|