Track color script for Icon P1-X & D4 display

Is there anyone here who can make a script that can send the track color to the display (Icon D4) of the P1-X controller?

Hi @Shikimi,

this might be me – I’ll be working on a V1-M script soon (once my V1-M has arrived, estimated late march) and I expect the MIDI protocol to be identical w.r.t. track colors. I’ll keep you posted here when I get to it.

Cheers!

1 Like

Thank you @bjoluc for the great work on the XTouch, can’t wait to see what you come up with for the P1M/V1M!

2 Likes

Here’s a beta version of the P1-M/P1-X script for you to try out :tada:

2 Likes

Hey @GPnicolett,

yes to all (referring to the beta version from my previous post)!

1 Like

Great! The track colours work now indeed.

Instead of always displaying “Pan,” could it be possible to show the current setting instead? For example, it could display L20, C, or R30. Currently, it shows “Pan” all the time, and you can only see the current setting when you turn a knob. The same issue applies to the volume display.

Hey @bjoluc thanks for setting me straight! Just got a P1-M unit and am testing out the new script. I’ve got it up and working but can’t as of yet get the unit to respect my mix configurations.

Am I doing something wrong on my end or is this a limitation? If so, is it something you plan on adding in the near future? I mostly use this unit to mix from busses, and for various workflow reasons can’t really re-order my session to get the busses in the an order that’s solely compatible with the unit.

I believe the old Cubase MCU support DOES honor mix configs though correct, though I lose auto banking? Believe it or not, I think I need mix configs more than auto banking.

Thanks for doing all this amazing work. Truly fantastic it works so well, even if my particular needs aren’t met.

UPDATE: Saw that this is indeed a limitation of the API (why!!! :flushed:)

@bjoluc, if there’s not support for visibility configurations is there perhaps another way to achieve something similar in a different way?

I don’t know the MIDI remote very well, but if we could simply create custom fader mappings and save them as pages/presets somehow this would , at least for me, do the job.

That’s true. If your workflow is based on mix configs, with the proper mix configs and filters and macros, and with the “spill” (show connected channels), banking is very limited and auto banking is not that important (still, it is a useful feature, don’t get me wrong, and brings cohesion when working both with the keyboard and the surface).

Yeah the main real use for auto banking, for me anyway, is for single fader adjustments. The chances that I’ll have more than 1 fader within 8 of eachother that I have to adjust at one time is super low, unless I’m setup such that all of my busses always mirror what I want my control surface to look like (and I cannot set up my session this way).

My current setup is:

devices: [“extender”, “extender”, “extender”, “extender”, “main”],

It works, but as you can see on the photo, the display doesn’t show correctly.
Can you please help me?

@bjoluc Is this a good place to leave feedback/suggestions/comments on the script?

Any news on the faulty display?

@bjoluc I’m having the exact same issue as @Shikimi , only using 1 P1-M (no extenders) and the display values seem to not be scaled properly for the display, they bleed over:

1 Like

The download of the Beta work isn´t working anymore. Was also for mac or PC?

I also had to add the surface and import the script again after updating the controllers

Does anyone have any idea on how to change the font size of the text in the displays? Is it possible to add this variable to the current script?

(P1-X, P1-M)

