I googled around and I find a million results to this subject. But none of the pages helps me. I think that I have a very common problem. I'm playing around with audio programming especially working with audio queues. The purpose of my program does not matter for explaining the problem. But in a nutshell: I get an error when I try to call an objective-c function from c++ code. So here is my code that contains the error: AudioRecorder.h:
#import <Foundation/Foundation.h>
@interface AudioRecorder : NSObject {
}
-(void)setup;
-(void)startRecording;
-(void)endRecording;
-(void)playAlarmSound;
@end
And this is the implementation: AudioRecorder.mm:
#import "AudioRecorder.h"
#include <AudioToolbox/AudioToolbox.h>
#include <iostream>
using namespace std;
@implementation AudioRecorder
static const int kNumberBuffers = 3;
...
static void HandleInputBuffer (void *aqData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc ) {
AQRecorderState *pAqData = (AQRecorderState *) aqData;
if (inNumPackets == 0 &&
pAqData->mDataFormat.mBytesPerPacket != 0)
inNumPackets =
inBuffer->mAudioDataByteSize / pAqData->mDataFormat.mBytesPerPacket;
UInt32 size;
AudioQueueGetPropertySize ( inAQ, kAudioQueueProperty_CurrentLevelMeter, &size );
char* levelMeterData = new char[size];
AudioQueueGetProperty ( inAQ, kAudioQueueProperty_CurrentLevelMeter, levelMeterData, &size );
AudioQueueLevelMeterState* meterState = reinterpret_cast<AudioQueueLevelMeterState*>(levelMeterData);
cout << "mAveragePower = " << meterState->mAveragePower << endl;
cout << "mPeakPower = " << meterState->mPeakPower << endl;
delete levelMeterData;
[self playAlarmSound]; //<--- here I get the error: Use of undeclared identifier 'self'
if (pAqData->mIsRunning == 0)
return;
AudioQueueEnqueueBuffer ( pAqData->mQueue, inBuffer, 0, NULL );
}
...
-(void)playAlarmSound {
NSLog(@"Alarmsound....");
}
When I omit "[self playAlarmSound];" then everything works fine. So how do I call this Objective-C function from my C++ code?
You really can't use C in Objective-C, since Objective-C is C. The term is usually applied when you write code that uses C structures and calls C functions directly, instead of using Objective-C objects and messages.
You can mix C++ in with Objectiv-C (Objective C++). Write a C++ method in your Objective C++ class that simply calls [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self. layer]; and call it from your C++.
Calling a method While creating a Objective-C method, you give a definition of what the function has to do. To use a method, you will have to call that function to perform the defined task. When a program calls a function, program control is transferred to the called method.
It's Shorthand writing. In Objective-C, any character , numeric or boolean literal prefixed with the '@' character will evaluate to a pointer to an NSNumber object (In this case), initialized with that value. C's type suffixes may be used to control the size of numeric literals.
self
only exists in Objective-C methods and that is a C style function. You need to pass self
from an Objective-C method to the inUserData when you set up the callback, then cast it back to the correct type.
//This is an example for using AudioQueueNewInput
//Call this in an Objective-C method passing self to inUserData
AudioQueueNewInput (
const AudioStreamBasicDescription *inFormat,
AudioQueueInputCallback inCallbackProc,
// this is where you will pass (void*)self
void *inUserData,
CFRunLoopRef inCallbackRunLoop,
CFStringRef inCallbackRunLoopMode,
UInt32 inFlags,
AudioQueueRef *outAQ
);
And your original implementation
static void HandleInputBuffer (void *aqData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc )
{
AudioRecorder *ar_instance = (AudioRecorder*)aqData;
...
[ar_instance playAlarmSound];
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With