summaryrefslogtreecommitdiff
path: root/client/index.js
blob: 64c1433e779a2031ccd1128bcbd287411ad0546e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import WebMidi from 'webmidi'
import { params } from './subphatty'

let output;
let channel = 1

function init(){
  build()
  bind()
  WebMidi.enable(ready)
}
function ready(err) {
  if (err) {
    console.error('webmidi failed to initialize')
    return
  }
  if (!WebMidi.outputs.length) {
    console.error('no MIDI output found')
  }
  console.log(WebMidi.inputs)
  console.log(WebMidi.outputs)
  output = WebMidi.outputs[0]
}
function build(){
  const section_template = document.querySelector('#section_template').innerHTML
  const checkbox_template = document.querySelector('#checkbox_template').innerHTML
  const range_template = document.querySelector('#range_template').innerHTML
  const enum_template = document.querySelector('#enum_template').innerHTML
  const params_by_tag = params.reduce((a,b,i) => {
    const tag = b.tag || b.name.split(' ')[0]
    b.index = i
    if (a[tag]) {
      a[tag].push(b)
    } else {
      a[tag] = [b]
    }
    return a
  }, {})
  Object.keys(params_by_tag).map(tag => {
    const els = params_by_tag[tag].map(param => {
      let t, options;
      switch (param.type) {
        case 'checkbox':
          t = checkbox_template.replace(/{name}/, param.name)
            .replace(/{param_name}/, param.name.replace(/ /g, '_'))
            .replace(/{index}/, param.index)
          break
        case 'range':
          t = range_template.replace(/{name}/, param.name)
            .replace(/{param_name}/, param.name.replace(/ /g, '_'))
            .replace(/{index}/, param.index)
            .replace(/{min}/, param.range[0])
            .replace(/{max}/, param.range[1])
            .replace(/{value}/, Math.floor((param.range[1] - param.range[0]) / 2))
          break
        case 'enum':
          options = param.values.map(a => '<option value="' + a[0] + '">' + a[1] + '</option>')
          t = enum_template.replace(/{name}/, param.name)
            .replace(/{param_name}/, param.name.replace(/ /g, '_'))
            .replace(/{index}/, param.index)
            .replace(/{options}/, options)
            .replace(/{value}/, param.values[0][0])
          break
        default:
          console.log('unknown type', param)
          t = ""
          break
      }
      return t
    }).filter(t => !!t)
    let t = section_template.replace(/{name}/, tag).replace(/{els}/, els.join(''))
    document.querySelector('#params').innerHTML += t
  })
}
function bind(){
  toArray(document.querySelectorAll('#params input[type=range]')).forEach(el => {
    const index = el.dataset.index
    const param = params[index]
    el.addEventListener('input', () => {
      update_param(param, el.value)
    })
  })
  toArray(document.querySelectorAll('#params input[type=checkbox]')).forEach(el => {
    const index = el.dataset.index
    const param = params[index]
    el.addEventListener('input', () => {
      const isChecked = el.checked
      const value = isChecked ? param.on : param.off
      update_param(param, value)
    })
  })
  toArray(document.querySelectorAll('#params select')).forEach(el => {
    const index = el.dataset.index
    const param = params[index]
    el.addEventListener('input', () => {
      update_param(param, el.value)
    })
  })
  document.querySelector('#randomize').addEventListener('click', randomize)
}
function update_param(param, value){
  if (param.fourteen) {
    const msb = value >> 7
    const lsb = value & 127
    output.sendControlChange(param.fourteen[0], msb, channel)
    output.sendControlChange(param.fourteen[1], lsb, channel)
  } else {
    output.sendControlChange(param.cc, value, channel)
  }
}
function randint(n) {
  return Math.floor(Math.random() * n)
}
function randomize(){
  params.forEach(param => {
    let value
    if (param.randomize === false) return
    if (param.type === 'range') {
      value = randint(param.range[1])
      update_param(param, value)
      document.querySelector("input[name=" + param.name.replace(/ /g, '_') + "]").value = value
    }
  })
}
function toArray(a){
  return Reflect.apply(Array.prototype.slice, a, [])
}

init()