Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: usbMidi: How to get information from the DAW?

  1. #1
    Junior Member
    Join Date
    Dec 2017
    Posts
    6

    usbMidi: How to get information from the DAW?

    Hi,

    I am trying to create a midi controller for Logic or Mainstage. In order to start simple, I have created a project with one encoder that controls one parameter (for instance the volume). This is working fine.

    But now I want to receive the current setting from Logic or Mainstage. For instance, when the channel volume is changed by another way (for instance by using the mouse), I want to receive the new setting with teensy. This way I can update the setting for the encoder, and prevent any jumping.

    However, I seem not the receive any messages from Logic or Mainstage at all.

    Below the code that I am currently using to check if I am receiving any midi information at all. But none so far. Still, this should be possible. I saw examples of motorized faders responding to changes in the DAW.

    Any help is very much apreciated!

    Code:
    void MidiMessages(){
       if(usbMIDI.read()){ //true if new midi message
        Serial.println(usbMIDI.getType());
       }
       
    }
    It should print the message type if any message is received. But I am receiving none at all.
    To be complete, below the whole code:

    Code:
    #include <Encoder.h>
    
    void setMidiPos(int valChange,int scale);//calculate valid mide value for the encoder
    int setencSpeedFct(int interv);//calculate speed factor based on encoder rotation speed
    void myControlChange(byte channel, byte control, byte value);//event handler midi control change
    
    Encoder myEnc(6, 5);
    unsigned long previousMillis = 0;//needed to calculate speed of turning the encoder
    unsigned long currentMillis = 0;//needed to calculate speed of turning the encoder
    long oldPosition  = 0;//needed to calculate the position change of the encoder
    long newPosition = 0;//needed to calculate the position change of the encoder
    int encPosChange=0;//needed to keep track of the position change
    bool encMoving=false;//flag indicates that the encoder is still being turned
    int midiPos=0;//current midi value for the encoder
    int encSpeedFct=1;//speed factor for multiplying the value change
    const long interval = 200; // interval after which encodermovement is assumed to have stopped
    const int midiCC=7; //7 is common for volume
    
    void setup() {
      // put your setup code here, to run once:
      usbMIDI.setHandleControlChange(myControlChange);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      MidiMessages();//read any incoming midimessages
      EncoderMovement();//respond to encoder
    }
    
    //check for incoming midi messages
    void MidiMessages(){
       if(usbMIDI.read()){ //true if new midi message
        Serial.println(usbMIDI.getType());//check if anything is received
       }
    }
    
    void EncoderMovement(){
      currentMillis = millis();//keep track of time
      newPosition = myEnc.read();//check encoder movement
      if (newPosition != oldPosition) {//encoder moved
        encMoving=true;
        encPosChange=encPosChange+newPosition-oldPosition;//keep track of posisiton changes 
        //filter out multiple pos changes that happen with each click
        //otherwise you do not get a proper speed calculation   
        if(abs(encPosChange)>2) 
        {
          setencSpeedFct(currentMillis-previousMillis);//calculate speed of turning rotary
          setMidiPos(encSpeedFct*encPosChange/3,128);//calculate new midi value
          usbMIDI.sendControlChange(midiCC, midiPos, 1);//sent value
          previousMillis = currentMillis;//reset timer
          encPosChange=0;//reset position changes
        }
        oldPosition= newPosition;
      }
      else{
        if (currentMillis - previousMillis >= interval) {
           //to much time without movement: stopped moving
           if(encMoving) { //reset if it was moving
            encMoving=false;
            previousMillis = currentMillis;
            encPosChange=0;
            oldPosition= newPosition;
          }
        }
      }  
    }
    
    //calculate valid mide value
    void setMidiPos(int valChange,int scale){
      midiPos=midiPos+valChange;
      if(midiPos>scale)
        midiPos=scale-1;
      if(midiPos<0)
        midiPos=0;
    }
    
    //calculate multiply factor based on speed of encoder movement
    int setencSpeedFct(int interv)
    {
      if(interv<100)
        encSpeedFct=4;
      else if(interv<200)
        encSpeedFct=3;
      else if(interv<400)
        encSpeedFct=2;
      else   
        encSpeedFct=1;
    }
    
    //respond to incoming control changes
    void myControlChange(byte channel, byte control, byte value){
      switch(control){
        case midiCC:
          setMidiPos(value,128);
          return;
         default:
          Serial.println("Control:" + control);
          return;
      }
    }

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,306
    I ran your program here on a Teensy 3.2, with nothing connected on the pins. Then I typed a command to send a sysex message. It printed "240" in the serial monitor. Here's a screenshot.

    Click image for larger version. 

