CC value problem

Fredzed

2013-08-05 02:04:25

Hello guys,

I've recently started trying out the translator (trial version for now) and it appears to be amazing in terms of customization possibilities, I'm definitely buying it sooner or later.

But I've become stuck on an issue that I can't seem to get past (I've looked up other threads for similar problems and the golden rules but Nada) which is the following:

I'm trying to control up and down and left and right keystrokes on a single CC# number, using one of the rotaries on my Quneo midi controller (to navigate tracks browser etc on Ableton Live). Problem is I can't avoid the stream of cc values that come up every time i press the rotary, which makes it unreliable for navigation. Here's what I mean (screen attached)

The rotary pad on the Quneo sends location cc# in a circular shape (the pad is actually a circle). I'm simply trying to send 1 keystroke up arrow whenever I press the 12 o'clock position in the rotary (which is between values 8 to 12 more or less). It works BUT whenever i press the rotary i get about 2 and 3 values. In the screenshot, i pressed the rotary 3 times, and as you can see I had 10 outputs of the keystroke left...

First solution i though was using only 1 value input (say b0 62 10) for each keystroke but that doesn't help because it's too tricky to activate, and still produces several keystrokes instead of just one.

Some help on this matter would be greatly appreciated!!
Regards,
Fred
bomeccproblem.jpg
bomeccproblem.jpg (156.16 KiB) Viewed 9771 times

DvlsAdvct

2013-08-05 04:43:33

Hi Fredzed

What you want to do should be very easy using global variables. You would need two translators, one for the press of the key and the other for the release. I'm assuming upon release the velocity or the last byte of the message would be 00. If it isn't, you should be able to use the QuNeo editor to set a Note message to the pad, or some sort of toggle control.

Code: Select all

Translator 1: Left Down
Incoming Message: B0 62 pp
Rules: if pp>0 then Goto "Down"
if pp==0 then exit rules, skip outgoing action
Label "Down"
if g0==1 then exit rules, skip outgoing action
g0=1
Outgoing Signal: Keystroke Left Down

Translator 2: Left Up
Incoming Message: B0 62 pp
Rules: if pp>0 then exit rules, skip outgoing action
g0=0
Outgoing Action: Keystroke Left Up
Let me know if that makes sense.

Fredzed

2013-08-05 12:18:33

That makes perfect sense!
Only with this cc value the last output is never zero unless I'm pressing at 11 o'clock since it's a location cc# but I've already added a note to the pad in the Quneo editor that can make it work like you said. I'm still failing to write some proper rules to say that upon pressing this note, output should be the one cc value. Can you help me with that global variable? Hopefuly I'll get better at writing rules with practise :mrgreen:
Thank you!
Fred

DvlsAdvct

2013-08-05 12:38:52

Hi Fred

If you set it to a proper note signal you can use the Press/Sequence message, just make sure the incoming signal is the note message, not the CC.

If you want the press to send a specific CC then that is as easy as changing the outgoing message from the incoming one. For example, if your incoming note message is 90 40 and your outgoing CC needs to be B0 86 4C then your translator would look like:

Code: Select all

Translator 1: CC Translation
Incoming Message: 90 40 pp
Rules: if pp==0 then exit rules, skip outgoing action
Outgoing Message: B0 86 4C
If you want it to be continuous it gets more complicated, and if you set the 4C message to pp it will have the same velocity as the note velocity.

Hope that helps
J

Fredzed

2013-08-05 12:55:56

Yes that was my initial try at this. Why it doesn't work is that I only need the note to trigger the location CC to send a value, and the note off to skip sending a value, but I need the cc depending on where I press to output 1 key up at 12 o'clock (values between 8 and 12), right at 3 o'clock (values between 25 and 29) and so forth. If I use only note velocity as incoming It works for one keystroke everywhere across the pad, so I can't have 4 buttons in different locations of the pad/location cc#.

Hope that clears what I'm trying to get here? I'm still not even sure if it's possible to do this.
Thanks

DvlsAdvct

2013-08-05 14:24:56

OH! I see what you're trying to get at.

So what you need to do is set translators using rules to designate ranges. Now, assuming these are not going to have a continuous range being sent, just on off, you are going to need to set a series of rules to calculate where you are pressing. So the pad needs to have two note messages (which I believe you can set in the editor for the QuNeo, one for the X and one for the Y axis. Then we'd use the velocity to designate which corner does what.

And out of curiosity, is there any particular reason you are not using their Launchpad Emulator for the four by four grid?

Let me know if you can set the two notes for the pad, x and y, and I will put together what you need :)

Fredzed

2013-08-05 15:10:25

I did explore the Quneo Launchpad Emulation but it wasn't really ideal, using Midi Remote Control Scripts proves unstable forcing me to open and close Live when going through the 16 presets in the Quneo, and that was my ticket to leave midi remote scripts behind and try customize my own buttons and knobs. Which is what brought me to Bome! Very happy to have found it!

Anyway, I figured illustrating my objective could help so here it is. This is 1 of the 2 rotary pads, which I'm trying to control arrows navigation with. It doesn't have X/Y notes, only the possibility of activating note on/ note off (anywhere on the pad), pressure cc (anywhere on the pad), location cc (blue inner circle) and direction cc (which disables location cc).
quneo illustration.jpg
quneo illustration.jpg (124.49 KiB) Viewed 9748 times
And it works! This is what's bugging me, is that this idea works with Bome MT, only I haven't figured how I can filter out the "extra" cc values that my finger triggers when I press the given region of the pad.

What's currently happening is, for example, if I press the top of the rotary, there will be 2 or 4 up arrow triggers, because the location cc outputs every single value in that particular range. All I would need is something else telling this translator to only send 1 of the location cc values every time i press the pad.

Thanks you for your patience!

DvlsAdvct

2013-08-05 15:43:02

Ah well that all makes a lot more sense, and your illustration is perfect. Since I don't know the note you're using we are going to use 90 00 7F/00 for the note on/off, and B0 00 pp for the cc location. Feel free to change these as you need. We are going to use a combination of timers and global variables to force MT to ONLY recognize the first press and its location and ignore all other signals until you the Note Off signal is received. I'm going to assum you are going to want to be able to hold the button and release it, so each button action will need two translators, one for pressing up and one for releasing. Here's what you need:

Code: Select all

Translator 1: Note Press
Incoming Signal: 90 00 7F
Rules: g0=1
Outgoing Signal: Timer Button Press 0ms Delay

[i]This creates a toggle for MT to reference.  The other translators will base themselves around whether or not the button has been released before triggering[/i]

Translator 2: Note Release
Incoming Signal: Timer Button Press
Rules: None
Outgoing Signal: Timer Button release 5ms Delay

[i]This creates a second timer which will already have a reference point (which we'll see) just to deactivate the keystroke[/i]

Translator 2: CC Location
Incoming Signal: B0 00 pp
Rules: g1=pp
Outgoing Signal: None

[i]This creates a reference point for where the rotary is pressed so the timers can trigger the correct keystroke upon press[/i]

Translator 2: Button Up Press
Incoming Signal: Timer Button Press
Rules: if g0==0 then exit rules, skip outgoing action
if g1<8 then exit rules, skip outgoing action
if g1>12 then exit rules, skip outgoing action
g0=0
Outgoing Signal: Key Up Down action

[i]The timer is based off of when you press the button, but the outgoing signal is based off of the position of your finger.  Once the timer triggers and the signal is sent the trigger variable (g0) is reset and it now cannot retrigger until you press it again[/i]

Translator 3: Button Up Release
Incoming Signal: Timer Button Release
Rules: if g1<8 then exit rules, skip outgoing action
if g1>12 then exit rules, skip outgoing action
Outgoing Signal: Key Up Up Action

[i]This translator will trigger upon release and be referencing whatever keystroke action you were previous using (as noted by the cc position) so MT doesn't get confused as to the position of the key.  Since the timer is using a 5ms delay, it should be enough for the keystroke to be sent and then toggled off.  If you are having issues with it then increase the ms delay to see if it becomes more manageable[/i]
Does that all make sense?

Fredzed

2013-08-05 16:09:55

Thank you, that's Perfect!!!! How can I ever repay you? :)

DvlsAdvct

2013-08-05 16:12:01

Buy MT, use it, post your problems, successes and gripes here, and help us build this community up :)

Fredzed

2013-08-05 16:36:06

Will do! :)

