basic C++ question (using OF + CoreAudio)

Hi - my C++ skills are pretty light but I manage to get stuff done - until I run into a wall. The current wall:

I am using CoreAudio to do some stuff with Midi playback. I’ve got lots of it working but am stuck on a simple thing. (I don’t know the right C++ terminology so bear with me…).

I’m using a render callback function in CoreAudio to indicate when a midi note event is being rendered by an AU. If I define it as a non-class function and stick it main.cpp (or testApp.cpp for that matter) it works - I get the events. The problem is I need to be able to have the instance of testApp get those events.

So… is there a way to get at the instance of testApp from main.cpp so I can call the testApp method I need?

OR is there some C++ voodoo to have a non-class function residing within a class call a method of that class? For example, if the function below is in my class, how can it call a method on the instance of the class…

  
  
OSStatus renderCallback(void *inRefCon,  
                                              AudioUnitRenderActionFlags *	ioActionFlags,  
                                              const AudioTimeStamp *		inTimeStamp,  
                                              UInt32				inBusNumber,  
                                              UInt32				inNumberFrames,  
                                              AudioBufferList *		ioData)  
{  
           someClassMethod(); //doesn't work  
           this.someClassMethod(); // doesn't work  
           self.someClassMethod(); // doesn't work  
  
}  
  

I don’t know for sure but I think the CoreAudio stuff doesn’t take instance methods as callbacks - at least that’s what I’ve gleaned from the error msg (below). I’m fine doing it anyway that works.

thanks for any tips!

[tt]error: argument of type ‘OSStatus (testApp::)(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32, UInt32, AudioBufferList*)’ does not match ‘OSStatus (*)(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32, UInt32, AudioBufferList*)’
[/tt]

since i’m not understanding your problem 100%, I will try to help, maybe this fixes the problem anyway:

try to declare your callback method as a class method in this way

  
OSStatus testApp::renderCallback(void *inRefCon, ...   

dont forget to add it to your header file, too.
then you should call all methods auf testapp with

  
handleCallback();  

or something like this

As the callback is a c-function, it doesn’t know anything about your c+±object. When registering the callback-function there should be a way to add some userdata (probably inRefCon), where you supply a pointer to your c+±object. This pointer gets carried to your callback-function:

With that it’s pretty easy:

  
  
OSStatus renderCallback(void *inRefCon,  
                                              AudioUnitRenderActionFlags *	ioActionFlags,  
                                              const AudioTimeStamp *		inTimeStamp,  
                                              UInt32				inBusNumber,  
                                              UInt32				inNumberFrames,  
                                              AudioBufferList *		ioData)  
{  
           MyObject* obj = (MyObject*)(inRefCon);  
           if(obj) obj->somClassMethod();  
  
}  
  
  

HTH,
Stephan

Thanks for the replies - I was able to solve it based on the info in this post here:
http://forum.openframeworks.cc/t/access-app-instance-from-static-function-callback/6364/3

Setting up the callback from within my testApp instance + passing a reference to the instance as an arg:

  
AudioUnitAddRenderNotify(theSynth, renderCallback, this);   

Calling the instance from the renderCallback function defined in main.cpp

  
OSStatus renderCallback(void *inRefCon,    
                        AudioUnitRenderActionFlags *    ioActionFlags,    
                        const AudioTimeStamp *      inTimeStamp,    
                        UInt32              inBusNumber,    
                        UInt32              inNumberFrames,    
                        AudioBufferList *       ioData)    
{    
    testApp * app = static_cast <testApp *>(inRefCon);     
    app->getEvent();    
}   

I don’t understand ‘static_cast’ here - but it works…

static_cast is just one of the the C++ ways of casting from one pointer type to another without too many type-safety checks. It’s just a way to safely get the testApp type information about the void* that rtAudio is returning. There’s a really nice tutorial about casting in C++ here:

http://www.cplusplus.com/doc/tutorial/typecasting/