summaryrefslogtreecommitdiff
path: root/client/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/index.js')
-rw-r--r--client/index.js189
1 files changed, 189 insertions, 0 deletions
diff --git a/client/index.js b/client/index.js
new file mode 100644
index 0000000..8517af6
--- /dev/null
+++ b/client/index.js
@@ -0,0 +1,189 @@
+import Tone from 'tone'
+import 'nexusui'
+import keys from './lib/keys'
+import color from './lib/color'
+import kalimba from './lib/kalimba'
+import scales from './lib/scales'
+
+const nx = window.nx
+
+const noteCount = 24
+const stepCount = 16
+
+let grid
+
+var loop = new Tone.Sequence(function(time, col){
+ var column = grid.matrix[col]
+ grid.jumpToCol(col)
+ for (var i = 0; i < noteCount; i++){
+ if (column[i] === 1){
+ const freq = scales.current().index(noteCount - i - 12)
+ kalimba.play(freq)
+ }
+ }
+}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "16n")
+
+nx.colorize('#f4d142')
+
+nx.onload = () => {
+ grid = nx.widgets.grid
+ grid.sequenceMode = true
+ grid.bpm = 1
+ grid.col = stepCount
+ grid.row = noteCount
+
+ grid.init()
+ grid.resize(480, 640)
+ grid.draw()
+
+ nx.widgets.shiftUp.on('*', e => e.press && shiftUp())
+ nx.widgets.shiftDown.on('*', e => e.press && shiftDown())
+ nx.widgets.slideUp.on('*', e => e.press && slideUp())
+ nx.widgets.slideDown.on('*', e => e.press && slideDown())
+ nx.widgets.rotateUp.on('*', e => e.press && rotateVertical(-1))
+ nx.widgets.rotateDown.on('*', e => e.press && rotateVertical(1))
+ nx.widgets.rotateLeft.on('*', e => e.press && rotateHorizontal(-1))
+ nx.widgets.rotateRight.on('*', e => e.press && rotateHorizontal(1))
+ nx.widgets.flip.on('*', e => e.press && flip())
+ nx.widgets.flop.on('*', e => e.press && flop())
+
+ loop.start()
+ Tone.Transport.bpm.value = 108
+ Tone.Transport.start()
+}
+
+function shiftUp () {
+}
+function shiftDown () {
+}
+function slideUp () {
+ assignNotes( mapFunction(findNotes(), (n) => {
+ return (n - 1 + noteCount) % noteCount
+ }))
+}
+function slideDown () {
+ assignNotes( mapFunction(findNotes(), (n) => {
+ return (n + 1 + noteCount) % noteCount
+ }))
+}
+function flip () {
+ assignNotes( mapReverse(findNotes()) )
+}
+function flop () {
+ assignPositions( mapReverse(findPositions()) )
+}
+function rotateHorizontal (n) {
+ assignPositions( remapArray(findPositions(), n) )
+}
+function rotateVertical (n) {
+ assignNotes( remapArray(findNotes(), n) )
+}
+function assignPositions (notes) {
+ if (! notes) return
+ const a = grid.matrix
+ const b = iota()
+ stride(a, (i,j,v) => {
+ if (i in notes) {
+ b[notes[i]][j] = v
+ }
+ })
+ assign(grid.matrix, b)
+ grid.draw()
+}
+function assignNotes (positions) {
+ if (! positions) return
+ const a = grid.matrix
+ const b = iota()
+ stride(a, (i,j,v) => {
+ if (j in positions) {
+ b[i][positions[j]] = v
+ }
+ })
+ assign(grid.matrix, b)
+ grid.draw()
+}
+
+function stride (a, f) {
+ const w = a.length, h = a[0].length
+ for (let i = 0; i < w; i++) {
+ for (let j = 0; j < h; j++) {
+ f(i, j, a[i][j])
+ }
+ }
+ return a
+}
+
+// assign b -> a
+function assign (a, b) {
+ return stride(b, (i,j,v) => a[i][j] = b[i][j])
+}
+function clone (a) {
+ const b = iota(a.length, a[0].length)
+ return assign(b, a)
+}
+function iota () {
+ const w = grid.matrix.length, h = grid.matrix[0].length
+ const a = new Array(w)
+ for (let i = 0; i < w; i++) {
+ a[i] = new Array(h)
+ for (let j = 0; j < h; j++) {
+ a[i][j] = 0
+ }
+ }
+ return a
+}
+function findNotes () {
+ const a = new Array(grid.matrix[0].length)
+ grid.matrix.forEach((col, i) => {
+ col.forEach((v, j) => { if (v) a[j] = 1 })
+ })
+ return a.reduce((acc, v, i) => {
+ if (v === 1) acc.push(i)
+ return acc
+ }, [])
+}
+function findPositions () {
+ return grid.matrix.reduce((acc, row, i) => {
+ if (row.some((x) => x === 1)) acc.push(i)
+ return acc
+ }, [])
+}
+function remapArray (a, n) {
+ if (! a.length) return
+ const h = {}
+ const b = rotate(a, n)
+ for (let i = 0; i < b.length; i++) {
+ h[b[i]] = a[i]
+ }
+ return h
+}
+function rotate(a, n) {
+ const b = a.slice(0)
+ b.unshift.apply( b, b.splice( -n, b.length ) )
+ console.log(b)
+ return b
+}
+function mapFunction (a, f) {
+ if (! a.length) return
+ const h = {}
+ for (let i = 0; i < a.length; i++) {
+ h[a[i]] = f(a[i])
+ }
+ console.log(h)
+ return h
+}
+function mapReverse (a) {
+ if (! a.length) return
+ const h = {}
+ const b = a.slice(0).reverse()
+ for (let i = 0; i < b.length; i++) {
+ h[b[i]] = a[i]
+ }
+ return h
+}
+
+keys.listen(function(index){
+ const freq = scales.current().index(index)
+ kalimba.play(freq)
+})
+