Fredzed

2013-08-08 20:14:15

As promised, I now own a Bome MT license! Already creating my ensemble and looking great!

Amazing little detail already: I was thinking of how to redo the LED feedback on my Livid Instruments code, since I turned off the sysex messages which controlled the led rings before, when I realized just 1 translator could do the exact same thing. I had each encoders sending cc from 1 to 32. And I had the led rings over each encoder detached to respond to 33 to 65 (for some reason I couldn't have Leds 1 to 32 on the code, Livid editor software is kind of dodgy).

And my problem was how to make the leds respond to their own encoders again, with Bomes (without making 32 translators...) I tried this without even thinking it could really work just like that:

Translator 1:
From Code
B0 ss oo
Rules:
qq = ss + 32
To Code
B0 qq oo

And it worked!!! Great stuff!

Now I'm kind of in another unrelated bind, due to my limited knowledge of Bomes (and math)
I have a shift button, which is working fine as a standard shift. When it's pressed the combination with other buttons produce different outputs than the single buttons alone. But what I'm trying to do now is a shift button that stays active on pushing the shift button once, and releases on pushing the button again. I have a weird fascination with flipping encoders horizontally, don't ask me why.

Thanks in advance for anyone's help!

DvlsAdvct

2013-08-08 21:44:42

Hi Fredzed

You'd want to use global variables to set this up. Your code would look something like:

Code: Select all

Translator 1: Shift
Incoming Signal: 90 00 7F
Rules: if g0==0 then Goto "Shift On"
if g0==1 then Goto "Shift Off"
Label "Shift On"
g0=1
Exit rules, execute outgoing action
Label "Shift Off"
g0==0
Exit rules, execute outgoing action
Outgoing Action: None
So what this does is cycle the global variable so you can use your shift key as a toggle as opposed to momentary. Make sure you use 7F as the incoming value and not pp or else this will still work as a momentary command. Then just have your g0 (or whatever global variable you use) referenced in the translators you want to change.

That make sense?

Fredzed

2013-08-08 22:50:44

Makes total sense. And works great, Thanks!

I feel like an idiot. I can't apply this same idea you put in to make the led on the shift button be on when shift is on, and off when it's off... Damn.

DvlsAdvct

2013-08-09 00:52:03

You have a few options for this. You can either use a Timer or presets.

Since you mentioned that the LEDs respond to MIDI then we can simply use the global variable to modify the output. If you use a single translator it would look like this:

Code: Select all

Translator 1: Shift
Incoming Signal: 90 00 7F
Rules: if g0==0 then Goto "Shift On"
if g0==1 then Goto "Shift Off"
Label "Shift On"
g0=1
Exit rules, execute outgoing action
Label "Shift Off"
g0==0
Exit rules, execute outgoing action
Outgoing Action: Knob LED Shift Timer 0ms delay

Translator 2: LED Change
Incoming Signal: Knob LED Shift Timer
Rules:
if g0==0 then pp=15
if g0==1 then pp=80
Outgoing Signal: 90 50 pp
Now I'm selecting random values there, but effectively what's happening is the value for g0==0 is the shift-off state, and g0==1 is the shift-on state. Then the outgoing signal is whatever the necessary MIDI signal is that would change the knob's output.

Does that work?
J

Fredzed

2013-08-09 02:01:02

As usual, yes it works!

One last question and I will harass you no more :mrgreen:

I've been testing out the 2 cc values that I can midi map in the same knob and there is this inconvenience in Ableton Live: If I midi map the 2 values to different things, say vol. track 1 and 2, and I put knob 1 down in minimum value, when I flip the encoder (with the shift btn) the value that the track 2 knob will output starts at the last position from knob 1 and not from it's own track.

do you reckon this is something that can be fixed in Bomes?
Cheers,
Fred

DvlsAdvct

2013-08-09 02:18:16

This is where things get complicated (I was worried this was what you were going to try to do), and don't worry about bothering us over here. :)

What kind of control is the knob sending? Is it sending a relative or absolute message? If it's sending an absolute message then we are going to be in a rough spot. If it's sending a relative message then it won't be too difficult.

Thanks
J

Fredzed

2013-08-09 02:22:20

All encoders in the bank I'm currently working on are sending absolute cc, but I can easily switch them to relative with the Code editor, no problem.
Glad to hear that it can be done!

Thanks!
Fred

DvlsAdvct

2013-08-09 17:36:27

Yup, you're going to have to, if you want this to work easily. It CAN be done with Absolute using soft takeover in MT, but I am not a fan of doing that when the software can do it for us.

If you want feedback from Ableton, in case you are going to be using other controls (incl the mouse) to change commands that the QuNeo is giving you feedback on, you are going to need to use feedback from Ableton to update the controller. If you will not be, and you will ONLY be using the QuNeo to control your application, then we aren't going to need to do that.

So the first step is to designate a global variable (g0-gz, h0-hz, i0-iz...n0-nz, y0-yz, z0-zz) for each command you want feedback on, especially if it is being modulated by this shift function. We can do this one of two ways, using presets or timers, to have the controller feedback properly. While I am a bigger fan of presets, we have already begun using timers, so we might as well keep this consistent and clean. Assuming you have changed everything to Rotary knobs, you are only using the QuNeo to control Ableton, and not anything else, I can give you some examples. I am still going to use g0 for the shift function, and I am going to assume that the up command on the rotary is greater than 64, and the down command is less than 64. Since some endless commands can be specific (0/7F or 3F/41) it can be modified to suit your needs.

Code: Select all

Translator 1: Rotary 1 Input
Incoming Signal: b0 00 pp
Rules:if g0==0 then Goto "Shift Off"
if g0==1 then Goto "Shift On"
Label "Shift Off"
if pp>64 then g1=g1+1
if pp<64 then g1=g1-1
Exit Rules, execute outgoing action
Label "Shift On"
if pp>64 then g2=g2+1
if pp<64 then g2=g2-1
Exit Rules, execute outgoing action
Outgoing Signal: Rotary 1 Timer 0ms Delay

Translator 2: Knob 1 in Ableton
Incoming Signal: Rotary 1 Timer
Labels: if g0==0 then Goto "Knob 1"
if g0==1 then Goto "Knob 2"
Label "Knob 1"
qq=45
pp=g1
Exit rules, execute outgoing action
Label "Knob 2"
qq=46
pp=g2
Exit rules, execute outgoing action
Outgoing Signal: B0 qq pp
[i]the qq signal is whatever the MIDI CC's Ableton is looking for for those knobs.[/i]

Translator 3: QuNeo Output
Incoming Signal: Rotary 1 Timer
Rules: if g0==0 then Goto "Knob 1"
if g0==1 then Goto "Knob 2"
Label "Knob 1"
pp=g1
Exit rules, execute outgoing action
Label "Knob 2"
pp=g2
Exit rules, execute outgoing action
Outgoing Signal: B0 00 pp
Does that make sense? It should then update the knobs when you turn them. Since you're going to want to have the button press update the knobs so it's always accurate you're going to need one more translator based off of the previous shift button:

Code: Select all

Translator 4: Knob Update
Incoming Signal: Knob LED Shift
Rules: if g0==0 then pp=g1
if g0==1 then pp=g2
Outgoing Signal: B0 00 pp
Let me know if that makes sense. :)
Thanks
J

