Tuesday 2 November 2010

Sending MIDI through CoreMIDI

The 4.2 iOS GM seed is out. CoreMIDI is coming to the masses. So I've updated my CoreMIDI example to show how to send MIDI out through the USB port. (I've had a lot of people ask me for this.)

Go to the GitHub project page and check out the update. It's a simple addition, but shows the simplest way of getting MIDI data out of your application and through CoreMIDI.

Interestingly, the later - and the GM - versions of iOS 4.2 are far less forgiving of attached USB control devices. Most of the devices I test with are rejected by the iPad because they draw too much power. These are devices with LEDs, but that are certainly within USB power specifications. That's quite a shame.

As ever, I welcome feedback about this example project. Let me know if you find it useful.

26 comments:

Bruno Afonso said...

Have you tried the e-mu midi1x1? That's the one I was hoping to use...

Pete Goodliffe said...

No, but I have successfully used an Edirol UM-1

Bruno Afonso said...

I'm just afraid of it not working because it has leds :) maybe i'll just get one that works once 4.2 comes out

Smash said...

But this coremidi with usb work only with ipad or also with iphone? [and camera connection]

Pete Goodliffe said...

From what I understand, its iPad only. Certainly, at first.

The circuitry in the iPhone is different, so it cannot support the camera connection kit. Different hardware is required to enable a USB connection on an iPhone over the 30-pin connector.

Anonymous said...

FYI: I've used it with my M-Audio USB Uno, which has LEDs on it.

I've heard that supposedly Core MIDI also enabled MIDI over a network connection like WiFi (assuming the device can read the network connection, like a MacBook). Do you know if this is true?

Laci said...

Hi Pete,

I built your app today and tested on my iPad (4.2.1), but it seems not recognizing my Roland digital piano, which works nicely with another CoreMidi app (called Midi Monitor).
Do you have an idea why?
I would be happy to debug this issue and commit the code back to you, but I have no idea if this can be debugged at all, as connecting my piano takes away the PC connectivity.

Regards
Laci

Laci said...

I tried another Roland piano and it worked! I retry the former tomorrow.

Antonio Grazioli said...

thanks that's what I was looking for. I will test it soon on my iPad

Antonio Grazioli said...
This comment has been removed by the author.
Michael Engel said...

Thanks for the tip and your example code. Works great with a cheap (€6.50) LogiLink USB-to-MIDI-adapter (model UA0037 connected via noname iPad USB adapter, iPad 3G 16GB running iOS 4.2.1).

Greg Kellum said...

You got it to work with a Edirol UM-1? Strange. I just plugged mine in, and an ipad warning message popped up which said "unrecognized device". I tried plugging in a powered usb hub, because I was afraid it might be drawing too much power. But that didn't help... Did you have to do anything special to get yours to work?

Pete Goodliffe said...

The UM-1 works really well with iPad. I've not had problems with it.

In fact, I've not had any simple USB MIDI interface fail when placed behind a powered hub.

If your iPad gets upset, it might be worth switching it off and on again to reset it. Often this clears some UDB weirdness.

Leigh Hunt said...

Hi Pete - Thanks so much for your superb midi communication app. I have one question.. regarding threading and updating UIs. As you mention in the PGmidi.h comments, you must be careful about autoreleasing things. As a noobie, I am really struggling to find a way of updating my UI objects when receiving midi. I have a button on my ipad(call it mute on/off), which when touched sends midi to my laptop app, which in turn sends midi back to my ipad which updates the button image. This works fine, but when I sends the midi message directly from my laptop app instead, I cannot find a way to update the UI. Any help or pointers would be greatly appreciated.
Thanks,
Leigh Hunt

Pete Goodliffe said...

As documented in the PGMidiSourceDelegate protocol, you need to make use of NSObject's

performSelectorOnMainThread:withObject:waitUntilDone:

That will allow you to schedule selectors on the UI thread from the MIDI thread.

Pygar said...

Hi, Great Post and example code. All works well with USB camera connector, but I can't get MIDI Monitor to recognise any Wifi Input connections or data. Seems to work fine for Garageband and similar. Any ideas?

Pete Goodliffe said...

Please note that I have updated this post as the location of the PGMidi repo has changed (by popular request) to GitHub: https://github.com/petegoodliffe/PGMidi.

Darione said...

Hi Pete,

