We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSound,  Music Libraries › proMIDI, MidiBus, and Accurate Input Detection
Page Index Toggle Pages: 1
proMIDI, MidiBus, and Accurate Input Detection (Read 1464 times)
proMIDI, MidiBus, and Accurate Input Detection
Jan 21st, 2009, 8:00am
 
Hello All,

I'm just getting started learning Processing for an upcoming performance. I've been trying to get input from my MIDI hardware to be detected in a Processing sketch. The ultimate goal is to be able to set and adjust the frame rate in time to a click. So, for example, noteOns of a specific pitch and above a specific velocity should be used to deduce the beats per minute, and from there the frame rate. This way projected video or imagery will speed up and slow down in time to the musicians without the musicians doing anything more than just playing as usual.  (Actually, for this piece it is the drummer I'm focusing on.)

The problem I'm seeing is that I'm getting input data that does not seem clean enough for this task.  I made a quick demo using proMIDI, and (what I think is) an identical one using MidiBus.  The demos simply output (via a println()) a timestamp, the function that is being called (noteOn, noteOff, etc,) and the parameters of the MIDI event.  I execute the sketches and I simply press one key on my M-Audio Oxygen8, hold it for a count of three (just to let some time advance), and release it.

The first issue I notice is with proMIDI: For the keypress there is a noteOn and a noteOff with the same timestamp. The key release at outputs another noteOn/noteOff pair, as well as a second pair 2ms later.  Note that MidiBus does not exhibit this behavior.  Why is this happening?  Is it a MIDI cross-talk thing?  A peculiarity in proMIDI's plug() method?

The second issue I notice is with MidiBus: Although it does not have the duplicate outputs, it also does not seem to react to noteOffs.  Instead of a noteOff I get a noteOn with the same pitch and velocity=0.  Is this a normal MIDI thing?

Has anyone else seen such behavior?  Any clues would be much appreciated.  I'll happily share the code and output listings if that helps me get to the bottom of things (or helps anyone else get a leg up with Processing and MIDI.)

beatkeeper
Re: proMIDI, MidiBus, and Accurate Input Detection
Reply #1 - Jan 21st, 2009, 8:21am
 
check out http://smallbutdigital.com/themidibus.php

brand new contribution to processing.  i am a super newb, but this def looks like something that could possibly lead you in the right direction.
Re: proMIDI, MidiBus, and Accurate Input Detection
Reply #2 - Jan 21st, 2009, 4:54pm
 
Thanks for the hint, blad. As I mentioned, I tried it with the MidiBus, and the issue I faced was that I was not getting any noteOff messages, only noteOn messages with velocity=0. This might suffice for my purposes, but I'm not yet certain.

If anyone with more experience with MIDI can comment I'd be very thankful.  I'll try to post the code tonight.
Re: proMIDI, MidiBus, and Accurate Input Detection
Reply #3 - Jan 21st, 2009, 5:32pm
 
Hey beatkeepr,

I've looked into your question.

With relation to my library (themidibus), this is not really bug. It's quite common for MIDI hardware/software to use a noteOn with a velocity of 0 instead of a noteOff. In fact, the MIDI specification allows you to use them interchangeably (aka noteOn with vel 0 = noteOff). And currently themidibus gives you unaltered MIDI (so it doesn't do the NoteOn to NoteOff conversion for you).

It's fairly likely that your controller or some other part of your setup is sending noteOn with vel 0 instead of noteOff hence you get two noteOn messages instead of a noteOn and a noteOff message.

On the other hand, it would probably make sense for my library to do this conversion automatically because it's really common, especially in older MIDI hardware. I will try and fix this sometime later this afternoon when I have a bit of free time. I will update this thread and my main themidibus thread when I do so.

Also, I can confirm that when I use promidi I also get and extra noteOn after a slight delay. I poked around a bit, but I was in a hurry and couldn't figure out why at the moment. You should probably ask tex about that.

Hopefully this was helpful, I'll subscribe to this thread in case you have further problems/questions.

Here are some eclectic links that are useful/mention the noteOn vel 0 = noteOff behavior

http://www.srm.com/qtma/davidsmidispec.html (read the paragraph Note On, Note Off)

http://www.cycling74.com/forums/index.php?t=msg&th=36583&rid=0&S=901a1e8efaffef96e67f6f650d1bf083 (a flame war about it)

Sparky
Re: proMIDI, MidiBus, and Accurate Input Detection
Reply #4 - Jan 21st, 2009, 8:14pm
 
Hey Sparky,

Thanks for the reply. I figured the noteOn with velocity=0 was probably equivalent to noteOff, but the confirmation is much appreciated. If I remember correctly, using MIDI Monitor on my PowerBook quoted noteOffs for the same MIDI controller. Perhaps that software is making the conversion internally.

For my purposes I think it doesn't really matter whether I receive a noteOn or noteOff. That's something I can probably architect my code around. However, I suspect getting the noteOff would make my code easier to read.  That is, I would not have to check each noteOn message to filter out the noteOffs before I continue with my own tempo-detection filtering.

Thanks again for the confirmation and for MidiBus!

beatkeeper
Re: proMIDI, MidiBus, and Accurate Input Detection
Reply #5 - Jan 22nd, 2009, 6:44am
 
Hello All,

