Hello everybody,
iam currently working on a preset for the Waldorf RackAttack.
The sysex-message is looking like this:
[F0 3E 11 00 20] [20 00 00] [27] [01 68] [F7] (Value 1)
[F0 3E 11 00 20] [20 00 00] [27] [7F 66] [F7] (Value 1270)
Header | … | Parameter | 2 value in 2 bytes | End
Its really crazy because the value is represented by two numbers. That is no 14bit-value - there are two separate bytes incremented linear each by the parameter. The offset of the second byte is 64.
So, how can i control two bytes by one fader in the preset editor? I tried to put the value two times in the sysex-sequence and shift the first one by 6 bytes (+64) but it doesnt work.
Does anyone have an idea?
I wasn’t aware parameters on the RackAttack could be larger than 7 bit values. Can you give the name of a parameter whose value goes beyond 127 in its sysEx message? Preferably the one you provided the sysex for .
Can you also provide a screenshot on how you set up the bit extraction for the MSB byte in the E1 editor?
Thats the point: I think there are no values larger than 7bit values.
But when I change the cutoff parameter on the device, it sends two new values that seem to be independent of each other.
The second to last byte is the normal parameter value. The byte before it is the parameter value + offset of 64.
I have no idea why it was done that way. However, I still have to somehow calculate this second value and place it in the sysex message.
I had a successfull message for the cutoff parameter today. The second data byte needs to be calculated via lua script.
But i found out that the offset of this second byte shifts with the parameter id. Its reminds on the enigma machine … wtf? However, i need to find out the parameter id of the current control. I tried all the things from the forum here but nothing works. Does anyone has an idea?
function secondByte( valueObject, value )
local message = valueObject:getMessage()
local currentParameter = message:getParameterNumber()
print (currentParameter)
return value
end
The debugger tells me:
error running function 'runTemplateFunction': ctrlv2/slots/p019.lua:3: attempt to call a nil value (method 'getMessage')
I thought what your are looking at is a checksum. It’s a byte calculated on the totality of the payload. This is meant to prevent corrupt messages entering your machine.
But I’ll need to investigate. I have some other Waldorfs but none of them use checksums, so maybe it is something else.
Edit: it is indeed a checksum. This doc might be relevant to you:
http://synth.stromeko.net/docs/Waldorf.pdf
The checksum is calculated on the combination of the command and its data.
1.3.6 Checksum
MIDI isn’t a very reliable transport medium. Therefore longer sysex messages are protected by a checksum, which is the sum of all sysex bytes from CMD to the end of MSG truncated to 7 bits (modulo 127).
If the sum calculated from the received bytes and the transmitted checksum differ, something has gone wrong. When the checksum is evaluated, a wrong checksum will cause the complete message to be
ignored.
Notes
• A checksum of 7Fh is always accepted as valid. This can be used if data is altered manually or produced by MIDI control surfaces with limited capabilities. This option should not be employed by editor programs to skip the checksum calculation.
• On some models or for some message types the command or the first bytes of the message are not included in the checksum calculation or no checksum is required – check the model specific MIDI
implementation for details.
• Not all Waldorf gear actually evaluates the checksum for all datatypes when receiving data, even when a checksum byte is defined to be present. Thus corrupt messages can get through and may
lead to unexpected reactions. If a corrupt sound program is stored in memory, then selection of that program can reliably crash the synth for instance.
1 Like
Thanks for your help! Thats very interesting.
In order to calculate the checksum i need to find out the parameter number via LUA. Do you have any idea how i can do this? Is their any API documentation about classes and methodes of the Electra One?
This is the code I use when I need to build a specific checksum.
The same framework I’ve used elsewhere also.
First I make 2 functions: one that calculates a checksum where the payLoad is a table (a string of bytes) and the result is a byte. Mind you, your checksum algorithm is different than in this example.
The second function concatenates 2 tables into 1.
function calcChecksum(payLoad)
local result = 0
for i= 0, #payLoad do
result = result + payLoad[i]
end
return (-result) & 0x7F
end
function concat(t1,t2)
local table = {}
for i=1,#t1 do
table[#table+1] = t1[i]
end
for i=1,#t2 do
table[#table+1] = t2[i]
end
return table
end
Then ultimately I build my sysex based on some header, the payload and the checksum :
local checkSum = {calcChecksum(sysExPayload)}
midi.sendSysex (devPort, concat(sysExHeader,concat(sysExPayload,checkSum)))
And here is typical code to extract parameter or control data out of a valueObject:
function compLevel (valueObject, value)
local message = valueObject:getMessage ()
local parameterNumber = message:getParameterNumber()
local control = valueObject:getControl()
local ctlId = control:getId()
...
1 Like
Thanks so much!
I found out that there is already a checksum block for Waldorf in the visual sysex editor and it works pretty fine. But iam sure your code snippets will help me on further projects. With the E1 you can control every MIDI-device and thats great.
1 Like
If anyone interested to check my editor template for the Waldorf RackAttack, try it here:
https://app.electra.one/preset/EyyBtuyppb3KyAWxPMwB
4 Likes