Jump to content

Converting two CC as sigle data (9bit)


Zam
 Share

Recommended Posts

Hello

 

I'm playing with my midobox_NG system, which is a moving fader prototype.

I'm able to set up a fine .NGC file over mackie control protocol. This protocol use PB as fader data.

But I want to try a .NGC configuration to be HUI compatible, I just don't know how to manage the fader movement data

HUI use two CC in a 9 bit configuration. First (say CC1) in the 0-127 range. Second (say CC2) in 4 step range 0,32,64,96.

Ending in a 128*4 value, 9bit.

How can I listen to this and convert them to a single data (PB? nrpn?) that I can use for AIN and AOUT event.

I read and read ngc configuration user manual and also search at the forum but find nothing, maybe I'm just missing something?

Best

Zam

Link to comment
Share on other sites

Hi,

 

such a function isn't provided by the firmware.

It will only work for the (MIDI compliant) NRPN and Pitchbender events.

Actually Mackie HUI "misuses" the MIDI protocol here, therefore MBNG isn't prepared for this kind of data transfer.

 

Wouldn't it be possible to use better protocols at your side?

DAWs are very flexible today, doesn't it allow you to define your own communication scheme?

 

Best Regards, Thorsten.

Link to comment
Share on other sites

hey Thorsten

 

Tks for reply

 

As I say Mackie control work here, I can leave with this :smile:

The idea using HUI is for two reason

-Protools compatible

-How the solo and mute is managed

 

With MC the mute  (using note) is send instantly to DAW which is fine when I press a physical button to mute DAW track

But I drive a relay with DOUT to achieve a real mute at audio side, unfortunately the returned mute note is delayed (scanned and sent each sec, originally just to light up a led)

I can't use it for "automation", It just work for soloing and muting when working a mix, not for final mixdown.

When tracking data with HUI mode it seem that solo and mute data is send as soon as something is pressed, useful "real time" bidirectional data

 

anyway you say it's not possible so I have to put this out of my mind and accept some limitation/restriction regarding my initial "specification sheet" :rolleyes:

 

Best

Zam

 

Link to comment
Share on other sites

Hi,

 

it isn't impossible, but difficult to implement.

Looking at my backlog for various projects, it could take several months until I will find the time to implement such a challenging feature.

 

So: better don't wait for this and search for alternative solutions.

 

Best Regards, Thorsten.

Link to comment
Share on other sites

Hey Thorsten

 

No pb, don't put this on your "to do" list, the future is most in eucon protocol for protools... if i'm right they already announced the end of HUI support soon (in the mean time it's a real shame !!!)

 

BUT YOU KNOW WHAT !!!!

i think i'm close to fine a solution, for the moment THIS work:

 

EVENT_AINSER id= 1   hw_id=1 ain_mode=direct type=Sysex  chn= 1  range=0:16383 stream=" 0xb0 0x00 ^val_h"
EVENT_AINSER id= 10 hw_id=1 ain_mode=direct type=Sysex  chn= 1  range=0:16383 stream=" 0xb0 0x20 ^val"

 

I'm able to move the DAW fader according to physical one :)

Like HUI, two CC for position, In fact it's 14bit but DAW only retain what he need

 

Now I have to handle the touch (seems to be two CC too) and the AOUT which should be same faked stream as AIN

 

Best

Zam

Link to comment
Share on other sites

An interesting hack! ;-)

 

But it won't work for receiving the values, and this would be a function which would require some firmware extensions (and consume some memory to make it generic)

 

Best Regards, Thorsten.

Link to comment
Share on other sites

  • 2 years later...
On 12/04/2015 at 9:17 PM, TK. said:

Hi,

 

it isn't impossible, but difficult to implement.

Looking at my backlog for various projects, it could take several months until I will find the time to implement such a challenging feature.

 

So: better don't wait for this and search for alternative solutions.

 

Best Regards, Thorsten.

Hey

Long time I don't look at this, but I'm somehow forced to make the moving fader system natively compatible with protool (HUI only...)

I ended today with modification at mbng_event.c alowing NRPN event to handle the dual CC (not in NRPN format)

and it work both way, sending end receiving fader data to/from DAW

As I'm far from good programmer and C expert