As promised, this is the sketch I use to figure out what I'm receiving via the MidiBus library.  Any improvements are certainly welcome.

----Start of code----
/*
* This sketch is a simple diagnostic tool for monitoring MIDI
* input data. It uses the MidiBus library.
*
* Issues:
*/
import themidibus.*;

MidiBus myBus;

void setup(){

 // List all available Midi devices on STDOUT. This will show each device's index and name.
 MidiBus.list();
 myBus = new MidiBus(this, 0,1);
}

void draw(){
}

void noteOn(int channel, int pit, int vel){
 println(millis() + "\tNoteOn : Pitch=" + pit + "\tVelocity=" + vel + "\tChannel=" + channel);
}

void noteOff(int channel, int pit, int vel){
 println(millis() + "\tNoteOff: Pitch=" + pit + "\tVelocity=" + vel + "\tChannel=" + channel);
}

void controllerChange(int channel, int num, int val){
 println(millis() + "\tController Change: Number=" + num + "\tvalue=" + val + "\tChannel=" + channel);
}
----End of code----

Below is the equivalent using the proMIDI library. Note that it exhibits the behavior that I mentioned earlier in the thread. If anyone sees anything obvious that might be the cause, please let me know.

----Start of code----
/*
* This sketch is a simple diagnostic tool for monitoring MIDI
* input data. It uses the proMIDI library.
*/
import promidi.*;

MidiIO midiIO;

int device = 0;
// Roland TDW-1
// int channel = 8;
// Oxygen 8
int channel = 7;


void setup(){

 midiIO = MidiIO.getInstance(this);
 // print a list of all devices
 midiIO.printDevices();

 Receiver recvr = new Receiver();

 midiIO.plug(recvr,"noteOn", device, channel);
 midiIO.plug(recvr,"noteOff", device, channel);
 midiIO.plug(recvr,"controllerIn", device, channel);
 midiIO.plug(recvr,"programChange", device, channel);

}

// Note that without this draw function, nothing seems to happen!
void draw(){
}

// If this class is not declared public then it will cause the MidiIO.plug()
// method to fail with an IllegalAccessException.
public class Receiver {

 Receiver(){
   println("Created Receiver object recvr");
 }

 void noteOn(Note note){
   int vel = note.getVelocity();
   int pit = note.getPitch();
   println(millis() + "\tNoteOn : Pitch=" + pit + "\tVelocity=" + vel);
 }

 void noteOff(Note note){
   int pit = note.getPitch();
   int vel = note.getVelocity();

   println(millis() + "\tNoteOff: Pitch=" + pit + "\tVelocity=" + vel);
 }

 void controllerIn(Controller controller){
   int num = controller.getNumber();
   int val = controller.getValue();

   println(millis() + "\tController In: Number=" + num + "\tvalue=" + val);
 }

 void programChange(ProgramChange programChange){
   int num = programChange.getNumber();

   println(millis() + "\tProg Change: Number=" + num);
 }  
}// class Receiver
----End of code----
Re: proMIDI, MidiBus, and Accurate Input Detection
Reply #6 - Jan 25th, 2009, 5:05am
 
hey beatkeeper,

This is just a quick post to say that I just updated my library, so it should now convert NoteOn with velocity 0 to noteOff. Just redownload and you're ready to go. Sorry it was kinda slow, but I was busy with school.

Also, I was thinking in a general way about what you're trying to do (as in using the timing of midi notes). The only information I can think to add is that every time themidibus receives a MIDI note (via the receiver interface) it get's passed a timestamp. Now it would be possible for me to pass on that timestamp to you the user, but I've done some testing and as far as I can tell you get the same accuracy using the millis() function as you do with the timestamps that themidibus receives.

In support of my point, here's the output of a little test I threw together. It send out MIDI notes at random intervals (using a random delay) and then I prints both the timestamp received by themidibus and the timestamp according to millis():

Code:

themidibus TimeStamp: 1065000
Processing TimeStamp with millis(): 1996
Delay for: 2377

themidibus TimeStamp: 3443000
Processing TimeStamp with millis(): 4373
Delay for: 1683

themidibus TimeStamp: 5127000
Processing TimeStamp with millis(): 6057
Delay for: 1524

themidibus TimeStamp: 6652000
Processing TimeStamp with millis(): 7582
Delay for: 2172

themidibus TimeStamp: 8825000
Processing TimeStamp with millis(): 9756
Delay for: 2337

themidibus TimeStamp: 11163000
Processing TimeStamp with millis(): 12093


As you can see there is never more than 1 millisecond error.
Re: proMIDI, MidiBus, and Accurate Input Detection
Reply #7 - Jan 28th, 2009, 7:54pm
 
Hey Sparky,

Thanks for the mods, I'll fetch that when I can.  So far your library has been working very well for me.

As for the time stamp thing, thanks also for looking into it. I'm perfectly happy using millis() wherever I need to.  Yes, I suppose the object model could be richer and that might lead to better code, but it is not as if I couldn't fashion such an object model myself outside of the MidiBus. It's better to keep the common libs simple, no?

So far I've managed to determine the tempo based on noteOn events, but I haven't quite managed to make that influence frameRate() and/or other values or calculations.  (That's more about having time to complete it.  It's all about timing, isn't it?)

beatkeeper
Page Index Toggle Pages: 1