Hi Espen,
First, resolve the fact that you are casting a single variable, inRefCon, to two different and presumably incompatible types (MixerHostAudio * and soundStructPtr). It should be re-cast to the type that it was when you set your .inputProcRefCon property on the AURenderCallbackStruct var which you passed into an AudioUnitSetProperty(..., kAudioUnitProperty_SetRenderCallback...) call.
The general idea to do what you are asking goes like this:
1. Pass in a struct to the render callback. Objective-C objects are actually structures themselves with the instance variables being the struct members. You can (bypass popular dogma and) just make a @public instance variable (NOT a public ‘property’. See below...) and then pass in the Obj-C object and recaste it as you are doing and then access the instance vars like you would a struct (MyObj *myobj = (MyObj *)inRefCon; myobj->myIVar = X). Or you can create a separate struct or a C++ object...
2. Carefully (see below) set the struct member from within the callback
3. In your outer (Objective-C) class, create an NSTimer or some other mechanism to periodically poll the value and update the display. Alternatively, you can use CADisplayLink (https://developer.apple.com/library/ios/#DOCUMENTATION/QuartzCore/Reference/CADisplayLink_ClassRef/Reference/Reference.html)
BUT, there’s a lot more to the story. The callback runs in a separate, real time, and mission critical thread and you need to be very careful that you don’t delay it, otherwise you’ll end up with drop-outs. Hence you don’t want to have the callback update an Obj-C property (especially once for each frame!) as this results in Obj-C message calls which are potentially slow and to be avoided. You also need to ensure that you don’t read from the variable at the same time that you are writing to it, or the data might be inaccurate. To make things even tricker, you should avoid locks or at least not wait on them in the callback (see links below). OSAtomic functions are useful here.
There are a few do’s and a bunch of dont’s. The main rule is to do as little processing and take as little time as possible in your callback. Here is some essential reading:
http://www.subfurther.com/blog/2009/04/28/an-iphone-core-audio-brain-dump/
http://www.mikeash.com/pyblog/why-coreaudio-is-hard.html
http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html
https://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/Introduction/Introduction.html
Also you might want to move the timeIntoBeat assignment to take place once per callback rather than once per frame
iteration. If your ioBufferDuration is reasonable low, (say, <0.03s, >30Hz) then the callback will be called at a higher frequency than you’ll likely want your screen refresh to be anyway.
If all you are doing is passing the data from input to output untouched, I would imagine that this would all be much easier with a higher level API...
Good luck! I was unaware of all of this 2 weeks ago! What a ride it’s been!
Gratefully,
Hari Karam Singh
From: Espen Kluge [mailto:email@hidden]
Sent: 13 February 2012 19:30
To: Hari Karam Singh
Subject: Re: Bad access with reference within mixer callback
Thank you for your reply Hari.
What I'm trying to achieve is to update an animation based on the sampleNumber variable in the callback.
I cant seem to find information on how to handle information flow from within the callback to the UI side.
I'd be very appreciative if you could give me a really quick rundown?
I thought the best way was to create a property on the mixerHostAudio class, then update it from within the callback, then pull it from the UI side just using an NSTimer.