I have a control surface encoder that sends B0 0A pp (pp= 0x01 thru 0x7F). I am expected to send this encoder data to a software knob expecting to see Mackie encoder data. Here is the explanation:
Mackie:
B0, 1i, XX
i V-Pot ID (00—07)
XX delta value in the form of ( 0 s v v v v v v )
s direction bit:
0 = clockwise,
1 = counter clockwise
vv number of ticks
Examples:
• B0, 10, 01 = V-Pot Ch. 1 is being turned clockwise by one
tick.
• B0, 17, 47 = V-Pot Ch. 8 is being turned counter-clockwise by 7 ticks.
So basically I’m trying to translate the linear encoder data to this Mackie encoder data and I’m a little stumped on how to do this. Any help is greatly appreciated
I use the global variable ga for the last known value of the incoming absolute encoder.
The example is only for the first encoder, you will need to set up a different global variable for each encoder. I document and initializes global variable used in this project in the rules of translator 0.2
Translator 2.0 is the translator used for conversion.
You can learn more about aliases from this tutorial.
Here are the rules with comments.
// Positive Movement
if pp>ga then tt=pp-ga
// Negative Movement
if pp<ga then tt=ga-pp
if pp<ga then tt=tt|64
// lower end
if pp==0 then tt=65
//higher end
if pp==127 then tt=1
//update for next iteration
ga=pp
// no higher than 127
if ga>127 then ga=127
// no lower than 0
if ga<0 then ga=0
Log "Log outgoing value is 0x%02x tt%"
Here is an update after some trial and error for anyone who is looking to map an absolute encoder (1-127) to a Mackie/MCU encoder. I have changed the rules to match the absolute encoder rotation with it’s corresponding 15 LED Ring, so both the absolute encoder and software encoder match throughout the entire scale.
I needed to create 2 translators where each one will ONLY function if it detects either the clockwise OR counter clockwise rotation of the hardware encoder. When the software encoder was rotated to send data back to the hardware encoder, and the hardware encoder was rotated again, there was a random value that made the software encoder skip to an incorrect position.
A third translator for LED return from software is to update the hardware encoder 15 LED Ring position
[x] Preset 5: PANS 1-8
[x] Translator 5.0: Pan 1-8
Options: swallow
Incoming: MIDI yy 0A zb, on port V-Control Midi Mode
Rules:
// Ensure pp is within the valid range
if zb==0 then zb=1
// Avoid division by zero issues
if zb==127 then zb=126
// Scale pp (1-127) to a 0-40 range using integer math
ga=zb-1
// Adjust pp to start from 0
ga=ga*40
// Scale up to match the target range
ga=ga/126
// Scale down to fit within 0–40
// ga now holds the scaled value, use it for scaled_pp
// Calculate tt based on scaled_pp (stored in ga) and za (previous value)
if ga>za then tt=ga-za
if ga<za then tt=za-ga
if ga<za then tt=tt|64
// Set direction bit for decrement
// Handle special cases
if zb==1 then tt=65
if zb==126 then tt=1
// Update za with the new scaled value
za=ga
// Ensure za stays within 0–40 range
if za>40 then za=40
if za<0 then za=0
if yy==176 then zz=16
if yy==177 then zz=17
if yy==178 then zz=18
if yy==179 then zz=19
if yy==180 then zz=20
if yy==181 then zz=21
if yy==182 then zz=22
if yy==183 then zz=23
if yy<=175 then exit rules, skip Outgoing Action
if yy>=184 then exit rules, skip Outgoing Action
if zz<=15 then exit rules, skip Outgoing Action
if zz>=24 then exit rules, skip Outgoing Action
//This rule prevents software encoder skipping due to rogue
//values after adjusting hardware encoder.
if tt!=65 then exit rules, skip Outgoing Action
Outgoing: MIDI B0 zz tt, to port Bome Virtual Port 1
[x] Translator 5.1: Pan 1-8
Options: swallow
Incoming: MIDI yy 0A zb, on port V-Control Midi Mode
Rules:
// Ensure pp is within the valid range
if zb==0 then zb=1
// Avoid division by zero issues
if zb==127 then zb=126
// Scale pp (1-127) to a 0-40 range using integer math
ga=zb-1
// Adjust pp to start from 0
ga=ga*40
// Scale up to match the target range
ga=ga/126
// Scale down to fit within 0–40
// ga now holds the scaled value, use it for scaled_pp
// Calculate tt based on scaled_pp (stored in ga) and za (previous value)
if ga>za then tt=ga-za
if ga<za then tt=za-ga
if ga<za then tt=tt|64
// Set direction bit for decrement
// Handle special cases
if zb==1 then tt=65
if zb==126 then tt=1
// Update za with the new scaled value
za=ga
// Ensure za stays within 0–40 range
if za>40 then za=40
if za<0 then za=0
if yy==176 then zz=16
if yy==177 then zz=17
if yy==178 then zz=18
if yy==179 then zz=19
if yy==180 then zz=20
if yy==181 then zz=21
if yy==182 then zz=22
if yy==183 then zz=23
if yy<=175 then exit rules, skip Outgoing Action
if yy>=184 then exit rules, skip Outgoing Action
if zz<=15 then exit rules, skip Outgoing Action
if zz>=24 then exit rules, skip Outgoing Action
//This rule prevents software encoder skipping due to rogue
//values after adjusting hardware encoder.
if tt!=1 then exit rules, skip Outgoing Action
Outgoing: MIDI B0 zz tt, to port Bome Virtual Port 1
[x] Translator 5.2: Pan 1-8 LED
Options: swallow
Incoming: MIDI B0 yy pp, on port Bome Virtual Port 1
Rules:
//zc is the output value
qq=pp-1
zc=qq*12
if zc>127 then zc=127
if yy==48 then zz=176
if yy==49 then zz=177
if yy==50 then zz=178
if yy==51 then zz=179
if yy==52 then zz=180
if yy==53 then zz=181
if yy==54 then zz=182
if yy==55 then zz=183
if yy<=47 then exit rules, skip Outgoing Action
if yy>=56 then exit rules, skip Outgoing Action
if zz<=175 then exit rules, skip Outgoing Action
if zz>=184 then exit rules, skip Outgoing Action
Outgoing: MIDI zz 0A zc, to port V-Control Midi Mode, delay:500 millisec
I recommend, however, you use local variables for any time you don’t need globals. In this case, moving two encoders at the same time will cause havoc because you are using mostly global variables.
Steve Caldwell
Bome Customer Care
Also available for paid consulting services: bome@sniz.biz
I set a busy timer to disable feedback while moving the physical encoders. They have local feedback so that works. Then I simply do scaling when I move the V-POTs on the DAW.
If your controller does not have local feedback, then enable translator 2.3 and it will provide local feedback for you.
I use the global variables g0-g7 to hold their current value and ga for the busy flag. When ga==1 then feedback is disabled from the DAW. I set it back to 0 after stopping any encoder for 500ms.