Name:	sc.png 
Views:	43 
Size:	257.0 KB 
ID:	12679

    I can't say why your PC isn't sending messages, but hopefully this can at least to confirm your code is correctly receiving messages. When you get software on your PC to actually transmit, I'm sure you'll see numbers in the serial monitor.

  3. #3
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    210
    This is a general synchronization problem often encountered with MIDI controllers. You have a parameter in your DAW you want to control with MIDI, so you map it to a particular CC. Then you setup your MIDI controller to control that parameter with one of it's knobs. When you move the knob on the hardware controller, the parameter changes in the DAW, and is reflected often by the GUI showing the parameter as a virtual knob or whatever.

    Now, if you move the virtual knob, you want the corresponding MIDI value to be sent to the controller so it's aware of the update.

    E.g.
    1) Param is as 64.
    2) Hardware knob turns one click to the right. It sends a MIDI CC to set the param to 65.
    3) DAW turns the virtual knob one position further. Param is not at 66.
    4) Hardware is unaware of the param value. Hardware knob turns one more click, it thinks it was at 65 still, param in the DAW is 66, so Hardware tells daw to set value to 66, instead of 67 as intended.

    Now I'll admit that I've used neither Logic or Mainstage. I've only used Cubase, Amplitube and Forte. And I never found a way to send MIDI CC message out when you change a virtual knob controlled by a MIDI IN in those three programs.

    Are you sure Logic/Mainstage supports that particular feature? I've always thought it was an obvious necessity but most DAWs don't seem to have it because 99% of midi controllers out there don't have MIDI inputs, output only.

  4. #4
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    168
    As far far as I know the only way to get information out of Logic is by emulating a Logic Control or other control surface. I'm working on a controller for Logic optimised for controlling plugins that emulates a Logic control and a Logic control XT so I can control 16 parameters at a time.
    What kind of controller do you have in mind? Rotary encoders? Motor faders? Display(s)? How many paramaters do you want to control simultaneously? Is it intended as a general controller or for specific functions, plugins or instruments?

    Kind regards,

    Gerrit

  5. #5
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    210
    Now that I think more about it, it's not really the DAW most of the time that's the issue, it's the VST plugins. If the VST plugin supports MIDI IN control of the parameter, it's up to the VST plugin itself to generate MIDI OUT messages when someone moves a virtual control inside the VST GUI. There's no way the VST host knows that inside the plugin a parameter changed.

  6. #6
    Junior Member
    Join Date
    Dec 2017
    Posts
    6

    usbMidi and Mackie Control

    Thanks to all for the quick and helpful responses, and special thanks to Paul for even testing my code.

    I assumed that somehow this information is sent back to the controller, for two reasons:
    1. Commercially available controllers like Nektar Panorama and Komplete Kontrol are able to show current settings. These are indeed Mackie (Logic) control devices, as Gerrit suggested.
    2. I see examples of motorised faders that apparently respond. I downloaded the code of one of these with Arduino (see https://blog.codyhazelwood.me/midi-c...torized-fader/). It seems to be based on Mackie as well, but I could not see anything in the code that is different from my code. So I do not understand how Mackie is playing a role here.

    So I suppose I need to implement Mackie Control. If anyone with experience with Mackie on Teensy could set me in the right direction, would be very welcome. For instance, is this possible via the usbMIDI, or not?

    What I am aiming to build (for who is interested like Gerrit)
    I am using plug-in synthesizers a lot. I want better hardware control than possible up to now. I have been using controllers like Kore, Komplete Kontrol, Nektar Panorama. I know exactly how I would improve all these controllers to make it really work to my likings. So time to built one my self.

    The first thing I want to build is what I would call a midi matrix. It will work much like the interface of a Microkorg or Blofeld, and also like the Panorama and the KK, but than better:
    1. Instead of having to scroll through an (sometimes unordered) list of pages/modes, I want dedicated push buttons for direct selecting the page/mode for Oscillator, Filter, Amp, Envelope, LFO, Mix, FX, Mod Matrix.
    2. The encoders and push buttons are always controlling the same parameter, whatever synth you ar controlling. For instance: in oscillator mode, encoder 1 is always controlling the waveform, encoder 2 the PW/shape, encoder 3 the coarse tuning, Encoder 4 the fine tuning, etc. If a certain parameter is not available for a certain synth, the encoder is dimmed and not used for another parameter. So, (after getting used to it) you do not have to search where a certain parameter is hidden.
    3. It is important that the current settings are shown on the midi controller (either by leds or a display), and there should be no jumping. You should be able to control the plugin without looking on your computer. That is why I need to receive the current settings.

    So I have started a simple project, just to learn Teensy and how this could be accomplished. I know, the final objective is far away, but you have to start somewhere, don't you?

  7. #7
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,107
    There does not seem to be an official specification for Mackie Control universal (MCU) but sereral companies implement apparently interoperable products using it.

    There is a PDF (available here https://web.archive.org/web/20130402...urfaceInfo.pdf) which describes the protocol (page 239 onward).

    For the related HUI protocol, look here
    https://forum.cockos.com/showthread.php?t=101328

    I know, these are not great sources. If someone has better ones I would like to see them.

    You can use Teensy USB Host to intercept the MIDI messages sent by your controllers, log them to the Arduino console, and forward them on via the USB device port. Basically a SysEX sniffer.

  8. #8
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    168
    Quote Originally Posted by postman View Post
    .... It seems to be based on Mackie as well, but I could not see anything in the code that is different from my code. So I do not understand how Mackie is playing a role here.

    So I suppose I need to implement Mackie Control. If anyone with experience with Mackie on Teensy could set me in the right direction, would be very welcome. For instance, is this possible via the usbMIDI, or not?

    ...
    Only if Logic detects a Mackie control unit on one of the midi ports will it send data to that port. I don't know if you can just tell logic that there's a controller connected as I implemented the sysex handshake for automatic detection and installation.
    Yes, this possible over USB.

    Here's the sketch I'm working on:Zeus-DPC.ino

    And here's a picture of it in operation:
    Click image for larger version. 

Name:	Zeus-DPC-Lexicon-front.jpg 
Views:	86 
Size:	90.3 KB 
ID:	12692

    It's not finished yet but the basics are working.

    Kind regards,

    Gerrit

  9. #9
    Junior Member
    Join Date
    Dec 2017
    Posts
    6
    Hi Gerrit,
    A bit late, but thanks a lot. Your Zeus code helped me a lot to get going! I do not understand it completely yet, but it definitely works. Your project is interesting as well, and probably quite similar to what I am going to try to do.
    Kind regards,
    Peter

  10. #10
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    168
    Zeus-DPC.ino
    Quote Originally Posted by postman View Post
    Hi Gerrit,
    A bit late, but thanks a lot. Your Zeus code helped me a lot to get going! I do not understand it completely yet, but it definitely works. Your project is interesting as well, and probably quite similar to what I am going to try to do.
    Kind regards,
    Peter
    Glad I could help
    Here's an updatet version of the sketch:Zeus-DPC.ino The 4D System library is not used anymore so it should work as is. There's more code as the displays are controlled directly from the sketch and some 'translations' and plugin ids are added.
    The unit now identifies itself as a standard Mackie control and extension unit and the jog shuttle is also working.

    Kind regards,

    Gerrit

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •