MIDI Filter/Processor feasibility

Status
Not open for further replies.

ForestCat

Member
Hi,
I've been using Teensy's with great success to implement various controller schemes. However, I've not yet tried to use it to filter/process a realtime MIDI data stream. I play MIDI guitar, and would be working with a channel per string consisting of NoteOn-Off and pitchbend data, as well as various cc and occasionally sysex data. The most basic need would be to intercept and modify specific data on specific channels, while passing the rest unmodified with absolute minimum added latency and no lost data.

I currently do this via Max/Bidule, etc., but I want a solution that does not rely on a computer, because it adds perceptible latency to an already bad situation (guitar to MIDI). So a couple of questions:

1. Is this just simply too ambitious for a Teensy?
2. If not, is there good reason to hope to achieve lower added latency than a pc/mac/ipad with their additional os/interface overhead?
3. I'm not an expert programmer. Would the buffer management be insanely tricky to code?

BTW, I'd be doing this via DIN MIDI, with hardware synthesizers.

Thank you very much for any thoughts/experience/advice. I searched the forum/website, but couldn't find any similar application, although I certainly could have missed it.
 
Yes, this is doable. See DIN MIDI on Teensy (and for comparison, USB MIDI on Teensy (yes, the latter is built in).

If you want low latency then you don't want to be buffering. Instead, assign event handlers to the messages and deal with them as they arrive. The MIDI examples will give you a good start.
 
I'm sure I'm gonna sound ignorant, but prior to posting here, I looked though all the included Arduino/Teensyduino examples that had anything related to "MIDI" in the name, and I could find no example of code in which incoming DIN MIDI data is echoed directly to a DIN MIDI output, with perhaps some modification to a subset of that data. This is basically a "MIDI Merge" of incoming data w/ Teensy-generated data. If you know of such an example, would you be kind enough to point me directly to that specific example, or alternatively, copy & paste it here. I'd be very grateful, that would get me started, or at least give me an idea of whether the code was too far over my head. Thanks.
 
That was actually why I pointed to the USB MIDI page above, since it has examples of using callback functions (look for the section "Receiving Messages with Read & Callback Functions") in more detail than the DIN MIDI page or included examples.
However, if you look in the Arduino gui under Examples > MIDI > MIDI_callback there is an (extremely brief) example there. The documentation for the DIN MIDI library has more info.

Further advice would be easier with more details of what you want to do. But as examples, you could set handlers for NoteOn to merge all data from channels 1 to 6 into a new stream on channel 8. Or, all data within a certain note range for each channel. Or, handle a particular CC by outputting pitchbend messages. Or respond to a MIDI tuning request. Or add in a MIDI clock for your DAW. It all depends what sort of filtering and generation you want.
 
Last edited:
As another example, given a list of notes produced at each fret by each string, you could filter out mis-notes or output the closest note that should have been produced.
 
Here is a quick example to merge six incoming channels to one outgoing one.
Code:
#include <[color=#CC6600]MIDI[/color].h>

[color=#7E7E7E]// This function will be automatically called when a NoteOn is received.[/color]
[color=#7E7E7E]// It must be a void-returning function with the correct parameters,[/color]
[color=#7E7E7E]// see documentation here: [/color]
[color=#7E7E7E]// http://arduinomidilib.sourceforge.net/a00001.html[/color]

[color=#CC6600]void[/color] HandleNoteOn([color=#CC6600]byte[/color] channel, [color=#CC6600]byte[/color] pitch, [color=#CC6600]byte[/color] velocity) { 
  [color=#7E7E7E]// Merge data on channels 1 to 6 (e.g a MIDI guitar) to channel 8[/color]
  
  [color=#CC6600]if[/color] (channel < 7) {
    [color=#CC6600]MIDI[/color].[color=#CC6600]sendNoteOn[/color](pitch, velocity, 8);
  }

}

[color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]() {
  [color=#7E7E7E]// Initiate MIDI communications, listen to all channels[/color]
  [color=#CC6600]MIDI[/color].[color=#CC6600]begin[/color]([color=#006699]MIDI_CHANNEL_OMNI[/color]);    
  
  [color=#7E7E7E]// Connect the HandleNoteOn function to the library, so it is called upon reception of a NoteOn.[/color]
  [color=#CC6600]MIDI[/color].[color=#CC6600]setHandleNoteOn[/color](HandleNoteOn);  [color=#7E7E7E]// Put only the name of the function[/color]
  [color=#7E7E7E]// In this example, everything except NoteOn is thrown away (filtered)[/color]
}


[color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]() {
  [color=#7E7E7E]// Call MIDI.read the fastest you can for real-time performance.[/color]
  [color=#CC6600]MIDI[/color].[color=#CC6600]read[/color](); 
  [color=#7E7E7E]// There is no need to check if there are messages incoming if they are bound to a Callback function.[/color]
}
 
As another example, given a list of notes produced at each fret by each string, you could filter out mis-notes or output the closest note that should have been produced.

How does one identify a "mis-note" in real time? Perhaps somehow you could inform the Teensy of the song key, and then have it ignore off key notes, but other than that, there isn't much you can do.
 
How does one identify a "mis-note" in real time? Perhaps somehow you could inform the Teensy of the song key, and then have it ignore off key notes, but other than that, there isn't much you can do.
My bad. I was thinking that a given string could not produce all the notes in a scale (but it can). Apparently (some) MIDI guitars have a problem where, if the string is not precisely stopped on a fret, the MIDI issues the next note up in the scale even though the frequency produced is much closer to the note on the fret that was intended.
 
Guys, I'm really sorry, there seems to be nothing I can do to get this forum s/w to notify me via email of new posts. I didn't know you replied.

Nantonos, thank you kindly for the links & the example code. That's what I needed. I was also evnetually able to find some similar example on another forum which I've adapted & begun testing.

Paul, I did eventually find some info re: merging/ MIDI thru, etc. The initial testing indicates it only adds a millisecond or two of latency in the most "plain vanilla" config. I'll see what happens when I start adding some conditional statements.

Thank you guys for your help. I appreciate it. Sorry again for the delayed acknowledgment. I don't know why the thread subscription notification isn't working for me.
 
Status
Not open for further replies.
Back
Top