Midi controller : different messages between input and output

Hi there.
I try to use a BCR2000 with Ardour to control the main fonctions : basically with ctrl+middle-click.
Assignation works with no problem. I can assign e.g. volume of a track to a knob.

It works perfectly if I only send midi to Ardour. But I experiment problems as soon as I want to have midi feedback.

What I do :

  • Connect BCR midi output to Ardour 's “MIDI Control In” ;
  • Connect BCR midi input to Ardour’s “MIDI Control Out”;
  • Ctrl + middle-click on a volume slider in Ardour ;
  • Move the desired knob on the BCR

What’s happening :

  • I can control Volume in ardour with the knob.
  • BCR receive parameters feedback when I use the Volume slider in Ardour
  • When I use the BCR knob to increment Volume, the Ardour slider is laggy, and slowly increment in a incorrect way. Decrement seems correct. This behavior stops when I disconnect midi feedback → Then I’ ve got normal increment and decrement in Ardour when I use the BCR knob.

What I have found :

  • Monitoring BCR’s midi output and Ardour’s MIDI Control Out gives me the following differences :

    • BCR :

    CC 81, value 1
    CC 81, value 2
    CC 81, value 2
    CC 81, value 3
    CC 81, value 3
    CC 81, value 4
    CC 81, value 4
    CC 81, value 5

    • Ardour :

    CC 81, value 1
    CC 81, value 2
    CC 81, value 3
    CC 81, value 4

Ardour here sends back different values that the ones it receives. It results in unexpected jumps in values because BCR updates its values with the feedback it receives.

To go deeper :
When I midi-send “value 0” to Ardour volume, , volume is set to -inf and sends back value 0 ( only one-time after setting volume to -inf).
When sending “value 1” to Ardour, volume is set to -inf, nothing is sent back.
When sending “value 2”, volume is set to -84.1 and sends back “value 1”, which is incorrect.

This is not only with BCR, others controllers acts as well, and in any case I believe that midi monitoring doesn’t lie → Output is different than input.

I’ve tried to adapt the “Smoothing” parameter in Generic MIDI, but no good result.
Trying smoothing=1 is worst and makes midi control unusable.

Another test : Try to map a midi button to e.g. arm recording button .
The arm button needs the midi value 127 to be both activated or deactivated . But it sends back 127 when activated and 0 when deactivated.
This is a wrong behavior.
We can set a midi button to send 127 each time we press it, so this way it will correctly control arm recording in Ardour, but feedback is wrong and the button’s led will be always off.

That is correct behaviour I would expect. The feed back would be meaningless unless it was so. The MIDI sent to Ardour from a button may be set to either toggle or set value. The MIDI spec would suggest that a note on event would be translated to a toggle, That is a note on with velocity higher than 64 would mean toggle and a cc higher than 64 would be on and less than 64 would be off. (the bcf2000 sends mostly noteon events, I am not sure about the BCR2000) However, the led’s on the BCF needs over 64 (127 in this case) for on and 0 for off. (the BCF2000 might use 1 for flash in mackie mode).

For the problems in the first message: A) I am not really sure what you mean. It is not abnormal for Ardour to send a message only once as feed back because it sends feedback when a value is changednot when the controller sends it an event. That is, if the controller sends a noteon that turns record enable on, Ardour will turn record enable on and send a message showing that change. If the controller turns the record enable on a second time there will be no feedback at all because record enable is already on.
B) I would suggest not using MIDI learn for a controller as complex as the BCR, but rather creating a midi map would be more appropriate. However, it would be ok to create a midi map for most of the comtroller and then use midi learn for left over controls that you may wish to assign on the fly.

I’m not talking about Note on messages here. (BCR/BCF can send every kind of midi messages, even sysex if you want).

I may misunderstand midi feedback, but this is not what I expect. Not in the case of CC at least. If changing of some value in Ardour is triggered by a midi CC value, I expect the same value of the same CC to be sent back. Or less/more than 64 in case of a toggle.

