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

Status
Not open for further replies.

joshnishikawa

Active member
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.
 
*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.
 
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.
 
Status
Not open for further replies.
Back
Top