summaryrefslogtreecommitdiff
path: root/client/lib
diff options
context:
space:
mode:
Diffstat (limited to 'client/lib')
-rw-r--r--client/lib/kalimba.js19
-rw-r--r--client/lib/life.js75
-rw-r--r--client/lib/organ.js27
-rw-r--r--client/lib/output.js5
4 files changed, 122 insertions, 4 deletions
diff --git a/client/lib/kalimba.js b/client/lib/kalimba.js
index d3cafbb..249560f 100644
--- a/client/lib/kalimba.js
+++ b/client/lib/kalimba.js
@@ -1,10 +1,9 @@
import Tone from 'tone'
import { choice } from './util'
+import output from './output'
const player_count = 4
-const compressor = new Tone.Compressor(-30, 3).toMaster()
-
const samples = [
{ root: 226, fn: 'samples/380737__cabled-mess__sansula-01-a-raw.wav', },
{ root: 267, fn: 'samples/380736__cabled-mess__sansula-02-c-raw.wav', },
@@ -28,12 +27,21 @@ samples.forEach((sample) => {
retrigger: true,
playbackRate: 1,
})
- player.connect(compressor)
+ player.connect(output)
sample.players.push(player)
}
})
function play (freq) {
+/*
+ while (freq < 440) {
+ freq *= 2
+ }
+ while (freq > 880) {
+ freq /= 2
+ }
+ freq /= 2
+*/
const best = { sample: choice(samples) }
best.sample.index = (best.sample.index + 1) % player_count
@@ -41,6 +49,9 @@ function play (freq) {
player.playbackRate = freq / best.sample.root
player.start()
}
+function pause () {
+ // no-op
+}
-export default { play }
+export default { play, pause }
diff --git a/client/lib/life.js b/client/lib/life.js
new file mode 100644
index 0000000..26ff0bf
--- /dev/null
+++ b/client/lib/life.js
@@ -0,0 +1,75 @@
+
+let w, h, a, b, notes, assign
+function init(z, fn){
+ // really bad
+ notes = z
+ assign = fn
+ build()
+ setTempo(50)
+}
+function build(){
+ w = notes.length
+ h = notes[0].length
+ a = a || new Array(w)
+ b = b || new Array(w)
+ for (var i = 0; i < w; i++) {
+ a[i] = a[i] || new Array(h)
+ b[i] = b[i] || new Array(h)
+ for (var j = 0; j < h; j++) {
+ a[i][j] = b[i][j] = (notes[i][j] && notes[i][j].playing) ? 1 : 0
+ }
+ }
+}
+let timeout, delay = 1200 // ~120 bpm
+function toggle(){
+ build()
+ if (timeout) {
+ clearTimeout(timeout)
+ timeout = null
+ }
+ else {
+ step()
+ }
+}
+function assign_item(freq,state){
+ b[freq.i][freq.j] = state ? 1 : 0
+}
+function setTempo(bpm){
+ console.log('bpm:', bpm)
+ delay = 60000/bpm
+}
+function swap () {
+ var tmp = a
+ a = b
+ b = tmp
+}
+function step() {
+ clearTimeout(timeout)
+ timeout = setTimeout(step, delay)
+ swap()
+ let i, j, ni, pi, nj, pj, score, state
+ for (i = 0; i < w; i++) {
+ for (j = 0; j < h; j++) {
+ ni = i === 0 ? w-1 : i-1
+ pi = i === w-1 ? 0 : i+1
+ nj = j === 0 ? h-1 : j-1
+ pj = j === h-1 ? 0 : j+1
+ score = a[ni][nj] + a[ni][j] + a[ni][pj] + a[i][nj] + a[i][pj] + a[pi][nj] + a[pi][j] + a[pi][pj]
+ state = fitness(a[i][j], score)
+ b[i][j] = state
+ if (a[i][j] !== state) {
+ assign(notes[i][j], state)
+ }
+ }
+ }
+}
+function fitness (old, score) {
+ if (old === 1) {
+ if (score === 2 || score === 3) return 1
+ } else {
+ if (score === 3) return 1
+ }
+ return 0
+}
+
+export default { init, step, assign_item, toggle, setTempo } \ No newline at end of file
diff --git a/client/lib/organ.js b/client/lib/organ.js
new file mode 100644
index 0000000..fe2315c
--- /dev/null
+++ b/client/lib/organ.js
@@ -0,0 +1,27 @@
+import Tone from 'tone'
+import { choice } from './util'
+import output from './output'
+
+const player_count = 4
+
+const oscillators = {}
+
+function play (freq) {
+ const osc = oscillators[freq] = oscillators[freq] || {}
+ if (!osc.el) {
+ osc.el = new Tone.Oscillator(freq , "sine")
+ osc.el.connect(output)
+ }
+ osc.el.start()
+ osc.playing = true
+ return osc
+}
+function pause(freq) {
+ const osc = oscillators[freq] = oscillators[freq] || {}
+ osc.el && osc.el.stop()
+ osc.playing = false
+ return osc
+}
+
+export default { play, pause, oscillators }
+
diff --git a/client/lib/output.js b/client/lib/output.js
new file mode 100644
index 0000000..2155009
--- /dev/null
+++ b/client/lib/output.js
@@ -0,0 +1,5 @@
+import Tone from 'tone'
+
+const compressor = new Tone.Compressor(-30, 3).toMaster()
+
+export default compressor