here is what I do, input and comment welcome about method I use to achieve this, in case it was completely bad strategy.

to send:

/////////////////////////////////////////////////////////////////////////////
//! Sends a NRPN event. Skips address bytes if they already have been sent!
/////////////////////////////////////////////////////////////////////////////
s32 MBNG_EVENT_SendOptimizedNRPN(mios32_midi_port_t port, mios32_midi_chn_t chn, u16 nrpn_address, u16 nrpn_value, u8 msb_only)
{
  u8 nrpn_address_msb = (nrpn_address >> 7) & 0x7f;
  u8 nrpn_address_lsb = (nrpn_address >> 0) & 0x7f;
  u8 nrpn_value_msb = (nrpn_value >> 7) & 0x7f;
  u8 nrpn_value_lsb = (nrpn_value >> 0) & 0x7f;

  // create MIDI package
  mios32_midi_package_t p;
  p.ALL = 0;
  p.type = CC;
  p.event = CC;
  p.chn = chn;

  // quick&dirty
#if MBNG_EVENT_NRPN_SEND_PORTS_MASK != 0x00f0
# error "Please adapt MBNG_EVENT_SendOptimizedNRPN!"
#endif
#if MBNG_EVENT_NRPN_SEND_PORTS_OFFSET != 4
# error "Please adapt MBNG_EVENT_SendOptimizedNRPN!"
#endif
    
      // NRPN special handling for HUI fader data
      // FADER 1
      if( nrpn_address == 0 ) {
          p.cc_number = 0x00; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);


          p.cc_number = 0x20; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
      // FADER 2
      if( nrpn_address == 1 ) {
          p.cc_number = 0x01; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);
      
      
          p.cc_number = 0x21; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
      // FADER 3
      if( nrpn_address == 2 ) {
          p.cc_number = 0x02; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);
          
          
          p.cc_number = 0x22; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
      // FADER 4
      if( nrpn_address == 3 ) {
          p.cc_number = 0x03; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);
          
          
          p.cc_number = 0x23; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
      // FADER 5
      if( nrpn_address == 4 ) {
          p.cc_number = 0x04; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);
          
          
          p.cc_number = 0x24; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
      // FADER 6
      if( nrpn_address == 5 ) {
          p.cc_number = 0x05; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);
          
          
          p.cc_number = 0x25; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
      // FADER 7
      if( nrpn_address == 6 ) {
          p.cc_number = 0x06; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);
          
          
          p.cc_number = 0x26; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
      // FADER 8
      if( nrpn_address == 7 ) {
          p.cc_number = 0x07; // Data MSB
          p.value = nrpn_value_msb;
          MIOS32_MIDI_SendPackage(port, p);
          
          
          p.cc_number = 0x27; // Data LSB
          p.value = nrpn_value_lsb;
          MIOS32_MIDI_SendPackage(port, p);
      }
 


  return 0; // no error
}

to receive:

    // track NRPN event
    if( port_mask & MBNG_EVENT_NRPN_RECEIVE_PORTS_MASK ) {
      int port_ix = (port_class | (port & 3)) - MBNG_EVENT_NRPN_RECEIVE_PORTS_OFFSET;
      if( port_ix >= 0 && port_ix < MBNG_EVENT_NRPN_RECEIVE_PORTS ) {
          // NRPN special handling for HUI fader data
        switch( midi_package.cc_number ) {
                
        case 0x00: { // Address MSB FADER 1
            nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
            nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
            nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
            nrpn_address = 0;
            nrpn_msb_only = 1; // for the MsbOnly format
#if 0
            // MEMO: it's better to update only when LSB has been received
            if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                midi_learn_nrpn_port = port;
                midi_learn_nrpn_chn = midi_package.chn + 1;
                midi_learn_nrpn_valid = 0;
            } else {
                // only if valid address has been parsed
                midi_learn_nrpn_valid |= 0x04;
            }
#endif
        } break;

        case 0x20: { // Address LSB
            nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
            nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
            nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
            nrpn_address = 0;
            
            if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                midi_learn_nrpn_port = port;
                midi_learn_nrpn_chn = midi_package.chn + 1;
                midi_learn_nrpn_valid = 0;
            } else {
                // only if valid address has been parsed
                // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                midi_learn_nrpn_valid |= 0x04;
            }
            
            
        } break;

            case 0x01: { // Address MSB FADER 2
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
                nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 1;
                nrpn_msb_only = 1; // for the MsbOnly format
#if 0
                // MEMO: it's better to update only when LSB has been received
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    midi_learn_nrpn_valid |= 0x04;
                }
#endif
            } break;
                
            case 0x21: { // Address LSB
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
                nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 1;
                
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                    midi_learn_nrpn_valid |= 0x04;
                }
                
                
            } break;
                
            case 0x02: { // Address MSB FADER 3
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
                nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 2;
                nrpn_msb_only = 1; // for the MsbOnly format
#if 0
                // MEMO: it's better to update only when LSB has been received
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    midi_learn_nrpn_valid |= 0x04;
                }
