Send Parameter values as ASCII?

I´m trying to do a basic remote for the performance EDIT functions of the KORG Wavstation A/D. The parameter values need to be send as 7 bit ASCII code. Is there a way to have a fader on ELECTRA sending out its values as ASCII code (which means that a single value like “56” must be send as 2 conscutive 7 bit bytes saying "5 " / “6”.
Any help is appreciated.

hi, I don’t know the specifics but if you are talking about hex values then this are so called nybbles.

Do you have an example message?

In the documentation you can find some info on sysex etc.

cheers

@Flyweight is correct. If you have an example working message or can point to some existing MIDI specification, it makes helping out much easier.

as I said, the values need to be send as 7 bit ASCII for each decimal in the synth parameter value. So if a parameter in the synth should be set to 56 (decimal) you must send: 0110101 (ASCII “5”) followed by 0110110 (ASCII “6”)


So the question was, if it is possible to have a fader in Electra that sends more than just one byte for each of its value.

Ah interesting. After the Mirage I thought I seen it all :slight_smile:

I do not think you can do this without LUA.

Some idea would be:

hex 30 = DEC 48, if you substract 30h from the hex you have the decimal.
Or even better just discard the 1st 4bits. ( just learned this for @oldgearguy )

ASCII table

HEX BIN DEC
30 00110000 0
31 00110001 1
32 00110010 2
33 00110011 3
34 00110100 4
35 00110101 5
36 00110110 6
37 00110111 7
38 00111000 8
39 00111001 9

Check: Electra One App

It contains some thing useful.

  1. if you give you parameter number the same in your template as the one on the synth there is code that shows how to nybbelize the parameter number
  2. There is the part that takes 4 bits off.

Don’t really understand the 7F and why you would need 16 chars to express 379 parameters.
128 bit means you could send dup to
The parameter number in the opcode looks to be 2 4bit nybbels.

So Its possible but with LUA.
If you know the specifics you would create a LUA function that generate the message.
You then hook up this function to virtual controls in your template.

So if you define a control as a sysex thing, you can embed one or more calls to a LUA function to dynamically generate the data you need.
However - the LUA function as called from the control like that can only return a single value; you cannot return an array (tends to lock up the E1 and my Chrome browser when I try it).

The reason you may need more than one value is because 0 → 127 (or whatever) returns 1,2, or 3 ASCII character representations.

The best way to handle it is to declare the control a virtual function, then in the “function” area (just below formatter in the definition), call a function to create the entire sysex message that you want (including the MIDI channel number, LSB and MSB of the parameter number, and as many values as needed, then call midi.sendSysex() to send the message each time

1 Like

I agree with @Flyweight that this is the weirdest way so far. I guess the idea was to encode numbers to 7bits bytes :slight_smile:

There are more ways to do that, as mentioned by @oldgearguy. I think the best way is to use the virtual parameter along with a Lua function that compiles whole SysEx message.

Again, there are many ways to compose the message in Lua. You can use processing the strings or calculating the bytes with math. The following code is a simplified demo of one way to do that:

function sendSysex(valueObject, value)
    local sysexBytes = { 0x42, 0x30, 0x28 }
    local asciiBytes = toAsciiByteArray(value)

    for _, value in ipairs(asciiBytes) do
        sysexBytes[#sysexBytes + 1] = value
    end

    printSysexMessage(sysexBytes)
    midi.sendSysex(PORT_1, sysexBytes)
end

function toAsciiByteArray(value)
    local arrayOfAsciiBytes = {}
    local valueText = tostring(math.floor(value))

    valueText:gsub(".",
        function(digit)
            table.insert(arrayOfAsciiBytes, digit + 0x30)
        end)

    return arrayOfAsciiBytes
end

function printSysexMessage(bytes)
    print("--")
    for _, value in pairs(bytes) do
      print("byte to send:" .. value)
    end
end

The sendSysex function merges the header bytes 0x42, 0x30, 0x28 with the ascii value bytes created with toAsciiByteArray function. The final message is printed and send as a SysEx message to the Port 1. Note, I skipped processing of the parameter number and other details. I wanted to point out the main idea.

toAsciiByteArray converts current numeric value to array of ascii characters. This one uses string processing as it is easier to read. You could, however, use also a combination of / a % by 10 to convert digits to an array of digits.

printSysexMessage just dumps the bytes to the debugger log window.

The MIDI Console can be used to verify you got your output right:

It all feels strange and complicated indeed. A good message is, we can do that with E1 :slight_smile:

3 Likes

I love coming to this site.

This small function from Martin caused me to pull up multiple pages of LUA programming tutorials to figure out exactly how it does the job.
Beautifully compact useful function.

Also - it handles any number from a single digit to thousands without any extra effort. The math method (divide, modulo) requires some extra work to handle numbers higher than 99.

So, from one post, I learned about character matching patterns, using a function as an argument to gsub, and a quick refresher why using the for with iterators saves keeping track of the number of items in the array.

3 Likes

Wow this is elegant! well done Martin!
I studied this code and there are few things new to me and look forward to play with.
Like calling a method using : and passing a function to gsub.

This is chatgpt’s explanation.

`In Lua, the : operator is used to call a method on an object. When you use the : operator, you are essentially passing the object as the first parameter to the method.

For example, in the code snippet valueText:gsub(".", function(digit) ... end),
valueText is the object on which the gsub method is called. The . character specifies the pattern to match in valueText, and the second argument is a function to be executed for each match.