Fredzed

2013-08-09 20:36:13

I'm sure this works, but I don't follow, and my knob outputs max to minimum toggle on pressing... My biggest confusion is what sort of routing are all these translators doing ideally?

Fredzed

2013-08-09 20:39:19

My mistake!!!! I got it working:) Thank you!

Kind of hazy on understanding what just happened though.

DvlsAdvct

2013-08-09 20:53:42

Okay, as an explanation:

So our shift translator is changing a global variable based on how many times it is pressed. Press once and g0=1, press again and g0=0. It alternates accordingly. :)

Each virtual knob in Ableton has its own MIDI CC. For this example we will refer to them as CC1 and CC2. The physical rotary knob needs to control each virtual knob, based on the state of the shift button and, by proxy, the g0 modifier (0 for cc1, 1 for cc2). Each CC will have its own value, as a full MIDI message (B0 01 pp and B0 02 pp respectively). Since the state of each knob needs to be stored for MIDI Translator to recall where the software is at, we need to save that last bit of information as a global variable as well (g1 and g2, respectively).

So we should take this in order. The first Rotary translator is receiving the Rotary dial's signal (B0 00 pp in the example below) and checking to see what state the Shift button is in (g0==1 or g0==2). The state of the Shift is going to dictate which variable (g1 or g2) increases when the knob is turned. Now, it is also possible to include the CC message itself (CC1 or CC2) as a global variable, but I don't think that really needs to be stored in this example, and can, instead, be calculated for each message individually. All that really matters is the position of the knob.