#endif
            } break;
                
            case 0x22: { // Address LSB
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
                nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 2;
                
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                    midi_learn_nrpn_valid |= 0x04;
                }
                
                
            } break;
            
            case 0x03: { // Address MSB FADER 4
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
                nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 3;
                nrpn_msb_only = 1; // for the MsbOnly format
#if 0
                // MEMO: it's better to update only when LSB has been received
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    midi_learn_nrpn_valid |= 0x04;
                }
#endif
            } break;
                
            case 0x23: { // Address LSB
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
                nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 3;
                
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                    midi_learn_nrpn_valid |= 0x04;
                }
                
                
            } break;
                
            case 0x04: { // Address MSB FADER 5
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
                nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 4;
                nrpn_msb_only = 1; // for the MsbOnly format
#if 0
                // MEMO: it's better to update only when LSB has been received
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    midi_learn_nrpn_valid |= 0x04;
                }
#endif
            } break;
                
            case 0x24: { // Address LSB
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
                nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 4;
                
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                    midi_learn_nrpn_valid |= 0x04;
                }
                
                
            } break;
                
            case 0x05: { // Address MSB FADER 6
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
                nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 5;
                nrpn_msb_only = 1; // for the MsbOnly format
#if 0
                // MEMO: it's better to update only when LSB has been received
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    midi_learn_nrpn_valid |= 0x04;
                }
#endif
            } break;
                
            case 0x25: { // Address LSB
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
                nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 5;
                
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                    midi_learn_nrpn_valid |= 0x04;
                }
                
                
            } break;
                
            case 0x06: { // Address MSB FADER 7
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
                nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 6;
                nrpn_msb_only = 1; // for the MsbOnly format
#if 0
                // MEMO: it's better to update only when LSB has been received
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    midi_learn_nrpn_valid |= 0x04;
                }
#endif
            } break;
                
            case 0x26: { // Address LSB
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
                nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 6;
                
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                    midi_learn_nrpn_valid |= 0x04;
                }
                
                
            } break;
                
            case 0x07: { // Address MSB FADER 8
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x3f80;
                nrpn_received_value[port_ix][midi_package.chn] |= ((midi_package.value << 7) & 0x3f80);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 7;
                nrpn_msb_only = 1; // for the MsbOnly format
#if 0
                // MEMO: it's better to update only when LSB has been received
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    midi_learn_nrpn_valid |= 0x04;
                }
#endif
            } break;
                
            case 0x27: { // Address LSB
                nrpn_received_value[port_ix][midi_package.chn] &= ~0x007f;
                nrpn_received_value[port_ix][midi_package.chn] |= (midi_package.value & 0x007f);
                nrpn_value = nrpn_received_value[port_ix][midi_package.chn]; // pass to parser
                nrpn_address = 7;
                
                if( port != midi_learn_nrpn_port || midi_package.chn != (midi_learn_nrpn_chn-1) ) {
                    midi_learn_nrpn_port = port;
                    midi_learn_nrpn_chn = midi_package.chn + 1;
                    midi_learn_nrpn_valid = 0;
                } else {
                    // only if valid address has been parsed
                    // use same valid flag like Data MSB (complete NRPN is valid with 0x07)
                    midi_learn_nrpn_valid |= 0x04;
                }
                
                
            } break;

      
                

        }
      }
    }

Best

Zam

Edited by Zam
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...