ofxMidi updates


#41

Hi, just started using OF and ofxMidi, some minor tweaking on the midi listener to fit it to my app, and it all works well.
Just wanted to reply about the SYSEX. I think all you need is something like this:

  
void ofxMidiOut::sendSYSEX(int manufacturer_id, int *data, int count){  
	int i;  
    message.clear();  
    message.push_back( 0xF0);  
    message.push_back( manufacturer_id );  
	for(i=0;i<count;i++){  
		message.push_back( data[i] );		  
	}  
    message.push_back( 0xF7 );  
    sendMessage();  
}  
  

Since SYSEX is device/manufacturer specific, it is really just a stream of bytes with a command byte (byte with msb set to 1) at the beginning (0xF0) and end (0xF7). The first data byte (byte with the msb set to 0) is the manufacturer’s id, since MIDI devices can be chained (well, hardware devices with THRU ports, from the early days of MIDI) the manufacturer ID would allow devices to only receive and parse packets intended for them.

So the function is rather simple, however the contents of that data array are device/software specific and may have a very specific structure. A function like above would require you to setup the data array accordingly, and would probably be made easier if you create data structure for your device’s SYSEX packet and then send it flattened to the function.

Thanks for your work on ofxMidi.
-mat

edit: put that function in code block


#42

yes I agree with that, looking good.
some minor points: manufacturer ID can also be extended (http://home.roadrunner.com/~jgglatt/tech/midispec/id.htm), there should be some logic for premature interruption, in the receiveSysEx function, and capitalization should be SysEx (to follow convention).


#43

hey chris, any updates on the new ofxMidi? i see the github repo at https://github.com/chrisoshea/ofxMidi but it looks like you haven’t updated it yet.


#44

here’s an example for 007 on OSX with ofxMidi from the first github commit.

it shows how to use an ofThread to create a sequencer that runs independently of the draw loop. hopefully the code is reusable.

SequencerExample.zip

![](http://forum.openframeworks.cc/uploads/default/1819/Screen shot 2011-09-03 at 8.01.40 PM.png)


#45

hmm still no updates from you chris, so i decided to fork and start committing my updates. https://github.com/kylemcdonald/ofxMidi


#46

Nice Kyle. Can you list what your changes are? I assume this doesn’t integrate the iOS stuff we were discussing in another thread?


#47

i haven’t done any iOS work. for changes see https://github.com/kylemcdonald/ofxMidi/commits

i’m actively using ofxMidi as part of a project right now so i will probably make a few more changes.


#48

Good to see updates. I’m planning on using ofxMidi with iOS soon, so expect some pull requests to come your way …


#49

Looking forward to see what you do Dan. I’m also implementing MIDI on iOS, but didn’t decide to use ofxMIDI since there’s a lot of differences. I look forward to seeing how you integrate things. If you need another tester, let me know. :slight_smile:


#50

Hey

I had started making changes to my offline version, but then life got in the way and progress stopped. I’d also not figured out the correct way to use git then, so made a few changes without committing each one at a time.

Kyle, I’m a strong believer in having one master version that everyone downloads to get the latest version so it isn’t confusing. Do you want to push your changes into my branch?

With more people adding to the code, it doesn’t make sense to have peoples names on the files anymore? “ofxMidi was originally developed by Chris O’Shea and Arturo Castro.”

Can you let me know what code you’ve changed in the ‘massive source cleanup’? Github diff viewer is being annoying, as I can only see the #ifndef - #pragmaonce change at the top but it makes it look like lots of the code has changed with + - but the code hadsn’t changed here.

Thanks


#51

the ‘massive source cleanup’ was only formatting. i don’t think i changed anything else during that commit. there was just some weird mixes of tabs and spaces, and coding styles. so i normalized it.

i sent you a pull request with notes about how it works. i didn’t realize you were modifying it outside github. that complicates things a little bit, and i wouldn’t have done the cleanup if i knew that.


#52

is there a reason the virtual port stuff was removed?

i’m trying to build a MIDI-OSC proxy app.

in the older ofxMidi ( I don’t remember whose it was, arturo’s ?) I managed to get the virtual output port working but not the input.

now the virtual ports are gone in both in/outs variants.

any ideas?

thanks

/*j


#53

I’m (also) a strong believer in having one master version that everyone downloads to get the latest version.

j45ch : openVirtualPort still exists in the version from here:
https://github.com/chrisoshea/ofxMidi
It seems also to be actually the most complete version.

By the way, I like the addition of fonction like sendProgramChange() or sendPitchBend()
I just think it should be complete (with both afterTouch too)

System common messages (start/stop/continue) could also be usefull.

What I think is really missing is :
int getNumPorts(void)
both for input than for output.

(unsigned int nPorts; is not public, so I actually have to check portNames.size() to know the available number of ports)


#54

Hi all,

Looking to use this add-on (great to see that its well maintained). I can’t seem to get passed this linking error.

Undefined symbols for architecture i386:
“testApp::newMessage(ofxMidiEventArgs&)”, referenced from:
testApp::setup() in testApp.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status

I’m on 10.7, Xcode 4. I would have thought that any linking errors I may have encountered would be related to the core.MIDI framework, but as that is included in the build phase, I’m not that sure why the linker is throwing this error. Could anyone shed some light on the situation?

Many thanks in advance.


#55

Apologies, my own silly mistake there. All sorted now, I just hadn’t put the void in the TestApp.cpp file that I’m currently working on. I put it down to snow blindness from coding all day. Again, brilliant addon, really useful and I hope to contribute in some small way very soon.


#56

Thanks for this addon, I’m using it in my project and it’s been great!


#57

Howdy all,

I will be using ofxMidi in a project and decided to make some updates in the process. They mainly involved making ofxMidi easier to use and fully-featured.

You can check out the updates on the develop branch of my Github fork: https://github.com/danomatika/ofxMidi/tree/develop

Here’s a list of changes and the reasoning behind them:
[list]

  • moved rtmidi source location to src/rtmidi: The Linux makefiles only build sources in the project src directory, linked libs are added from the libs dir. The layout has worked well for me in ofxPd. See a relevant discussion here.

  • updated rtmidi to 1.0.15, included the rtmidi readme (has license), and added a script to update rtmidi in scripts/: the rtmidi license has a portion that explicitly states the license must be included with the sources

  • added exception handling for RtError

  • replaced log stream operators with ofLog calls, so it should work with 0062

  • opening ports now returns a bool

  • ofxMidiOut now sends all message types and also provides a stream interface: the stream interface is similar to the one I use in ofxPd and makes byte sending more compact in code

  • made ofxMidiIn protected variables private: As far as I could tell, the class couldn’t be inherited and the ofxMidiListener class is the main interface for midi events anyway.

  • no longer grab port names by default: filling the port name vector by default seems redundant if there are multiple instances of ofxMidiIn/ofxMidiOut, it is now only filled when you call getPortList(); you can call listPorts() like before; also portNames is now portList and made private

  • moved the ofxMidiInCallback inside ofxMidiIn as a static function

  • added ignoreTypes to ofxMidiIn: ignoring sysex, timing, and active sense messages by default seems a reasonable default from RtMidi, users can simple call ignoreTypes themselves to enable receiving these messages

  • ofxMidiEventArg renamed to ofxMidiMessage

  • ofxMidiMessage now includes variables and raw byte vector (for full sysex messages, etc): bit masking midi messages seemed like an easy enough task to add inside ofxMidiIn and saves us alot of boiler plate

  • ofxMidiConstants defines are now enums: this makes for unambiguous status types inside ofxMidiMessage

  • all sources are (I believe) now fully commented

  • updated the examples

  • updated the readme

[/list]

Please test and give me feedback. If there aren’t any major issues, I’ll make a pull request to Chris’s repo.


#58

can you make a pull request? then it’s easier to see the diff in one spot.


#59

Done https://github.com/chrisoshea/ofxMidi/pull/9


#60

Also, I thought about adding the midi listener channel filtering from ofxPd, but it’s a bit complex and dosen’t use the OF event system. I decided it’s better to get the basic updates working first.

  
  
         /// \section Midi Receiving  
          
        /// add/remove incoming midi event receiver  
		///  
		/// receivers automatically receive from *all* incoming midi channels  
        ///  
        /// see receive/ignore for specific channel receiving control  
		///  
		void addMidiReceiver(pd::PdMidiReceiver& receiver);  
		void removeMidiReceiver(pd::PdMidiReceiver& receiver);  
		bool midiReceiverExists(pd::PdMidiReceiver& receiver);  
		void clearMidiReceivers();  
          
		/// set a receiver to receive/ignore an incoming midi channel  
		///  
		/// receive/ignore a specific midi channel or 0 for all channels,  
		/// make sure to add the receiver first  
		///  
        /// note: midi bytes are sent to all receivers  
		/// note: the global channel (aka 0) is added by default  
		/// note: ignoring the global channel ignores *all* channels,  
		///       so the receiver will not receive any midi events except for  
        ///       midi bytes  
		///  
		/// also: use negation if you want to plug into all channels but one:  
		///  
		/// pd.receiveMidi(midiReceiver);   // receive from *all* channels  
		/// pd.ignoreMidi(midiReceiver, 2); // ignore channel 2  
		///  
		void receiveMidi(pd::PdMidiReceiver& receiver, int channel=0);  
		void ignoreMidi(pd::PdMidiReceiver& receiver, int channel=0);  
		bool isReceivingMidi(pd::PdMidiReceiver& receiver, int channel=0);