What is happening here :

  • In the case of record button, which I believe should have a toggle behavior :
    If I choose to send CC, I need value>=64 to trigger both on and off even if Ardour answers back invariably CC value=127 if record is set on and CC value=0 if record is set off. But that’s no more a problem for me since I’m able to set the right config in the BCR.

  • But in the case of volume slider, this is more problematic.
    Presuming volume is at -inf : If I send a CC with value 0, nothing happens. That’s ok. If I send a CC with value 1, nothing happens. It could seems strange, regarding how poor is a 128 values resolution comparing to a slider in Ardour, but let’s deal with it. Now if I send a CC with value 2, volume change from -inf to -84.1 (which is what we expect), but Ardour sends back a CC with value 1. (and sends 2 when volume update is triggered by 3, and 3 when triggered by 4 …). That feedback is not what a midi controller could expect.

I consider this behavior, as long as someone hasn’t gave me a good explanation for that, as a bug. This is not really a matter of controller, you could test it with a simple midi generator and monitor what happens.

Maybe CC is not the good way to control volume or other things in Ardour, but the BCR unlike the BCF has no Mackie mode. If you know another kind of midi message that is more suitable for this, please let me know.

I’ve forgotten to say that I use ‘Generic MIDI’.

You are right, and it became more obvious now that I’m reading the manual.

I’m not sure how the generic MIDI works, but I presume it detects the category of midi message (the most simple like CC and Note) and adapts its behavior.
In any case a generic CC learning should provide a clean feedback, IMO

I am not sure what you mean by “clean feedback”. In Ardour, clean feedback should mean that when a function that is enabled or disabled is changed, that change is fed back as either 127 or 0. 127 for enabled and 0 for disabled. If the function is continuous, like a fader or pan then the feedback should be the new value from 0 to 127 if it has changed from before. In all cases changed from before means the change could come from the remote controller or the GUI. It also means that if there is no change there is no feedback. So if a record enable is already enabled, sending another enable will not get any feedback because there is no change to report.

In the MIDI standard, a noteon event is expected to be a temporary button press with both an on and an off (the noteoff may be replaced with a noteon with 0 velocity). Ardour therefore ignores the noteoff information and toggles based on the noteon. There is a monentary parameter to change this so that noteon with high velocity will enable and noteoff will disable. There is no way for MIDI learn to set momenary.
In the MIDI standard CC is different. A CC should send the value it wants to set, 127 for on (well anything above 64) and a 0 for off. Any toggling is expected to be done by the controller. Ardour has followed this standard for a long time. With midi map toggling can now be set in Ardour as well but MIDI learn cannot do that.
Many MIDI control surfaces also abuse the midi standard to send encoder information via CC. MIDI learn has no way of knowing that an encoder has send it something rather than a button or a pot so MIDI learn can not deal with encoders either. However midi map can deal with at least 4 kinds of encoder (last I checked).
Variable CC have some oddness. By default, if the next value of CC is too far away from the current value, Ardour will wait until the CC crosses the current value before it accepts new values. This is to deal with things like banking where a CC may be switched from one control to another so there is no sudden jump in value which could be very audible. There are two settings to help control this: Smoothing determines how close the CC has to be to the current value to have “crossed” the current value. Motorized turns this mode off. (a motorized control is expected to be able to follow feedback) I do not know personally what is right… perhaps there is no “right” way to deal with this besides using only motorized or glass controllers.
So far as I know, there has been little work done on generic midi control besides adding new map files for a few years at least.
Also be aware, that while midi learn does attempt to save MIDI controls it has learned with a session save, there are some controls which do not exist at the time the session file is read in and so are not restored. Generic midi mapping does not have this problem.

Hi @lenovens .
Thanks for your good explanations. I understand and agree most all of them.

However I don’t see answers to my questions so I’ll try to reword.

I will deliberately speak about midi learning in Generic Midi mode only and not about midi map.

1. Volume fader :

  • In Generic MIDI, enable feedback and enable motorized. (We don’t care here of jumps in values, we just want to see if feedback has correct behavior)

  • i.e. I choose, using midi learning, CC07 to control the fader.

  • Let’s say that CC07 value ‘v’ is triggering level value ‘n’.
    Of course 0<=v<=127

  • Send CC07 (v).

    • If current level = n, no change, no feedback. This is the expected behavior.

    • If current level != n, change is : new level = n, feedback is : CC07 (v-1) .
      Is this the expected behavior ?
      Shouldn’t it be new level = n ; feedback = CC07 (v) ?

