我正在用iOS进行一些核心音频编程,我遇到了这样一种情况:我需要在一些C回调代码中使用我在Objective C中声明的变量。buffer变量必须能够被目标C和C语法访问,但是在C语法中,有一个错误说"Use of undeclared buffer“。
我该如何解决这个问题?提前谢谢。
码头。
变量是buffer,在RIORecoerdingViewController.h中声明如下:
@interface RIORecoerdingViewController : UIViewController <AVAudioSessionDelegate> {
OSStatus status;
AudioComponentInstance audioUnit;
AudioStreamBasicDescription audioFormat;
RIO rio;
IBOutlet UIButton *button;
BOOL isPlaying;
Float64 graphSampleRate;
NSString *destinationFilePath;
CFURLRef destinationURL;
ExtAudioFileRef outExtAudioFile;
// New
AUGraph theGraph;
TPCircularBuffer buffer;
}我希望在C回调函数中使用它
static OSStatus recordingCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
if (rio->recording)
{
TPCircularBufferProduceBytes(&buffer, abl.mBuffers[0].mData, inNumberFrames * 2 * sizeof(SInt32)); //&buffer has an error "Use of undeclared identifier buffer"
}
return noErr;
}发布于 2012-10-31 04:26:41
这就是recordingCallback中的void * inRefCon参数的用途。当您设置RemoteIO回调时,它可能如下所示:
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProc = &recordingCallback;
callbackInfo.inputProcRefCon = NULL;
AudioUnitSetProperty(rio,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callbackInfo,
sizeof(callbackInfo));您可以将inputProcRefCon用作在回调期间将成为inRefCon指针的任意指针。如果您只想访问一个变量,这很简单(只需传入该变量的地址)。例如,如果您需要的只是您的TPCircularBuffer:
callbackInfo.inputProcRefCon = &buffer;然后,当调用recordingCallback时,您可以通过inRefCon参数访问缓冲区,如下所示:
TPCircularBuffer * bufferPtr = (TPCircularBuffer *)inRefCon;
TPCircularBufferProduceBytes(bufferPtr, abl.mBuffers[0].mData, inNumberFrames * 2 * sizeof(SInt32));如果您需要访问更多的变量(如recording布尔值),您可以创建一个结构并将其地址传递给它。
有传言说,你应该避免在AURenderCallbacks中调用Objective-C (由于消息开销),但我目前没有任何确凿的数据来支持这一点。您可以将self作为inputProcRefCon传递,但YMMV。
发布于 2012-10-30 17:05:49
您的buffer变量是一个具体RIORecoerdingViewController实例的实例变量。没有实例的情况下使用它是没有意义的(“缓冲区属于哪个对象?”)。
因此,如果你有一个实例,你可以像往常一样引用ivar (即,如果你想走C指针路线,就引用yourRecoerdingViewController->buffer )。
发布于 2012-10-31 05:54:25
Objective C是纯C语言的一个纯超集。它允许你将对象和实例变量指针复制到标准C语言全局变量、参数变量和结构(等等)中。
一种(被认为丑陋的)可能性是将缓冲区指针复制到C全局变量中(并确保手动将其设为空,或者在缓冲区释放时不使用它)。然后从任何地方访问它,任何C函数。
其他(可能更优雅的)可能性包括将缓冲区指针复制到传递给C回调的结构中,或者将指向对象本身的指针直接传递给或通过struct元素传递给C回调。然后,您可以在.m文件中的C函数中使用"->“语法来访问传递给标准C函数的任何对象的任何实例变量,例如音频单元回调。(C函数必须在.m文件中声明,以便可以导入对象定义的Objective C接口。)
还有一种可能,但不适合于音频回调,那就是让C函数(在.m文件中)向单例模型对象发送消息,以获取/设置模型对象状态(包括缓冲区指针)。
https://stackoverflow.com/questions/13135240
复制相似问题