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.
IndexProcessing DevelopmentLibraries,  Tool Development › The MidiBus MIDI library
Pages: 1 2 3 4
The MidiBus MIDI library (Read 35057 times)
The MidiBus MIDI library
Nov 28th, 2008, 4:00am
 
...

Important, you must uninstall mmj if you're on Mac OS 10.5 or later after the new apple Java update (update 6 on 10.5 and update 1 on 10.6) and then install the latest version of the MidiBus

The last update was Sun 12 December 2009 15:00:00 EST
I regularly make updates to the library (improvements, bug fixes). The latest version can always be found here. This post will always reflect the date of the latest update.

I recently wrote a Midi library for processing called the MidiBus. I must say I do feel a little silly because I've been taking my time getting it online and in the mean time someone has gone and written another (I assume awesome) Midi library called RWMidi.

So just to recap real quick there is already two other good libraries:
-promidi 2.0
and
-RWMidi

Anyways, I originally wrote this library because in my opinion promidi really isn't very well geared towards flexible realtime Midi and it's also a little too complicated for my tastes. Although there are sendNoteOn() sendNoteOff() methods, they are not listed in the documentation. Also, having to constantly instantiate Note and Controller objects to be able to send Midi messages sometimes feels very superfluous and irritating. This, isn't to say that I dislike promidi, it's sequencer/song/track functionality is great, but not useful to me. Furthermore, the (perhaps fixed now) bug with sendController() which made it impossible to set the controller value also gave me a push in right direction.

Now although RWMidi is much closer to my library than promidi, there are still some differences. In particular, I haven't included any wrapper objects such as Note, Controller, etc instead you simply sendNoteOn(channel, pitch, velocity) or sendControllerChange(channel, number, value). Obviously you could write your own such wrappers as it would be very easy to do or you could also use the MidiMessage object from javax.sound.midi which is supported by my library. I may add more such wrappers in the future. Also, I've rethought and tried to simplify setting up your inputs and outputs as much as possible. Inputs and outputs can be selected by name or by index and can be grouped together in simple and useful ways.

I've tried to write complete hopefully slightly comprehensible documentation. Please give me your feedback about the library or the documentation.

I recommend reading the examples and then referring to the javadocs if you want a quickstart. Otherwise don't hesitate to ask me questions either by post/e-mail/AIM.

Links

