diff --git a/README.md b/README.md index 074e9b8..eb419c2 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ control your MODEP pedalboard(s) via http requests | /pedals/`id` | get the current pedalboard's pedal by `id` | set values of current pedalboard's pedal by `id` | **note:** -to set a value for a pedal POST arguments **must** contain the parameters `id` and `value` where `id` is the id of one of the pedal's controls. +POST arguments **must** contain the parameters `id` and `value` where `id` is the id of one of the pedal's controls. **example - turn bypass on/off:** `curl localhost:3000/pedals/1` @@ -49,5 +49,13 @@ in this case the pedal's bypass is turned on and has the id "8"; now let's turn ### bypass | url | GET | POST | | - | - | - | -| /bypass | | toggle full bypass (switch to default pedalboard / back to last used pedalboard) | -| /bypass/`id` | | toggle bypass of a pedal by `id` | \ No newline at end of file +| /bypass | | toggle full bypass (switch to default pedalboard / back to last used pedalboard) | +| /bypass/`id` | | toggle bypass of a pedal by `id` | + +### midi +| url | GET | POST | +| - | - | - | +| /midi | | send a midi message via `oscsend` defined by the POST arguments to the osc host | + +**note:** +POST arguments **must** contain the parameters `controller`, `channel` and `value` where `id`. \ No newline at end of file diff --git a/libs/api.js b/libs/api.js index a4bd934..643405a 100644 --- a/libs/api.js +++ b/libs/api.js @@ -2,6 +2,7 @@ const logger = require('./logger.js'); const util = require('./util.js'); const constants = require('./constants.js'); const modep = require('./modep.js'); +const osc = require('./osc.js'); const info = require('./info.js'); const endpoints = new Map(); @@ -65,6 +66,11 @@ async function setupEndpoints() { undefined, { method: modep.toggleBypass } ); + setEndpoint( + constants.API_MIDI, + undefined, + { method: osc.sendByRequest} + ) logger.debug('setting up ' + endpoints.size + ' endpoints took ' + util.timeDiff(timestamp) + 'ms'); } diff --git a/libs/constants.js b/libs/constants.js index b46ee1b..0e3bb8d 100644 --- a/libs/constants.js +++ b/libs/constants.js @@ -7,6 +7,7 @@ const BANKS = '/banks'; const PEDALBOARDS = '/pedalboards'; const PEDALS = '/pedals'; const BYPASS = '/bypass'; +const MIDI = '/midi'; exports.VARIABLE_ID = VARIABLE_ID; @@ -25,6 +26,7 @@ exports.API_PEDALS = PEDALS; exports.API_PEDAL_BY_ID = PEDALS + '/' + VARIABLE_ID; exports.API_BYPASS = BYPASS; exports.API_BYPASS_BY_ID = BYPASS + '/' + VARIABLE_ID; +exports.API_MIDI = MIDI; exports.CACHE_INFO = "info"; exports.CACHE_BANKS = "banks"; diff --git a/libs/modep.js b/libs/modep.js index 6e5bed2..73f765a 100644 --- a/libs/modep.js +++ b/libs/modep.js @@ -5,6 +5,7 @@ const logger = require('./logger.js'); const cache = require('./cache.js'); const commands = require('./commands.js'); const blinky = require('./blinky.js'); +const osc = require('./osc.js'); const path = require('path'); const fs = require('fs'); const ttl2jsonld = require('@frogcat/ttl2jsonld').parse; @@ -327,24 +328,8 @@ function setControlByRequest(pedalId, requestParams) { async function setControl(control, value) { if (control === undefined || control.midi === undefined) { throw new Error('control \'' + control.name + '\' with id \'' + control.id + '\' has no midi bindings'); - } if (value === undefined || isNaN(value) || value < 0) { - value = 0; - } else if (value > 127) { - value = 127; - } - let cmd = 'oscsend'; - let args = [ - config.osc.host, config.osc.port, - config.osc.address, - 'm', - '00' + util.toHex(value) + '0' + util.toHex(control.midi.controller) + 'b' + util.toHex(control.midi.channel) - ]; - try { - await commands.execute(cmd, args); - control.value = value; - } catch (err) { - throw new Error(err); - } + } + control.value = await osc.send(control.midi.controller, control.midi.channel, value); } function setPedalboardById(pedalboardId) { diff --git a/libs/osc.js b/libs/osc.js new file mode 100644 index 0000000..5a04da8 --- /dev/null +++ b/libs/osc.js @@ -0,0 +1,57 @@ +const logger = require('./logger.js'); +const util = require('./util.js'); +const commands = require('./commands.js'); +const config = require('../config.json').osc; + +const CMD = 'oscsend'; + +async function send(controller, channel, value) { + if (controller == undefined || channel === undefined) { + return; + } + if (value === undefined || isNaN(value) || value < 0) { + value = 0; + } else if (value > 127) { + value = 127; + } + logger.debug('sending value \'' + value + '\' to controller \'' + controller + '\' on channel \'' + channel + '\'...'); + let args = [ + config.host, config.port, + config.address, + 'm', + '00' + util.toHex(value) + '0' + util.toHex(controller) + 'b' + util.toHex(channel) + ]; + try { + await commands.execute(CMD, args); + } catch (err) { + throw new Error(err); + } + return value; +} + +async function sendByRequest(id, args) { + if (args === undefined) { + throw new Error('no arguments defined'); + } + const controller = args.get('controller'); + if (controller === undefined) { + throw new Error('missing argument \'controller\''); + } + const channel = args.get('channel'); + if (channel === undefined) { + throw new Error('missing argument \'channel\''); + } let value = args.get('value'); + if (value === undefined) { + throw new Error('missing argument \'value\''); + } + try { + return JSON.stringify({ status: 'ok', controller: controller, channel: channel, value: await send(controller, channel, value) }); + } catch (err) { + return JSON.stringify({ status: 'error', error: err }); + } +} + +module.exports = { + send, + sendByRequest +} \ No newline at end of file