So the shift function will dictate which knob goes up or down and will then trigger a timer, activating the next translator. The Knob 1 in Ableton translator will then receive this timer, and cross reference with the initial Shift state. This will dictate which knob gets triggered (qq=45) and THEN check with the global variable recording the knob's position (pp=g1/g2). This translator then sends the correct knob, and that knobs position, to Ableton. Now, this can also be done using a Relative Message in Ableton, but almost the same amount of work will be needed for it to be updated in MT correctly.

The last two translators are tied directly together. The QuNeo Output translator is just outputting the current position of the knob to the QuNeo itself, so you get the correct feedback. This is being done whenever the rotary is turned on the QuNeo, and avoids dealing with Ableton's annoying MIDI feedback (at least in 8, I haven't yet used 9). The last translator forces the hardware to update to the knob that is controlled (CC1 or CC2) based on the shift state (g0). That way whenever you hit the shift button to switch knobs the rotary reads back properly.

That all make a little more sense?

Fredzed

2013-08-09 21:16:57

Sure does! Thanks

Fred

Fredzed

2013-08-10 00:33:02

I think I'm going to stick with absolute mode knobs. Took me two hours to do what I would do in 5 minutes with absolute encoders. It's not ideal to have to reajust knobs every time I touch them, but it's not the end of the world. Is there a simpler way to the whole thing? You mentioned using presets instead of timers, how does that work?

