diff options
Diffstat (limited to 'client/index.js')
| -rw-r--r-- | client/index.js | 189 |
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) +}) + |
