Skip to content

Instantly share code, notes, and snippets.

@hems
Created June 8, 2018 05:13
Show Gist options
  • Save hems/8246279cf28e8607fb0167da8b3deb9a to your computer and use it in GitHub Desktop.
Save hems/8246279cf28e8607fb0167da8b3deb9a to your computer and use it in GitHub Desktop.
NRPN Parser in Javascript
var MAPPING = {
// all messages on MSB 19
18: {
// message on LSB 0
0: {
"name": "FILT_1 FREQUENCY POT",
"NRPN": true,
"default": 250,
"range": {
"min": 0,
"max": 65535
}
}
},
// all messages on MSB 19
19: {
// message on LSB 0
0: {
"name": "FILT_2 FREQUENCY POT",
"NRPN": true,
"default": 250,
"range": {
"min": 0,
"max": 65535
}
}
}
}
// MIDI CC constants
var CC_DATA_MSB = 6
var CC_DATA_LSB = 38
var CC_NRPN_LSB = 98
var CC_NRPN_MSB = 99
// inlets and outlets
inlets = 1
outlets = 2
// hopefully recompile and reload
autowatch = true
// global variables and arrays
var nrpn_index
var value
var nrpn_index_lsb
var nrpn_index_msb = 0
var value_lsb
var value_msb = 0
var cc_index
var cc_value
// methods start here
// list - expects a CC Index + Value as argument
// filters out NRPN and RPN values and assigns to variables
// Passes through all other CCs
function list(val) {
// we expect at least 2 arguments
if (arguments.length != 2) return
cc_index = arguments[0]
cc_value = arguments[1]
switch (cc_index) {
case CC_DATA_MSB:
// post("CC_DATA_MSB \n")
// If we have a valid NRPN index, then the data is valid
if (nrpn_index) {
value_msb = cc_value << 7
if (value_lsb) {
value = value_msb | value_lsb
// We are now ready to send an index and value out!
send_nrpn(nrpn_index, value)
}
}
// If we don't have an index it's invalid
else {
// So forward the value as a normal CC
send_cc(cc_index, cc_value)
}
break
case CC_DATA_LSB:
// post("CC_DATA_LSB \n")
// If we have a valid NRPN index, then the data is valid
if (nrpn_index) {
value_lsb = cc_value
value = value_msb | value_lsb
// We are now ready to send an index and value out!
send_nrpn(nrpn_index, value)
}
// If we don't have an index it's invalid
else {
// So forward the value as a normal CC
send_cc(cc_index, cc_value)
}
break
// NRPN Index MSB - 7 high bits
case CC_NRPN_MSB:
// post("CC_NRPN_MSB \n")
// Save 7 high bits
nrpn_index_msb = cc_value << 7
// Create the 14 bit NRPN index
nrpn_index = nrpn_index_msb | nrpn_index_lsb
post_name( nrpn_index_msb, nrpn_index_lsb )
break
// NRPN Index LSB - 7 low bits
case CC_NRPN_LSB:
// post("CC_NRPN_LSB \n")
// Save 7 low bits
nrpn_index_lsb = cc_value
// Create the 14 bit NRPN index
nrpn_index = nrpn_index_msb | nrpn_index_lsb
post_name( nrpn_index_msb, nrpn_index_lsb )
break
default:
send_cc(cc_index, cc_value)
break
}
}
function post_name( MSB, LSB ) {
// sometimes it seems LSB comes as undefined
LSB = LSB || 0
// Divide by 128 to get the actual CTRL #
MSB = MSB >> 7
// selected parameter map
var param
post("\n")
if( MAPPING[MSB] && MAPPING[MSB][LSB] ) {
param = MAPPING[MSB][LSB]
post( "SELECTED PARAM: " )
post( "\n")
post( param.name )
post( "\n")
post( "RANGE MIN: " + param.range.min )
post( "\n")
post( "RANGE MAX: " + ( ( param.range.max + 1 ) / 16 ) )
}
post("\n")
}
// Send CC: Forward CC index and value to output 0
function send_cc(i, v) {
outlet(0, i, v)
}
// Send NRPN: Send NRPN index and value to output 1
function send_nrpn(NRPN, VALUE) {
// correct output
// outlet(1, NRPN >> 7, NRPN % 128, VALUE)
outlet(1, VALUE, NRPN % 128, NRPN >> 7)
value = null // reset the parsed value
value_lsb = null // reset the LSB of the value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment