diff --git a/.vscode/settings.json b/.vscode/settings.json index bfd3c95539..1f5c03823e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,6 +16,9 @@ "[json]": { "editor.formatOnSave": false }, + "[html]": { + "editor.formatOnSave": false + }, "editor.formatOnSave": true, "clang-format.style": "Google", "files.insertFinalNewline": true, diff --git a/demos/performance_rnn/images/magenta-logo-bottom-text2.png b/demos/performance_rnn/images/magenta-logo-bottom-text2.png new file mode 100644 index 0000000000..324f39b905 Binary files /dev/null and b/demos/performance_rnn/images/magenta-logo-bottom-text2.png differ diff --git a/demos/performance_rnn/index.html b/demos/performance_rnn/index.html new file mode 100644 index 0000000000..60c9592bdb --- /dev/null +++ b/demos/performance_rnn/index.html @@ -0,0 +1,306 @@ + +
+
+
+
+
+
diff --git a/demos/performance_rnn/keyboard_element.ts b/demos/performance_rnn/keyboard_element.ts
new file mode 100644
index 0000000000..64dddc3bc8
--- /dev/null
+++ b/demos/performance_rnn/keyboard_element.ts
@@ -0,0 +1,100 @@
+/* Copyright 2017 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+const offsets = [0, 0.5, 1, 1.5, 2, 3, 3.5, 4, 4.5, 5, 5.5, 6];
+
+const minNote = 21;
+const maxNote = 108;
+
+export class KeyboardElement {
+ private container: Element;
+ private keys: {[key: number]: Element};
+ private notes: {[key: number]: Note[]};
+
+ constructor(container: Element) {
+ this.container = document.createElement('div');
+ this.container.id = 'keyboard';
+ container.appendChild(this.container);
+
+ this.keys = {};
+
+ this.resize();
+ this.notes = {};
+ }
+
+ resize() {
+ // clear the previous ones.
+ this.keys = {};
+ this.container.innerHTML = '';
+
+ // each of the keys.
+ const keyWidth = 1 / 52;
+
+ for (let i = minNote; i <= maxNote; i++) {
+ const key = document.createElement('div');
+ key.classList.add('key');
+ const isSharp = ([1, 3, 6, 8, 10].indexOf(i % 12) !== -1);
+ key.classList.add(isSharp ? 'black' : 'white');
+ this.container.appendChild(key);
+ // position the element
+
+ const noteOctave = Math.floor(i / 12) - Math.floor(minNote / 12);
+ const offset = offsets[i % 12] + noteOctave * 7 - 5;
+ key.style.width = `${keyWidth * 100}%`;
+ key.style.left = `${offset * keyWidth * 100}%`;
+ key.id = i.toString();
+
+ const fill = document.createElement('div');
+ fill.classList.add('fill');
+ key.appendChild(fill);
+ this.keys[i] = key;
+ }
+ }
+
+ keyDown(noteNum: number) {
+ if (noteNum in this.keys) {
+ const key = this.keys[noteNum];
+
+ const note = new Note(key.querySelector('.fill'));
+ if (!this.notes[noteNum]) {
+ this.notes[noteNum] = [] as Note[];
+ }
+ this.notes[noteNum].push(note);
+ }
+ }
+
+ keyUp(noteNum: number) {
+ if (noteNum in this.keys) {
+ if (!(this.notes[noteNum] && this.notes[noteNum].length)) {
+ console.warn('note off before note on');
+ } else {
+ this.notes[noteNum].shift().noteOff();
+ }
+ }
+ }
+}
+
+class Note {
+ private element: Element;
+
+ constructor(element: Element) {
+ this.element = element;
+ this.element.classList.add('active');
+ }
+
+ noteOff() {
+ this.element.classList.remove('active');
+ }
+}
diff --git a/demos/performance_rnn/performance_rnn.ts b/demos/performance_rnn/performance_rnn.ts
new file mode 100644
index 0000000000..6f35652c8b
--- /dev/null
+++ b/demos/performance_rnn/performance_rnn.ts
@@ -0,0 +1,486 @@
+/* Copyright 2017 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+// tslint:disable-next-line:max-line-length
+import {Array1D, Array2D, CheckpointLoader, NDArray, NDArrayMath, NDArrayMathGPU, Scalar} from '../deeplearn';
+
+import {KeyboardElement} from './keyboard_element';
+
+// tslint:disable-next-line:no-require-imports
+const Piano = require('tone-piano').Piano;
+
+let lstmKernel1: Array2D;
+let lstmBias1: Array1D;
+let lstmKernel2: Array2D;
+let lstmBias2: Array1D;
+let lstmKernel3: Array2D;
+let lstmBias3: Array1D;
+let c: Array2D[];
+let h: Array2D[];
+let fullyConnectedBiases: Array1D;
+let fullyConnectedWeights: Array2D;
+const forgetBias = Scalar.new(1.0);
+const activeNotes = new Map