Re: Newbie documentation for MIDI
Re: Newbie documentation for MIDI
- Subject: Re: Newbie documentation for MIDI
- From: Robert Grant <email@hidden>
- Date: Tue, 26 Nov 2002 14:37:04 -0500
I started having the same thought after I'd posted that! How on earth
would the NC
know which thread to send the notification? :-)
Still it all works fine as long as he doesn't try to do any drawing in
the MIDI thread. Set
some values and tell things they need to be redisplayed and then get
out of there. The
UI thread will pick up the drawing task.
Robert.
On Tuesday, November 26, 2002, at 02:29 PM, Chris Reed wrote:
Keep in mind that when you post notifications using
NSNotificationCenter, the observers are send messages immediately.
Notifications are effectively just like function calls. So for the
example below, your observer is being called in the MIDI thread, not
the main thread!
(Of course, I may be wrong, but I've stepped through notifications in
the debugger and watched it immediately call my observer.)
Look at using NSDistributedNotificationCenter if you want the observer
to receive its notification in its own thread. I don't know much about
it, but I think that's one of its uses. (The other being inter-process
notifications.)
-chris
On Tuesday, November 26, 2002, at 11:35 am, Robert Grant wrote:
Use Notifications!
Sounds like you're using Cocoa and so what you want to do is a piece
of
cake. I do something similar for my flashing LEDs in Rax.
CoreMIDI invokes your call back in a separate thread so you're
already multi-threaded
for free. Just post a Notification in the callback thread and the
main UI thread will
pick it up and process it nicely.
Here's a function I use for walking the MIDIPacket (adapted from some
sample code):
const Byte * NextMIDIEvent(const MIDIPacket *pkt, const Byte *event)
{
const Byte *end = &pkt->data[pkt->length];
if (event < &pkt->data[0] || event >= end)
return NULL;
Byte c = *event;
switch ((c & 0xF0) >> 4)
{
default: // data byte -- assume in sysex
while ((*++event & 0x80) == 0 && event < end)
;
break;
case 0x8:
case 0x9:
case 0xA:
case 0xB:
case 0xE:
event += 3;
break;
case 0xC:
case 0xD:
event += 2;
break;
case 0xF:
switch (c) {
case 0xF0:
while ((*++event & 0x80) == 0 && event < end)
;
break;
case 0xF1:
case 0xF3:
event += 2;
break;
case 0xF2:
event += 3;
break;
default:
++event;
}
break;
}
return (event >= end) ? NULL : event;
}
Here's my call back proc - it just gets me back into Objective-C
ASAP! :-)
void MIDIInputProc(const MIDIPacketList *pktlist, void *refCon,
void *connRefCon)
{
Rack* rack = (Rack*)refCon;
[rack midiReceived: pktlist];
}
And here's a simplified version of my -(void)midiReceived method with
a Notification:
-(void)midiReceived:(const MIDIPacketList *)pktlist
{
int j = 0;
MIDIPacketList* list = (MIDIPacketList*)pktlist;
MIDIPacket *inPacket = (MIDIPacket *)list->packet; // remove const
BOOL noteOn = FALSE;
for ( j = 0; j < list->numPackets; ++j) {
Byte* event = inPacket->data; // assume there's at least one
event per packet
do {
if (event[0] >> 4 == 0x09 && event[2] > 0)
noteOn = TRUE;
} while(event = NextMIDIEvent(inPacket, event));
inPacket = MIDIPacketNext(inPacket);
}
if (noteOn) {
NSNotificationCenter *nc = [NSNotificationCenter
defaultCenter];
[nc postNotificationName: @"NoteOn" object: self];
}
}
Just register for a Notifcation in the defaultCenter and you're
rocking. If you want
info on Notifications Aaron Hillegaas's book is good and you probably
have it if
you're using Cocoa.
Hope that helps. Look at the Echo.cpp example for setting up a MIDI
source in
your app.
Robert.
On Tuesday, November 26, 2002, at 12:06 PM, Michael Bishop wrote:
I'm pretty much in the same boat as Jont, but for MIDI.
I know the languages and technologies, but I'd love a simple MIDI
sample code bit.
What I'm trying to do is just listen for MIDI events and then update
the screen. I don't want to update the screen in the High-Priority
MIDI thread so I need to notify the UI thread somehow that new MIDI
data has been captured.
It seems straightforward enough. Finding the right threading model
is what I'm stuck on.
From my reading, it seems like the ways I can do this are with
Notifications or with DO Messages. What are the best strategies?
Is there a bit of sample code that just does this?
_ michael
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.