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

Thread: Call MIDI.sendNoteOn() etc. from OUTSIDE main sketch?

  1. #1

    Call MIDI.sendNoteOn() etc. from OUTSIDE main sketch?

    Specifically, I have a Teensy 3.6 setup as a USB host. I'm successfully sending the incoming MIDI through to a 5-pin MIDI connector on pin 1 via callbacks. The problem is that, when I move the callbacks out of the main sketch, I get the following error.

    Code:
    Arduino: 1.8.5 (Windows 10), TD: 1.42-beta3, Board: "Teensy 3.6, MIDIx4, 180 MHz, Faster, US English"
    
    MIDIinput.cpp: In function 'void onUSBNoteOn(byte, byte, byte)':
    MIDIinput.cpp:11: error: 'MIDI' was not declared in this scope
       MIDI.sendNoteOn(note, velocity, channel); // WHY DOESN'T THIS WORK HERE???
    
       ^
    
    'MIDI' was not declared in this scope
    Here's the main sketch...
    Code:
    #include "Arduino.h"
    #include <USBHost_t36.h>
    #include <MIDI.h>
    #include "MIDIinput.h"
    
    MIDI_CREATE_DEFAULT_INSTANCE();
    USBHost teensyUSBHost;
    USBHub hub1(teensyUSBHost);
    USBHub hub2(teensyUSBHost);
    MIDIDevice USBMIDI(teensyUSBHost);
    
    void setup(){  
      MIDI.setHandleNoteOn(onNoteOn);
      USBMIDI.setHandleNoteOn(onUSBNoteOn);
      MIDI.begin(MIDI_CHANNEL_OMNI);
      teensyUSBHost.begin();
    }
    
    void loop(){
          teensyUSBHost.Task();
          USBMIDI.read();
          MIDI.read();
    }
    
    // THIS CALLBACK WORKS FINE HERE BUT I WANT IT IN "MIDIinput.cpp"
    /*
    void onUSBNoteOn(byte channel, byte note, byte velocity){
      usbMIDI.sendNoteOn(note, velocity, channel);
      MIDI.sendNoteOn(note, velocity, channel);
    }
    */
    Here's where I'd like the callback functions to be (MIDIinput.cpp)...
    Code:
    #include "MIDIinput.h"
    #include <MIDI.h>
    
    void onNoteOn(byte channel, byte note, byte velocity){
      usbMIDI.sendNoteOn(note, velocity, channel);
      // no need for MIDI.sendNoteOn() here
    }
    
    void onUSBNoteOn(byte channel, byte note, byte velocity){
      usbMIDI.sendNoteOn(note, velocity, channel);
      MIDI.sendNoteOn(note, velocity, channel); // WHY DOESN'T THIS WORK HERE???
    }
    And here's the header...
    Code:
    #ifndef MIDIinput_h
    #define MIDIinput_h
    
    #include "Arduino.h"
    #include <MIDI.h>
    
    void onNoteOn(byte channel, byte note, byte velocity);
    void onUSBNoteOn(byte channel, byte note, byte velocity);
    
    #endif
    This seems like the kind of thing that has a real facepalm explanation. I did try searching but got lost in the woods. I mean who wants to convert USB MIDI to the old 5-pin? I don't know. Any enlightenment is appreciated.

  2. #2

    *any source files

    SOLVED!
    It turns out that, when you have multi-file sketches, you can use the .h extension for header files but you shouldn't use a .cpp extension on any source files. For some reason it doesn't get the linking right. So just omit the extension altogether.
    In my case, I changed the name of "MIDIinput.cpp" to plain old "MIDIinput", tested it and it works just fine. I hope someone stumbles upon this info faster than I did.

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,565
    The .cpp file gets treated as a unique compile unit. For the linker to find something defined in another compile unit it would need to have an appropriate 'extern'/prototype to define it during compile and then the linker could associate the object made in the sketch.

Posting Permissions

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