import WebMidi from 'webmidi' import { params } from './jx8p' 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 => '') 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()