I've tidied the whole thing up a lot and pulled a lot of the sections if it out into functions in the JS to make it all more manageable. Consequently there are many more lines of code now so too many probably to just paste here - I've added a file however with all the code in.
Some of this relates to my specific OSC session so it might not work directly but you should be able to work it all out from this and snip out what you need...
Good luck!
Now not needed if you ensure you have send('midi', 'MCU_From_OSC', '/note', 1, 44, 127);
Before anything else in the custom module - this is the cubase MCU handshake
Wow... i just had a look at your js... and wow... just thinking "So many infos ! So much to learn from this !... but when ?.... and when will i get back to real life, now ? "
Just wondering - did you ever get through this little bug?…
If you didn’t I have finally got round to looking at it and have solved it in my CM now - track name extreatted cleanly every time, with no offset or random characters, even when going from midi to instrument or audio tracks… let me know and I’ll post if you need it.
Here you go - it's all down to how the MCU reads and erases characters on the LCD screen - if it knows that there are characters from the previous track it will send spaces, so you have to trim these off.
Here is the full function which you need to call:
function getTrackName(sysExVal) {
var nameDone = false
var d = sysExVal.split(" ").slice(6).map(x => parseInt(x, 16)) //this devides up using .split, then slices off the front 6 elements, and x => parseInt(x, 16) converts the rest from Hex to Int then .map creates the array d[]
pos = d[0] // first byte -> position // hex to int
console.log("position = " + pos)
//console.log("sysExVal = " + sysExVal)
text = d.slice(1).map(x => String.fromCharCode(x))// these are the new characters which are updated on the console, the rest -> updated characters
if (pos < 29) {
return trackNameJoined
}
text.pop() // drop sysex closing byte
trackName = text.join('')
//MCU only sends what it needs so you need to buffer the previous name and use parts of that
//Check the length of the new name vs the buffer
nameLengthCheck = bufferTrackName.length - trackName.length
//MCU sends some sysex data to tell the screen where to start showing the new characters
//This is related to the root position on the screen which is 72
//Check if root position matches the position where the characters are to be placed
charFromStart = pos - rootPosLCD
var lengthCheck = charFromStart + trackName.length
if (lengthCheck < 29) {
let newEndLength = 29 - charFromStart - trackName.length
newEnd = bufferTrackName.substring(bufferTrackName.length - newEndLength)
} else { newEnd = "" }
if (pos == 72) { //Full length name received
trackNameJoined = trackName + newEnd
bufferTrackName = trackNameJoined
posBuffer = pos
// console.log('TrackName Joined = ' + trackNameJoined)
nameDone = true
} else if (pos > posBuffer && posBuffer == 72 && nameDone == false) {
keepStringVal = pos - posBuffer //new name follows a full string text
var prevTrackKeep = bufferTrackName.substring(0, keepStringVal)
trackNameJoined = prevTrackKeep + trackName + newEnd
bufferTrackName = trackNameJoined
posBuffer = pos
nameDone = true
} else {
keepStringVal = pos - rootPosLCD //new name follows a full string text
var prevTrackKeep = bufferTrackName.substring(0, keepStringVal)
trackNameJoined = prevTrackKeep + trackName + newEnd
bufferTrackName = trackNameJoined
posBuffer = pos
nameDone = true
}
//MCU will sometimes send the characters (MIDI) as part of the track name
//so you need to strip these out
const findMidiTag = '(';
var posMidiTag = trackNameJoined.search("\\(M");
var posBrackTag = trackNameJoined.search("\\(");
if (posBrackTag == trackNameJoined.length - 1) {
trackNameJoined = trackNameJoined.substring(0, (posBrackTag - 1))
}
if (posMidiTag > -1) {
trackNameJoined = trackNameJoined.substring(0, (posMidiTag - 1))
}
//trim off all the spaces at the end
trackNameJoined = trackNameJoined.trimEnd();
return trackNameJoined
}
Thanks for sharing the solution. I'm new to OSC and my template only consists of some basic buttons so far triggering commands using Generic Remote. This is way over my head but I'm determined to implement this eventually! Curious @Sub3OneDay what your OSC template looks like.
Wow that's incredible! The Albion look is awesome haha. I'm sure you spent a while on those visualizations, but it looks really great. I may have to bother you at some point if I struggle with the expression maps!
Agreed....
After getting to know OSC
I'm always trying to get a better and even better solution for something...
There're just way too much knowledge to learn
There is quite a lot on the forum already about Using custom modules generally but I'm (very slowly as busy) trying to pull together a step by step on how to implement this specific solution which I will post when done.
I have set up your project with your custom modul. I have installed the node modules xml2js and glob in my custom modul folder and set the right path for glob and the Expression Map
I get the the first text_1 from Cubase with little glitches but ok.
Text_2 makes nothing (recieved from xml)
And no Buttons on the grid.. I have the one expression map in cubase loaded.
Can you please help me were my mistake is?
Thank you very much
As for the text-2 widget, how did you name your expression maps ?
For me, using this : AmpleSound - ASBU - Bass Upright.expressionmap shows ASBU in text_2.
I'm really sorry Barry, but right now i'm "out from o-s-c"... i've spent too much time on it (actually... months... learning everything from 0...)... Custom module is a huge piece i do not master, and to help you with what i know, i would have to dig again into it... but now, i... just can't... I just need to turn off my pc, and have a big big break...
I'll be back for sure, and will be pleased to help you... as soon as possible...
In the meanwhile, have fun exploring this amazing piece of software ! (and don't forget to go for a walk...)