Question

Background: I am trying to write a program that will take MIDI information from my synthesizer and do various things with it musically. I have already connected the keyboard so that I receive MIDI data. In my midiInputCallback() method, which is the method that is called when MIDI data is generated, it takes 3 parameters: a MIDIPacketList, any object from "the outside" and the input source of the MIDI info. I'm trying to use the second parameter to pass in a UIButton. For now, I am using UIButtons for the piano keys. When I play on my synth, I want it to show (on my GUI) that a certain note has been played. To show this, the button that is associated with the key on my keyboard will appear "pressed".

Problem: Just to test this process, I tried passing in a NSNumber called test.

- (void)awakeFromNib {
    MIDIClientRef midiClient;
    checkError(MIDIClientCreate(CFSTR("MIDI client"), NULL, NULL, &midiClient), "MIDI client creation error");


    test = [NSNumber numberWithInt:4];


    MIDIPortRef inputPort;
    checkError(MIDIInputPortCreate(midiClient, CFSTR("Input"), midiInputCallback, &test, &inputPort), "MIDI input port error");

    unsigned long sourceCount = MIDIGetNumberOfSources();
    for (int i = 0; i < sourceCount; ++i) {
        MIDIEndpointRef endPoint = MIDIGetSource(i);
        CFStringRef endpointName = NULL;
        checkError(MIDIObjectGetStringProperty(endPoint, kMIDIPropertyName, &endpointName), "String property not found");
        checkError(MIDIPortConnectSource(inputPort, endPoint, NULL), "MIDI not connected");
    }
}

I pass test into MIDIInputPortCreate() which sets up the callback method as midiInputCallback().

Here's what midiInputCallBack() looks likes:

static void midiInputCallback(const MIDIPacketList *list, void *procRef, void *srcRef) {
    NSNumber *test = (__bridge_transfer NSNumber*)procRef;
    NSLog(@"%@", test);
    ...

I tried regular casting at first: NSNumber test = (NSNUmber) procRef, but then XCode said to use some bridge casting instead. I've read up on this a bit and someone suggested to use __bridge_transfer instead of just __bridge. Each time I run this I get a EXC_BAD_ACCESS(code=1, address=0x43f) error for my NSLog() in midiInputCallback() and I'm not sure how to proceed. Let me know if you need more information. I'm fairly new to developing for the Mac. Thanks in advance!

Was it helpful?

Solution

Had the same problem some time ago when writing a similar app that receives MIDI input and logs it to the console.

Am assuming you are working with ARC.

Have solved the problem as follows:

First, I did the following cast (that would be in your awakeFromNib method, whereas &test would be some_object):

SomeClass *some_object = [[SomeClass alloc] init];

MIDIInputPortCreate(midiClient, CFSTR("Input"), midiInputCallback, (__bridge_retained void *)some_object, &inputPort);

Then, inside midiInputCallback, I have casted it back with:

SomeClass *some_object = (__bridge SomeClass*)procRef;

Hope I don't have any typos here, just did a quick copy and paste with some modifications for the context of this answer.

Checkout the following question and its answers, helped me a lot understanding it:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top