Found this JavaScript code here (Icon P1-M: a new very interesting small control surface - #12 by Vindes - Hardware - Gig Performer Community) seems to achieve centring and formatting the text on these smaller displays. One caveat, some people seem to have problems with the SysEx message used here.

The poster also talks about using Mackie messages, might be another avenue? (no clue, Mackie is something I have never have cause to use).

function decimalToHex(decimalNumber, padding = 2) {
    let hex = decimalNumber.toString(16).toUpperCase();
    while (hex.length < padding) {
        hex = '0' + hex;
    }
    return hex;
}

function centerText(text, maxAmount = 8) {
    let spaceAmount = maxAmount - text.length
    let newText = text
    for (let i = 0; i < spaceAmount; i++) {
        if (i < Math.floor(spaceAmount / 2)) {
            newText = " " + newText
        }
        else {
            newText = newText + " "
        }
    }
    return newText
}

function getCenterSpace(str) {
    let indices = []
    for (let i = 0; i < str.length; i++) {
        if (str[i] === ' ') {
            indices.push(i);
        }
    }
    if (indices.length == 1 && indices[0] <= 8 && str.length - (indices[0] + 1) <= 8) {
        return indices[0]
    }
    else if (indices.length > 1) {
        return -2
    }
    else {
        return -1
    }
}

function textToHex(text) {
    let hexValues = [];
    let indexValue;
    let fullText;
    let firstPart;
    let secondPart;
    text = text.trim() // remove space before or after text

    if (text.length < 8) {
        indexValue = text.length % 2 === 0 ? "03" : "01";
        fullText = centerText(text) + centerText("")
        firstPart = centerText(text)
        secondPart = centerText("")
    }
    else if (text.length == 8) {
        indexValue = "02";
        fullText = text + centerText("")
    } else {
        let spaceIndex = getCenterSpace(text)
        if (spaceIndex == -1) {
            firstPart = text.slice(0, 8);
            secondPart = text.slice(8);
            fullText = centerText(firstPart) + centerText(" " + secondPart)
        }
        else if (spaceIndex == -2) {
            firstPart = text.slice(0, 8);
            secondPart = (text.slice(8) + centerText("")).slice(0, 8);
            fullText = centerText(firstPart) + centerText(secondPart)
        }
        else {
            firstPart = text.slice(0, spaceIndex);
            secondPart = text.slice(spaceIndex + 1);
            fullText = centerText(firstPart) + centerText(secondPart)
        }

        // 04 both uneven
        if (firstPart.length % 2 == 1 && secondPart.length % 2 == 1) {
            indexValue = "04";
        }
        // 05 center top row
        else if (firstPart.length % 2 == 1 && secondPart.length % 2 == 0) {
            indexValue = "05";
        }
        // 06 center low row
        else if (firstPart.length % 2 == 0 && secondPart.length % 2 == 1) {
            indexValue = "06";
        }
        // 07 center both rows
        else if (firstPart.length % 2 == 0 && secondPart.length % 2 == 0) {
            indexValue = "07";
        }
        firstPart = centerText(firstPart)
        secondPart = centerText(secondPart)
    }

    // Convert the text to an array of hex values
    let hexText = indexValue + " " + fullText.split('').map(char => char.charCodeAt(0).toString(16).toUpperCase()).join(' ');

    return hexText;
}

function setNames() {
    // after 21, the next 3 values seems to be like a timestamp. end of string might be different for different daw modes
    let introLine = "F0 1D 03 10 07 21 0E 58 32 6D 65 58 12 7A 03 F7\n"
    let outroLines = "EF 7F 7F\n" + "EC 22 06\n" + "F0 1D 03 10 07 24 0E 58 32 6D 65 58 12 7A 03 F7"

    // construct a string to set all fields to note on channel 2, starting from 0
    let constructSendString = ""
    let constructNameString = ""
    for (let i = 0; i < 80; i++) {
        if (i % 28 == 0) {
            if (i > 0) { constructSendString = constructSendString + "F7\n" }
            constructSendString = constructSendString + "F0 1D 03 10 07 25 06 0" + ((i / 28) + 1) + " 1C " + "09 09 00 " + decimalToHex(i+40) + " 7F 00 00 00 "
        }
        else {
            constructSendString = constructSendString + "09 09 00 " + decimalToHex(i+40) + " 7F 00 00 00 "
        }

        let name = textToHex("test " + (i + 1))
        
        if (i % 10 == 0) {
            if (i > 0) { constructNameString = constructNameString + "F7\n" }
            constructNameString = constructNameString + "F0 1D 03 10 07 26 06 0" + ((i / 10) + 1) + " 0A " + name + " "
        }
        else {
            constructNameString = constructNameString + name + " "
        }
    }

    // add settings for device
    constructSendString = constructSendString +
        "09 09 00 30 7F 00 00 00 09 09 00 31 7F 00 00 00 09 09 00 2E 7F 00 00 00 09 09 00 2F 7F 00 00 00 F7\n" +
        "F0 1D 03 10 07 25 06 04 1C 09 09 00 32 7F 00 00 00 00 00 00 00 00 00 00 00 09 09 00 4F 7F 00 00 00 09 09 00 4A 7F 00 00 00 09 09 00 4C 7F 00 00 00 09 09 00 4B 7F 00 00 00 09 09 00 4E 7F 00 00 00 09 09 00 4D 7F 00 00 00 09 09 00 5B 7F 00 00 01 09 09 00 5C 7F 00 00 01 09 09 00 56 7F 00 00 01 09 09 00 5D 7F 00 00 01 09 09 00 5E 7F 00 00 01 09 09 00 5F 7F 00 00 01 09 09 00 00 7F 00 00 00 09 09 00 01 7F 00 00 00 09 09 00 02 7F 00 00 00 09 09 00 03 7F 00 00 00 09 09 00 04 7F 00 00 00 09 09 00 05 7F 00 00 00 09 09 00 06 7F 00 00 00 09 09 00 07 7F 00 00 00 09 09 00 20 7F 00 00 00 09 09 00 21 7F 00 00 00 09 09 00 22 7F 00 00 00 09 09 00 23 7F 00 00 00 09 09 00 24 7F 00 00 00 09 09 00 25 7F 00 00 00 F7\n" +
        "F0 1D 03 10 07 25 06 05 1C 09 09 00 26 7F 00 00 00 09 09 00 27 7F 00 00 00 09 09 00 65 7F 00 00 00 0B 0B 00 10 40 00 00 00 0B 0B 00 11 40 00 00 00 0B 0B 00 12 40 00 00 00 0B 0B 00 13 40 00 00 00 0B 0B 00 14 40 00 00 00 0B 0B 00 15 40 00 00 00 0B 0B 00 16 40 00 00 00 0B 0B 00 17 40 00 00 00 0B 0B 00 3C 40 00 00 00 09 09 00 66 7F 00 00 00 09 09 00 67 7F 00 00 00 09 09 00 68 7F 00 00 00 09 09 00 69 7F 00 00 00 09 09 00 6A 7F 00 00 00 09 09 00 6B 7F 00 00 00 09 09 00 6C 7F 00 00 00 09 09 00 6D 7F 00 00 00 09 09 00 6E 7F 00 00 00 09 09 00 6F 7F 00 00 00 09 09 00 70 7F 00 00 00 0E 0E 00 00 7F 00 00 00 0E 0E 01 00 7F 00 00 00 0E 0E 02 00 7F 00 00 00 0E 0E 03 00 7F 00 00 00 0E 0E 04 00 7F 00 00 00 F7\n" +
        "F0 1D 03 10 07 25 06 06 1C 0E 0E 05 00 7F 00 00 00 0E 0E 06 00 7F 00 00 00 0E 0E 07 00 7F 00 00 00 0E 0E 08 00 7F 00 00 00 09 09 00 60 7F 00 00 00 09 09 00 61 7F 00 00 00 09 09 00 62 7F 00 00 00 09 09 00 63 7F 00 00 00 40 05 00 00 00 00 00 00 40 04 0F 00 00 00 00 00 50 00 00 00 02 00 00 00 50 00 00 00 01 00 00 00 09 09 00 52 7F 00 00 00 09 09 00 53 7F 00 00 00 09 09 00 54 7F 00 00 00 09 09 00 55 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 09 00 64 7F 00 00 00 09 09 00 64 7F 00 00 00 09 09 00 08 7F 00 00 00 09 09 00 09 7F 00 00 00 09 09 00 0A 7F 00 00 00 09 09 00 0B 7F 00 00 00 F7\n" +
        "F0 1D 03 10 07 25 06 07 1C 09 09 00 0C 7F 00 00 00 09 09 00 0D 7F 00 00 00 09 09 00 0E 7F 00 00 00 09 09 00 0F 7F 00 00 00 09 09 00 10 7F 00 00 00 09 09 00 11 7F 00 00 00 09 09 00 12 7F 00 00 00 09 09 00 13 7F 00 00 00 09 09 00 14 7F 00 00 00 09 09 00 15 7F 00 00 00 09 09 00 16 7F 00 00 00 09 09 00 17 7F 00 00 00 09 09 00 18 7F 00 00 00 09 09 00 19 7F 00 00 00 09 09 00 1A 7F 00 00 00 09 09 00 1B 7F 00 00 00 09 09 00 1C 7F 00 00 00 09 09 00 1D 7F 00 00 00 09 09 00 1E 7F 00 00 00 09 09 00 1F 7F 00 00 00 09 09 00 20 7F 00 00 00 09 09 00 21 7F 00 00 00 09 09 00 22 7F 00 00 00 09 09 00 23 7F 00 00 00 09 09 00 24 7F 00 00 00 09 09 00 25 7F 00 00 00 09 09 00 26 7F 00 00 00 09 09 00 27 7F 00 00 00 F7\n" +
        "F0 1D 03 10 07 25 06 08 1C 0B 0B 00 10 40 00 00 00 0B 0B 00 11 40 00 00 00 0B 0B 00 12 40 00 00 00 0B 0B 00 13 40 00 00 00 0B 0B 00 14 40 00 00 00 0B 0B 00 15 40 00 00 00 0B 0B 00 16 40 00 00 00 0B 0B 00 17 40 00 00 00 09 09 00 20 7F 00 00 00 09 09 00 21 7F 00 00 00 09 09 00 22 7F 00 00 00 09 09 00 23 7F 00 00 00 09 09 00 24 7F 00 00 00 09 09 00 25 7F 00 00 00 09 09 00 26 7F 00 00 00 09 09 00 27 7F 00 00 00 0B 0B 00 10 40 00 00 00 0B 0B 00 11 40 00 00 00 0B 0B 00 12 40 00 00 00 0B 0B 00 13 40 00 00 00 0B 0B 00 14 40 00 00 00 0B 0B 00 15 40 00 00 00 0B 0B 00 16 40 00 00 00 0B 0B 00 17 40 00 00 00 09 09 00 20 7F 00 00 00 09 09 00 21 7F 00 00 00 09 09 00 22 7F 00 00 00 09 09 00 23 7F 00 00 00 F7\n" +
        "F0 1D 03 10 07 25 06 09 1C 09 09 00 24 7F 00 00 00 09 09 00 25 7F 00 00 00 09 09 00 26 7F 00 00 00 09 09 00 27 7F 00 00 00 0B 0B 00 10 40 00 00 00 0B 0B 00 11 40 00 00 00 0B 0B 00 12 40 00 00 00 0B 0B 00 13 40 00 00 00 0B 0B 00 14 40 00 00 00 0B 0B 00 15 40 00 00 00 0B 0B 00 16 40 00 00 00 0B 0B 00 17 40 00 00 00 09 09 00 20 7F 00 00 00 09 09 00 21 7F 00 00 00 09 09 00 22 7F 00 00 00 09 09 00 23 7F 00 00 00 09 09 00 24 7F 00 00 00 09 09 00 25 7F 00 00 00 09 09 00 26 7F 00 00 00 09 09 00 27 7F 00 00 00 0B 0B 00 10 40 00 00 00 0B 0B 00 11 40 00 00 00 0B 0B 00 12 40 00 00 00 0B 0B 00 13 40 00 00 00 0B 0B 00 14 40 00 00 00 0B 0B 00 15 40 00 00 00 0B 0B 00 16 40 00 00 00 0B 0B 00 17 40 00 00 00 F7\n"

    constructNameString = constructNameString + "F7\n"

    let text = introLine + constructSendString + constructNameString + outroLines

    let multipleStringsArray = text.split("\n")

    let send = true
    for (let i = 0; i < multipleStringsArray.length; i++) {
        let string = multipleStringsArray[i]

        let stringArray = string.split(" ").map(x => Number("0x" + x))

        if (stringArray.length > 2 && send) {
            sf.midi.send({
                midiBytes: stringArray,
                externalMidiPort: "iCON P1-M V1.07  Port 4"
            })
        }
    }
}
setNames()

Hi guys,

I just found this topic, as I was kind of unhappy with some parts of the P1-M.

I was about to sell it again, and buy something else instead, but this topic here made my day.

I’m grateful for you’re work and I love the Midi remote script.

If the text letters, could be smaller to cover longer track names and some of the mentioned text offsets could be fixed, I would be so happy.

But so far this thing works better than original supplied for me.

Thank’s guys and special thanks to bjoluc!

Keep up that great work!

Cheers!