edited July 2013


I'm trying to send a message via AEAudioControllerSendAsynchronousMessageToMainThread using the code below and pass through my PlaybackManager class so that I can send it a message on the main thread.

I'm getting a crash on the first line of the pageTurnHandler and need some help to figure out why as I'm not that experienced working with C.

Below is my code.


#pragma mark - Audio Timing Callback
    return playbackTimingReceiver;

static void playbackTimingReceiver(PlaybackManager* receiver,
                                   AEAudioController *audioController,
                                   const AudioTimeStamp *time,
                                   UInt32 const frames,
                                   AEAudioTimingContext context)
    receiver->_hostTime = getUptimeInMilliseconds(time->mHostTime);

static void pageTurnHandler(AEAudioController *audioController, void *userInfo, int userInfoLength)
    PlaybackManager* receiver = (__bridge PlaybackManager*)userInfo;
    NSLog(@Receiver:%@", receiver);


  • edited July 2013

    Your crash is happening because you need to dereference userInfo once more.

    AEAudioControllerSendAsynchronousMessageToMainThread will copy the value of the third argument (of length given by the fourth argument) - you've got that call correct, as you're passing the pointer to the id. But then in pageTurnHandler, you're treating userInfo as a PlaybackManager*, which it isn't: userInfo is a pointer to a memory area containing a PlaybackManager*. That is, it's a PlaybackManager**.

    So, you need at extra dereference:

    PlaybackManager* receiver = *((__bridge PlaybackManager**)userInfo);

    Um.. at least I think that's how you'd do it in an ARC-friendly way. Not sure if the compiler would complain about __bridge being used with something that isn't a pointer to an object. You might need to use (__bridge PlaybackManager*)*((PlaybackManager**)userInfo) if that doesn't work. Let me know either way, cos I'm interested =)

  • edited July 2013

    Thanks for your quick response Michael much appreciated.

    I tried:

    PlaybackManager* receiver = *((__bridge PlaybackManager**)userInfo);

    compiler complains with:
    Pointer to non-const type 'PlaybackManager *' with no explicit ownership
    Incompatible types casting 'void *' to 'PlaybackManager *__strong' with a __bridge cast

    and for

    PlaybackManager* receiver = (__bridge PlaybackManager*)*((PlaybackManager**)userInfo);

    compiler complains with:
    Pointer to non-const type 'PlaybackManager *' with no explicit ownership
    Incompatible type casting 'PlaybackManager *' to 'PlaybackManager *' with a __bridge case

  • Haha. Ahh. Um... I'm afraid your guess is as good as mine regarding that syntax, then. I'm personally not using ARC in my audio code as the last time I attempted a migration a couple years back it added more complexity than it removed due to all the C structures/etc I was using.

    So... You're on your own there =)

  • Hmm, what is the syntax without ARC? As maybe it is worth me switching it off for this class to make things easier...

    I've been researching and playing around and just can't get the complier quite.

  • edited July 2013
     PlaybackManager* receiver = *((PlaybackManager**)userInfo);
  • I spent a good amount of time on this today. Just to keep the conversation going, Brendt had his answer resolved here->

  • This post is really old and TAAE went through a second version and is now completely deprecated! (VERY SAD :( )
    However, if anyone comes across this ARC issue, here is my fix:

    PlaybackManager *audioBufferPlayer = *(__weak PlaybackManager **)userInfo;

    Just be sure to check for nil when accessing

Sign In or Register to comment.