Is there a posibility to send midi from Visual Neo? - Forum

Forum Navigation
You need to log in to create posts and topics.

Is there a posibility to send midi from Visual Neo?

Hey everyone, i want to know if there is a way to implement sending Midi data like a cc note to a device from a button in visual neo,
I am not so good in Javascript and am looking for a way to communicate with midi devices via a software application and if possible within visualneo web.

Cheers i hope some of you may know something or a workaround,

 

Thanks in advance!!

I have found this, is there a way to implement it and make it configure-able? sorry if i ask alot, thanks in advance!

https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API

Hi @sinmorph,

I think this library is probably a better option:

http://webmidijs.org/

I don't have any knowledge about MIDI devices but this library should be easily integrated into VisualNEO Web

sinmorph has reacted to this post.
sinmorph

Thanks i will look into it and see if i can find a way, cheers!

Hey!! i think i found something, is it possible to load in this Javascript and enable it, and can you maybe explain how i can read from these to query their function?

i have never used javascript before and have a very low code experience, and sadly i cannot learn due to discalculy dysfunction, but i do see sometimes what it does, thats why i ove visua neo, becasue its visual ;)Thi is the javascript i found;

const DEBUG = true

export var access
var midiOut
var globalChannel

export async function getAccess() {
try {
if (!access) {
// First try to get MIDI access, will throw error if fails
access = await navigator.requestMIDIAccess()
}
return access
} catch (err) {
console.error('MIDI getAccess failed', err)
}
}

// =====================================================================================
// Configure globals used by MIDI, the output device and any global channel
// =====================================================================================
export function setup(deviceId = 'output-1', globalChan = 0) {
midiOut = deviceId
globalChannel = globalChan
}

// =====================================================================================
// Send MIDI note ON
// =====================================================================================
export function sendNoteOn(note, chan = 1, velo = 127) {
if (!midiOut) return
const channel = globalChannel > 0 ? globalChannel : chan

checkValue(note, 'note')
checkValue(velo, 'velocity')
checkChannel(channel)

if (DEBUG) console.debug(`MIDI note on - note:${note}, velo:${velo}, channel:${channel}`)
midiOut.send([0x90 + (channel - 1), note, velo])
}

// =====================================================================================
// Send MIDI note OFF, default velocity is zero
// =====================================================================================
export function sendNoteOff(note, chan = 1, velo = 0) {
if (!midiOut) return
const channel = globalChannel > 0 ? globalChannel : chan

checkValue(note, 'note')
checkValue(velo, 'velocity')
checkChannel(channel)

if (DEBUG) console.debug(`MIDI note off - note:${note}, velo:${velo}, channel:${channel}`)
midiOut.send([0x80 + (channel - 1), note, velo])
}

// =====================================================================================
// Send MIDI controller change
// =====================================================================================
export function sendCC(cc, chan = 1, val = 0) {
if (!midiOut) return
const channel = globalChannel > 0 ? globalChannel : chan

checkValue(cc, 'CC')
checkValue(val)
checkChannel(channel)

if (DEBUG) console.debug(`MIDI control - cc:${cc}, val:${val}, channel:${channel}`)
midiOut.send([0xb0 + (channel - 1), cc, val])
}

// =====================================================================================
// Send MIDI pitch bend
// =====================================================================================
export function sendPitchBend(chan = 1, val = 0) {
if (!midiOut) return
const channel = globalChannel > 0 ? globalChannel : chan

checkChannel(channel)

// I have no idea if this 14 bit stuff works...
const val_msb = Math.floor(val / 128)
const val_lsb = Math.floor(val % 128)

if (DEBUG) console.debug(`MIDI pitchbend - val_msb:${val_msb}, val_lsb:${val_lsb}, channel:${channel}`)
midiOut.send([0xe0 + (channel - 1), val_msb, val_lsb])
}

// =====================================================================================
// Send series of messages for a NRPN change
// =====================================================================================
export function sendNRPN(bytePair, chan = 1, val = 0, highRes = false) {
if (!midiOut) return
const channel = globalChannel > 0 ? globalChannel : chan

try {
const bytes = bytePair.split(',')
const lsb = parseInt(bytes[0].trim())
const msb = parseInt(bytes[1].trim())

checkValue(lsb, 'NRPN LSB')
checkValue(msb, 'NRPN MSB')
checkChannel(channel)

// Send two messages to select which NRPN we are updating
midiOut.send([0xb0 + (chan - 1), 0x63, msb])
midiOut.send([0xb0 + (chan - 1), 0x62, lsb])

if (DEBUG) console.debug(`MIDI nrpn - lsb:${lsb}, msb:${msb}, val:${val}, channel:${channel}, highRes:${highRes}`)

// Handling of high res values (e.g. greater than 127 or 14-bits)
// This has been tested on a Novation Ultranova, not sure if this is MIDI standard
if (highRes) {
if (!Number.isInteger(val)) throw 'Bad value'
const val_msb = Math.floor(val / 128)
const val_lsb = Math.floor(val % 128)
// Send two messages to set both LSB and MSB of high res 14 bit value
midiOut.send([0xb0 + (chan - 1), 0x06, val_msb])
midiOut.send([0xb0 + (chan - 1), 0x26, val_lsb])
} else {
checkValue(val)
// Send one message (CC 6) to set value
midiOut.send([0xb0 + (chan - 1), 0x06, val])
}
} catch (err) {
console.warn('Malformed NRPN, it should be two integers separated by commas:', bytePair, val)
}
}

// =====================================================================================
// Send MIDI program change with bank select
// =====================================================================================
export function sendProgChange(bytePair, chan = 1, progNum = 0) {
if (!midiOut) return
const channel = globalChannel > 0 ? globalChannel : chan

try {
const bytes = bytePair.split(',')
const lsb = parseInt(bytes[0].trim())
const msb = parseInt(bytes[1].trim())

checkValue(lsb, 'Bank LSB')
checkValue(msb, 'Bank MSB')
checkChannel(channel)

if (DEBUG) console.debug(`MIDI prog change - lsb:${lsb}, msb:${msb}, progNum:${progNum}, channel:${channel}`)

// Send three messages two for bank select and one for prog change
midiOut.send([0xb0 + (channel - 1), 0x00, msb])
midiOut.send([0xb0 + (channel - 1), 0x20, lsb])
midiOut.send([0xc0 + (channel - 1), progNum])
} catch (err) {
console.warn('Malformed program change number, it should be two integers separated by commas:', bytePair, progNum)
}
}

// =====================================================================================
// Validation functions
// =====================================================================================
function checkChannel(channel) {
if (!(channel > 0 && channel <= 16 && Number.isInteger(channel))) {
throw `MIDI channel '${channel}' is invalid, should be an integer between 1 and 16`
}
}

function checkValue(value, type = 'value') {
if (!(value >= 0 && value <= 127 && Number.isInteger(value))) {
throw `MIDI value '${value}' for '${type}' is invalid, should be an integer between 0 and 127`
}
}

I think i have found a way to load it in, but hwo do i define it and call its functions with say a button in visual neo web?

Uploaded files:
  • You need to login to have access to uploads.

Is this maybe a way?

Uploaded files:
  • You need to login to have access to uploads.

@sinmorph the code you have included seems to be ECMAScript 6, and using it is a bit tricky.
Where have you found the code you have shared?
I need to see some documentation.

its a snippet from this project;

https://github.com/benc-uk/touchmidi