at first : THANKS, THANKS a lot! As you'll understand, I'm a newbie, and sorry for the maybe "stupid" questions. When I run the program in xcode (MIDIMonitor - iphone4.3 simulator) I find 4 warnings and 3 error:
warnings:
1) warning: anonymous variadic macros were introduced in C99
errors:
1)error: ISO C++ forbids compound-literals
2)error: ISO C++ forbids variable-size array 'packetBuffer'

Surely I'm doing something wrong. Thanks for all.

Dario

Pete Goodliffe said...

Dario, check that you've set the language standard in your "build settings" to at lead C99

Darione said...

Thanks again for your super-fast help.
I tried using:
1)GCC 4.2 --> error
2)LLVM GCC 4.2 --Z error
3)LLVM compiler 2.0 --> build succeeded but:
warinigs:
1)variadic macros were introduced in C99 [-Wvariadic-macros,1]
2) compound literals are a C99-specific feature [-pedantic,3]
3)Semantic Issue: Variable length arrays are a C99 feature, accepted as an extension

..anyway ...it runs....thanks Pete, thanks a lot!!!

Dario

Darione said...

Hi Pete,

I created an app using your old PGMIDI for Xcode 4.0, but now I tried to recompile the same software with Xcode 4.3.2, for iOS 5.1 . . . ... It doesn't work.
I refreshed my code with ARC, but now I find a new error:

MidiMonitor[49285:fb03] Error (Create MIDI client): -50:Error Domain=NSMachErrorDomain Code=-50 "The operation couldn’t be completed. (Mach error -50.)"

I don't understand what is changed, and why I should have problem with MIDI connection.

I also tried to use your last version of PGMIDI, and its code, but I get the same error.

Thanks a lot in advance.

Darione

Cicconet said...

Thanks for the post.
I'd like to connect your application (running on iPad) to GarageBand (running on the Mac) through the USB cable, but GarageBand doesn't recognize the iPad (with your app running) as an external MIDI device.
Is that connection possible? I'm doing something wrong?
Thanks.
Marcelo.

Anonymous said...

Hi Pete,

first, thanks for you example, that realy helped me to get into the CoreMidi stuff.

I want to ask you a question because I think you may have an answer or any idea why:

I want to call in my own App the function "MIDIFlushOutput" but it doesn't work.
So just in case I did something wrong, I tried it with your "original" example code. I just added one function to send MIDI-Notes in advance with an timestamp and then called MIDIFLushOutput, but I had the same behavior as bevore. All in "future" sended MIDI-Notes received the target. Actually this function should delete all outstanding MIDI-Notes, so that there won't be send.

Do you ore someone have any idea why?
Maybe I should post the code here !?


Best Regards,

FK

logtech1946 said...

Hi Pete

So many Core MIDI Apps are available. I want to design a 30 pins connector(hardware) with MIDI-IN/MIDI-OUT/THRU port to communicate MIDI Message with external MIDI controller. What basic components should have in PCB circuitry. Any input? Thanks.

Anonymous said...

Hi,

I got a warinigs like Dario here…
"Variable length arrays are a C99 feature"

Have Xcode 4.6
Have tested every combination of language standard in the "build settings"…

Has anyone solved this?

thax

Byte packetBuffer[size+100]; is the problem in…


- (void) sendBytes:(const UInt8*)bytes size:(UInt32)size
{
NSLog(@"%s(%u bytes to core MIDI)", __func__, unsigned(size));
assert(size < 65536);
Byte packetBuffer[size+100];
MIDIPacketList *packetList = (MIDIPacketList*)packetBuffer;
MIDIPacket *packet = MIDIPacketListInit(packetList);
packet = MIDIPacketListAdd(packetList, sizeof(packetBuffer), packet, 0, size, bytes);

[self sendPacketList:packetList];
}

Hilke said...

I wondered if the iOS simulator can also detect midi sources which are connected to my laptop. I don't think so, because nothing is detected when I run PGMidi.

I am actually a musician who's working on an iOS app. During a preparing phase (I'm creating songs) I'm running Ableton Live together with AU Lab. I worked out how to send midi from Live to AU Lab.

Now I would like to recreate the AUGraph that I have in AU Lab in Xcode and send the midi from Live to the iOS simulator to work on the next phase of the song. The purpose is that I have controls in the iOS app that change parameters in the AUGraph. It would be great if I still can run this together with Ableton Live