There's also the fact with the relative encoders, if i midi map them to say a volume track, they don't constraint to the -oo to +6 db maximum and min values, so there's another half hour lost :) Thanks for helping out but I'll stick with the easy route for now.
Fred

DvlsAdvct

2013-08-10 21:32:53

If you want to constrain them you only need to insert rules for it. For example, in the translator that counts the global variables (Rotary 1 Input) add two entries for each shift layer:

Code: Select all

Translator 1: Rotary 1 Input
Incoming Signal: b0 00 pp
Rules:if g0==0 then Goto "Shift Off"
if g0==1 then Goto "Shift On"
Label "Shift Off"
[i]if g1>=127 then g1=127
if g1<=0 then g1=0[/i]
if pp>64 then g1=g1+1
if pp<64 then g1=g1-1
Exit Rules, execute outgoing action
Label "Shift On"
[i]if g2>=127 then g2=127
if g2<=0 then g2=0[/i]
if pp>64 then g2=g2+1
if pp<64 then g2=g2-1
Exit Rules, execute outgoing action
Outgoing Signal: Rotary 1 Timer 0ms Delay
and it should lock it to the set range of the volume meter. If you still want to use the Absolute values, then that's fine. Everything is almost identical except you don't need the Rotary Input translator. It can be done with just the others. Just remove the pp=g1 and pp=g2 entries and it should pass through just fine, and set the Incoming Signal to the rotary MIDI CC. It would look like:

Code: Select all

Translator 2: Knob 1 in Ableton
Incoming Signal: B0 00 pp
Labels: if g0==0 then Goto "Knob 1"
if g0==1 then Goto "Knob 2"
Label "Knob 1"
qq=45
Exit rules, execute outgoing action
Label "Knob 2"
qq=46
Exit rules, execute outgoing action
Outgoing Signal: B0 qq pp
That make sense?
Thanks
J

Fredzed

2013-08-11 17:55:50

That's cool. And works fine, except for the LED feedback on pressing shift (The led feedback on the shift button works fine!!). It's just every time I press shift the value on the encoder led goes back to zero, whether it's the shifted or non shifted cc...

DvlsAdvct

2013-08-11 23:09:11

Weird. What does your QuNeo output translator look like?