2. On/off parameter like ‘Enable record’ with CC:

Should I understand that user should not use MIDI learn with CC and should prefer to send NoteOn events?
I ask that because if record is enabled and then I send CC with value = 0 (or value < 64), nothing is happening. Is this the expected behavior ?

That does sound like a bug, I would ask if you have tried various values for v though. Internally, the level is stored as a float and 0-127 is converted to 0.0 - 1.0. The feedback goes through the same conversion and it may be possible that some values end up closer to v-1 with this double conversion. So if all feedback values are v-1, That is a bug. If it is only some values, or some values feedback v+1 I suppose that is a bug too but different. If all the odd ones out are -1 it may be possible to adjust the float value before conversion (or after) a small amount so that v-in and v-out are the same. This is not code I looked at in some time (well the conversion code not at all) but I would expect the same thing with midimap as with midi learn.

I would not expect that, however, do check that sending the same CC with value 127 two times in a row does not toggle in the same way a noteon v=127 does. I have not used anything MIDI in a long time and things may have changed. If the CC with value 127 toggles, I would guess that is the “new normal” if I agree it is correct or not.

To be honest, I disliked the idea of midi learn for my use because I came from the mackie control end of things and because, for my use, controlling a particular control just for right now has not been that useful. The main thing I have used is: Start, stop, master record arm. For mixing I normally use the GUI.

Yes I have tried various values and and feedback is always v-1 except for the followings values : v=0 → feedback=0 ; v=127 → feedback=127.
v=1 gives feedback=0 but is also triggering level=(-inf)

Yes CC with value 127 is triggering both on and off features. ( as well as any value >=64 )

It doesn’t make any sense to me since it prevents feedback to work. How do you expect to tell to a hardware toggle to send 127 for both “on” and “off” and in the same time make it to update to “on” when receiving 127 and to “off” when receiving “0” ?

Feedback handling is separate in both the controller (or it should be) and the DAW. The feedback is used for: 1) an indicator (LED for example) 127 is LED on, 0 is LED off. Some controllers accept other values for LED flash or LED colour. 2) Feedback is used to tell a motorized fader where it should motor to or a glass control where it should point to or how an encoder LED ring should light up. Because of this the feed back is always the same, it is an indicator of what the DAW is set to. It does not matter how the control signal is sent (toggle, 1/0, on/off, value or offset from last value for an encoder) The feedback is always the same and this is what any controller I have worked with, expects for feedback. So in a sane world, the controller never turns on it’s own LED indicator unless it knows all feedback is turned off, it expects the DAW to send it a signal to do that. This way, if the controller sends a record enable to a bus, the controller LED is not lit because there is not record enable. This is the same as a MIDI synth. The keyboard part and the sound generation part are totally separate and joined by a MIDI path only (perhaps virtual MIDI path) and the sound generator does not know where the MIDI is coming from it just makes noise to go with that MIDI. The keyboard may have a display but that display is not connected to the buttons that seem to make changes in the display, but rather the sound generator tells the display what the new patch is via internal midi. In the same way, what the Controller sends to the DAW is separate from what the DAW sends to the controller. they are two different things that may have nothing to do with each other.
All that overly long explanation to say that it doesn’t matter if the incoming MIDI is used to toggle a value or set a value, the feedback will always set the value no matter if it is a noteon, CC, pitch bend, etc.

I agree.
It just seems a little weird to me that the ‘off’ value in the daw is triggered by CC value 64<v<127 rather than 0<v<64. Maybe this is done to act as noteOn. Anyway there is workaround so it’s not really a problem.

Number 1. seems like a bug, so if you confirm I could report on the tracker.
FYI the behavior which is induced by this bug is partially discribed in a very old post : Ardour 3 with BCR2000, a strange behaviour on midi feedback.

I really appreciate your long explanations. Maybe the next step to me is to make a good midi map.
Thank you.