-The main page about the MidiBus
-Download the MidiBus library (with examples and javadocs
-Read the the MidiBus javadocs online

-It is heavily based on javax.sound.midi so check that out too

Finally if you're on a mac with 10.4 or earlier don't forget to install mmj, because there's no midi support built in
Re: TheMidiBus MIDI library
Reply #1 - Nov 28th, 2008, 9:42am
 
hi severin,
thank you for posting your library contribution. looks good. i took a quick look at the src code inside the library folder. you did include processing.core classes there, which you could leave out if you add core.jar to your classpath. keeps the download smaller in file size and wont conflict with processing's own core classes.
best,
andreas
Re: TheMidiBus MIDI library
Reply #2 - Nov 28th, 2008, 3:31pm
 
Edit:

Sorry misread what you said, you're completely right, I was just being lazy and not adding core.jar to my classpath. I've done that and I've fixed my release so it doesn't contain a copy of the processing core.

Although I'd like to mention that there is no risk of conflicting with processing's own core classes because I made a point of excluding the processing core folder from my .jar file

Here's the inside of my themidibus.jar file:

Code:

0x0A:library Admin$ jar -tf themidibus.jar
META-INF/
META-INF/MANIFEST.MF
themidibus/
themidibus/MidiBus$MReceiver.class
themidibus/MidiBus.class
themidibus/MidiListener.class
themidibus/RawMidiListener.class
themidibus/SimpleMidiListener.class
themidibus/StandardMidiListener.class
0x0A:library Admin$


Thanks for the feedback
Re: TheMidiBus MIDI library
Reply #3 - Dec 16th, 2008, 1:37am
 
Hey Sparky, first of all, thanks for posting this great library, it does just what i need.

I was wondering if it's possible to get each MIDIdevice name and if it's an input or output, like the list() method does.
I'm trying to do a little app with a graphic interface, using sojamo's controlP5 great library... so i can put some scroll lists from where you can select the controller device (e.g. a gamepad), and midi IN/OUT devices, etc.

i've tried with an array and returnList(); for example:
Code:

listmd = MidiBus.returnList();
println(listmd[4]);


this prints the name of the 4th device available (in this case: "Midi Yoke NT: 1") but i need to display if it's an input or output (as Midi Yoke has both Midi Yoke 1 IN and Midi Yoke 1 OUT) so you can recognize it.

maybe it's a silly question, but i got stucked...
Thanks in advance, and once again, thanks for posting TheMidiBus.

Cheers,

Jon
Re: TheMidiBus MIDI library
Reply #4 - Dec 16th, 2008, 11:51pm
 
Hey bjlotus,

I'm really happy you like my library.

I had actually though about the problem you mention when I was writing the library but hadn't found a suitable solution at the time. The difficulty is thinking of a nice clean way to return all the device indexes, names and types together.

But I think I figured out something ok last night, and whipped it up. I've updated the library (and the javadocs) so that returnList() now returns a 2D array containing with the index, name and type of each device. So go check out the updated javadocs and re-download the library

Here's a little example of how it works now:

Code:

MidiBus.list(); //For comparison

String[][] list_of_devices = MidiBus.returnList(); //The new returnList() is now a 2D array

println();
println("Available Midi Devices (from returnList()):");
println("-----------------------");

for(int i = 0;i < list_of_devices.length;i++) {
println("[" + i + "] \"" + list_of_devices[i][0] + "\" [" + list_of_devices[i][1] + "]");
}


Which outputs:

Code:

Available Midi Devices:
-----------------------
[0] "IAC Driver - Bus 1" [Input]
[1] "IAC Driver - Bus 1" [Output]
[2] "Real Time Sequencer" [Input/Output]
[3] "Java Sound Synthesizer" [Output]

Available Midi Devices (from returnList()):
-----------------------
[0] "IAC Driver - Bus 1" [Input]
[1] "IAC Driver - Bus 1" [Output]
[2] "Real Time Sequencer" [Input/Output]
[3] "Java Sound Synthesizer" [Output]
Re: TheMidiBus MIDI library
Reply #5 - Dec 17th, 2008, 8:38pm
 
Hi Sparky, thanks for replying, this seems to work perfectly!
I've already tested it using a couple scroll lists (one for inputs and other for outputs)

Code:

for(int i = 0;i < lista.length;i++) {
  if(lista[i][1]=="Input"){
  controlP5.Button c = l2.addItem(lista[i][0] + " - " +  lista[i][1], i);
  c.setId(200+i);}
  if(lista[i][1]=="Output"){
  controlP5.Button d = l3.addItem(lista[i][0] + " - " +  lista[i][1], i);
  d.setId(300+i);}
}


... and works great so far, so THANKS A LOT Cheesy

Jon
Re: TheMidiBus MIDI library
Reply #6 - Dec 17th, 2008, 8:45pm
 
You're welcome, I'm happy to accommodate.

If you have any other suggestions or requests, please send them my way.
Re: TheMidiBus MIDI library
Reply #7 - Jan 14th, 2009, 1:16am
 
Hi!
I am new to Processing programming and to MIDI.
Tried several things, using TheMidiBus library and it all worked well with receiving pitches from another application and controlling start/stop from my program. However, I can't understand how to receive song position pointers or clock information. Can you help me?

Thanks in advance.
Re: TheMidiBus MIDI library
Reply #8 - Jan 15th, 2009, 7:57pm
 
Hi elfh,

When I originally designed the library it was supposed to also support raw MIDI, but I clearly forgot to fully implement that! (it was partly there, but ....)

I have updated the library and added support for 2 types of raw MIDI. I will provide some examples below of how to do what you want with raw midi. I have also update the javadocs, and there is a new code example provided to illustrate these new features.

So go check out the updated javadocs (look at Papplet.rawMidi() and PApplet.midiMessage()), re-download the examples and re-download the library

I'm not exactly sure what you mean by clock information, so I'll assume that you want to receive "timing ticks" aka "timing clock" for the purpose of my examples

So if you wanted to get the song position pointer or the timing clock inside your PApplet (your sketch) here are your two options:

1. Use rawMidi(byte[] data)

Code:

import themidibus.*; //Import the library

void setup() {
size(300,300);
background(0);
}

void draw() {
//do something interesting
}

void rawMidi(byte[] data) {
if(data[0] == (byte)0xF2) {
//0xF2 is the status byte for SONG_POSITION_POINTER

println("Pointer LSB: "+(int)(data[1] & 0xFF));
println("Pointer MSB: "+(int)(data[2] & 0xFF));

} else if(data[0] == (byte)0xF8) {
//0xF8 is the status byte for TIMING_CLOCK

println("There was a timing tick");

}
}


2. Use midiMessage(MidiMessage message)

Code:

import themidibus.*; //Import the library
import javax.sound.midi.MidiMessage; //This is important because in this case we will use the MidiMessage class

void setup() {
size(300,300);
background(0);
}

void draw() {
//do something interesting
}

void midiMessage(MidiMessage message) {
if(message.getStatus() == 0xF2) {
//0xF2 is the status byte for SONG_POSITION_POINTER

byte[] data = message.getMessage();

println("Pointer LSB: "+(int)(data[1] & 0xFF));
println("Pointer MSB: "+(int)(data[2] & 0xFF));

} else if(message.getStatus() == 0xF8) {
//0xF8 is the status byte for TIMING_CLOCK

println("There was a timing tick");

}
}


A Quick Warning

Be careful manipulating bytes, because java only supports signed bytes but MIDI uses unsigned bytes

For comparisons do one of the following:
(in the example assume data[0] contains an unsigned byte from MIDI, stored in Java's signed byte type)

Code:
... if(data[0] == (byte)0x90) { ...  


This converts the int 0x90 to signed byte and you can safely compare the two signed bytes

Code:
... if((int)(data[0] & 0xFF) == 0x90) { ...  


This correctly converts the signed byte data[0] to int as if it was an unsigned byte

or if you want to be weird

Code:
... if(data[0] == (int)(byte)0x90) { ...  


Yeah I won't try and explain that one...

Finally if you just want to convert the unsigned byte to int so it can be displayed on the screen use:
Code:
 ... println((int)(data[0] & 0xFF)); ... 


as seen earlier ...

Doing it with interfaces

It would also be possible, if you wanted to, to do the same kind of thing by writing a new class which implements either the RawMidiListener interface or the StandardMidiListener interface. These interface are included in the library. Any object which is an instance of such a class could then be added to your MidiBus object using addMidiListener(MidiListener listener). Whenever a new MIDI message is received your listener would be notified in raw form or in MidiMessage form and you could process this information in the same way as above.

I can provide example of this if you're interested, just let me know.


I hope that this is helpful. Give me your feedback/requests/complaints
Re: TheMidiBus MIDI library
Reply #9 - Jan 16th, 2009, 2:30am
 
thank you for such a good post! your update and examples really helped. however i get only SPP (F2), no Timing Clock (F8). luckily, i realised, i don't need it right now, so can continue my development. also, i get a error, that is not influencing my work, but i'd like to know the reason anyway "ArrayIndexOutOfBoundsException1". test program is:

Code:
import themidibus.*;
int globalint; MidiBus myBus;
void setup() { size(400,400); background(0); MidiBus.list();
myBus = new MidiBus(this, 1, 9); }
void draw() { stroke(255,0,0,255); line(globalint, 10, 100, 100); }
void controllerChange(int channel, int number, int value) { globalint = number;};

list shows 19 available midi devices.
Re: TheMidiBus MIDI library
Reply #10 - Jan 16th, 2009, 6:08am
 
Hey thanks for the feedback.

I looked into it and I must admit I hadn't really tested all possible messages. Anyways it turns out I was improperly handling messages with only a status byte and no parameters - like the Timing Clock, 0xF8 - and this is almost for sure what was throwing the ArrayOutOfBoundException (although why it doesn't do so on my computer is a mystery I will have to look into). Because of this bug any such messages (with only a status byte) were being lost somewhere along the way.

Long story short, I've patched the bug and you can re-download it, again, and you should find that everything is working.

If you're still getting errors, or if you have any other problems please keep posting them.

(In particular, if you still get an ArrayOutOfBoundException please make sure you tell me, the constructor should not throw any such errors if your device index is invalid, the input validation should catch that. But as I said, I think it should be fixed now)
Re: TheMidiBus MIDI library
Reply #11 - Jan 16th, 2009, 8:56am
 
thanks again! timing clock works now, error keeps to appear. i noticed, it appears when i start an external sequencer application, which is sending midi data to my sketch. hope this helps.
btw, the above post was my first message on this forum, as i am learning processing for a few days only and doing my first project there. it is very inspiring to receive such support. best wishes to you!
Re: TheMidiBus MIDI library
Reply #12 - Jan 16th, 2009, 3:10pm
 
Alright, I'll try and reproduce the error you're talking about and see if I can pin it down.

You're welcome for the help, I'm just excited to have someone actively using my library.
Re: TheMidiBus MIDI library
Reply #13 - Jan 17th, 2009, 12:47am
 
Just made another small update, fixing more of the same problem. Re-download the library to get the fixes.

Elfh, this may have been the source of your ArrayOutOfBounds error. I will keep testing, if you're still getting the errors after redownloading please tell me.

Thanks
Re: TheMidiBus MIDI library
Reply #14 - Jan 17th, 2009, 12:00pm
 
yes, error is gone. thanks!
Pages: 1 2 3 4