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

Thread: teensy midi

  1. #1
    Junior Member
    Join Date
    Dec 2020
    Posts
    10

    teensy midi

    when you first set up a new Teensy 4 and select MIDI...is it ready to do the basic midi talk to a DAW or do you have to in addition add some code...? If you have to add code what is a good basic script for controlling transport functions in any major DAW
    like play/stop/record/cycle/ etc...
    thanks

  2. #2
    yes you need to write your own code to tell the Teensy what to do. This page covers it: https://www.pjrc.com/teensy/td_midi.html

  3. #3
    Junior Member
    Join Date
    Dec 2020
    Posts
    10
    I got the impression that the current Teensyduino app has everything you need if you just select Midi....
    And I have watched several videos that don't show adding code to the gui to get it going....????It might been in the past you have to write code but maybe not now....
    Can someone who has done a midi controller comment on this...I only have 6 buttons and 1 encoder and its for Cubase. Cubase has a generic remote app that lets you connect any controller .....
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	Screen Shot 2020-12-31 at 8.28.42 AM.png 
Views:	15 
Size:	65.6 KB 
ID:	23043  
    Last edited by gus29; 12-31-2020 at 03:50 PM.

  4. #4
    You have to write code, there's no way around that. You have to tell the Teensy what MIDI messages to send and when, and how it should react to the incoming MIDI messages it receives.

    I'm the maintainer of the Control Surface library, which allows you to design a MIDI controller in a declarative style with a minimum amount of programming, but you still have to write some code.

    For example:
    Code:
    #include <Encoder.h> // Include the Encoder library.
    // This must be done before the Control Surface library if you want to use encoders
    #include <Control_Surface.h> // Include the Control Surface library
    
    // Instantiate a MIDI over USB interface.
    USBMIDI_Interface midi;
    
    // Instantiate an array of NoteButton objects that send
    // MIDI note events when a push button is pressed/released
    NoteButton buttons[] {
      { 4, MCU::PLAY },  // Push button on pin 4, “play” control
      { 5, MCU::STOP },
      { 6, MCU::RECORD },
      { 7, MCU::REWIND },
      { 8, MCU::FAST_FWD },
    };
    
    // Instantiate a CCRotaryEncoder object
    CCRotaryEncoder enc {
      {2, 3},       // pins
      MCU::V_POT_1, // MIDI address (CC number + optional channel)
      1,            // optional multiplier if the control isn't fast enough
    };
    
    void setup() {
      // Select the correct relative MIDI CC mode:
      RelativeCCSender::setMode(relativeCCmode::MACKIE_CONTROL_RELATIVE);
      Control_Surface.begin(); // Initialize Control Surface
    }
    
    void loop() {
      Control_Surface.loop(); // Update the Control Surface
    }
    This code uses the Mackie Control Universal protocol, so it's best to map it as a Mackie control surface in your DAW, but you could use any MIDI note number or controller numbers instead of “MCU::PLAY” etc., and then map them manually using the MIDI learn mode of your DAW, for example. You might have to change the relative CC mode if the encoder behaves strangely.

    You can find more information in the NoteButton.ino and RotaryEncoder.ino examples.

    Pieter

  5. #5
    Junior Member
    Join Date
    Dec 2020
    Posts
    10
    thanks for details...I had trouble with Mackie when I used a Faderport although it did work..I think I would rather use the generic remote feature since its in Cube.I know how to use the learn fnc and select all the stuff for that.. so let me get his right.. I can use the above code but I could replace the line...{ 4, MCU::PLAY }, // Push button on pin 4, “play” control with a line{ 4, 28::PLAY }, whatever number shows in learn....
    this is using only the digital pins on the Teensy4....no analogue.. would that work.....I don't have to have a volume control so I could skip that until later..

  6. #6
    The MCU::PLAY constant is for the Mackie Control Universal protocol specifically. If you don't use that protocol, the controller numbers don't really have any meaning apart for the MIDI mapping you create in your DAW.
    28::PLAY is not valid C++ syntax, if you want to specify the controller number, use {4, 28}.

    You can find some more information in the documentation. It might be a good idea to go through the Getting Started guide as well.

  7. #7
    Junior Member
    Join Date
    Dec 2020
    Posts
    10
    look at this partial script for midi... does this contain enough for simple midi control mapping 6 buttons only...?
    // Send a MIDI note on message
    void noteOn(byte channel, byte pitch, byte velocity)
    {
    // 0x90 is the first of 16 note on channels. Subtract one to go from MIDI's 1-16 channels to 0-15
    channel += 0x90 - 1;

    // Ensure we're between channels 1 and 16 for a note on message
    if (channel >= 0x90 && channel <= 0x9F)
    {
    #ifdef DEBUG
    Serial.print("Button pressed: ");
    Serial.println(pitch);
    #elif defined(TEENSY_PLUS_PLUS) || defined(TEENSY_2) || defined(TEENSY_PLUS_PLUS_2)
    usbMIDI.sendNoteOn(pitch, velocity, channel);
    #else
    Serial.write(channel);
    Serial.write(pitch);
    Serial.write(velocity);
    #endif
    }
    }

    // Send a MIDI note off message
    void noteOff(byte channel, byte pitch)
    {
    // 0x80 is the first of 16 note off channels. Subtract one to go from MIDI's 1-16 channels to 0-15
    channel += 0x80 - 1;

    // Ensure we're between channels 1 and 16 for a note off message
    if (channel >= 0x80 && channel <= 0x8F)
    {
    #ifdef DEBUG
    Serial.print("Button released: ");
    Serial.println(pitch);
    #elif defined(TEENSY_PLUS_PLUS) || defined(TEENSY_2) || defined(TEENSY_PLUS_PLUS_2)
    usbMIDI.sendNoteOff(pitch, 0x00, channel);
    #else
    Serial.write(channel);
    Serial.write(pitch);
    Serial.write((byte)0x00);
    #endif
    }
    }

    // Send a MIDI control change message
    void controlChange(byte channel, byte control, byte value)
    {
    // 0xB0 is the first of 16 control change channels. Subtract one to go from MIDI's 1-16 channels to 0-15
    channel += 0xB0 - 1;

    // Ensure we're between channels 1 and 16 for a CC message
    if (channel >= 0xB0 && channel <= 0xBF)
    {
    #ifdef DEBUG
    Serial.print(control - MIDI_CC);
    Serial.print(": ");
    Serial.println(value);
    #elif defined(TEENSY_PLUS_PLUS) || defined(TEENSY_2) || defined(TEENSY_PLUS_PLUS_2)
    usbMIDI.sendControlChange(control, value, channel);
    #else
    Serial.write(channel);
    Serial.write(control);
    Serial.write(value);
    #endif
    }
    }

  8. #8
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,543
    If you compile that code for Teensy4, and assuming that you add some appropriate code to call these functions, it will not generate any MIDI messages - it will only output debugging messages to the Serial Monitor.
    The three statements which could generate a MIDI message are conditionally included but ONLY if the code is compiled for one of a Teensy++, Teensy2 or Teensy++2.

    Pete

  9. #9
    Junior Member
    Join Date
    Dec 2020
    Posts
    10
    what about this code...do you think it will compile and execute a rotary encoder??? if so should I paste it before the rest of my button code or after?
    Can I paste it just as it is? Do I need to skip a line before I paste it?? teensy 4.0

    <html><head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#include &lt;Encoder.h&gt;

    Encoder enc_one(2, 3);
    int value;

    long enc_one_previous = -999;
    byte button_previous;

    void setup() {
    pinMode(23, INPUT_PULLUP);
    }



    void loop() {
    value = enc_one.read();
    if(value &gt; 127) { enc_one.write(127); }
    else if(value &lt; 0) { enc_one.write(0); }

    value = constrain(value, 0, 127);
    if (value != enc_one_previous) { enc_one_previous = value; usbMIDI.sendControlChange(1, value, 1); }

    value = digitalRead(23);
    if(value != button_previous) { button_previous = value; usbMIDI.sendControlChange(2, (1 - value) * 127, 1); delay(3); }
    }

    </pre></body></html>

  10. #10
    I posted a working example for a MIDI controller with buttons and an encoder. Did it not work for you?

    If you want to write your own code from scratch, you'll have to learn some basics about the Arduino/Teensyduino environment and the C++ programming language. Just copy-and-pasting code that you don't understand won't get you anywhere. Did you try the examples in the Teensy MIDI documentation at the link in the first reply?

Posting Permissions

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