1

iOSでCoreAudioプログラミングを行っていますが、ObjectiveCで宣言した変数をCコールバックコードで使用する必要がある状況になりました。バッファ変数は、Objective CとCの両方の構文でアクセスできる必要がありますが、C構文では、「宣言されていない識別子バッファの使用」というエラーがあります。

どうすればこれを解決できますか?前もって感謝します。

橋脚。

変数はバッファであり、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;
    }
4

3 に答える 3

2

あなたのbuffer変数は具体的なインスタンスのインスタンス変数ですRIORecoerdingViewController。インスタンスなしで使用するのは意味がありません (「バッファはどのオブジェクトに属していますか?」)。

したがって、インスタンスがある場合は、通常どおり ivar を参照できます (つまりyourRecoerdingViewController->buffer、C ポインター ルートを使用する場合)。

于 2012-10-30T09:05:48.953 に答える
1

これがvoid * inRefConあなたの議論のrecordingCallback目的です。RemoteIO コールバックを設定すると、おそらく次のようになります。

AURenderCallbackStruct callbackInfo;
callbackInfo.inputProc = &recordingCallback;
callbackInfo.inputProcRefCon = NULL;

AudioUnitSetProperty(rio,
                     kAudioOutputUnitProperty_SetInputCallback,
                     kAudioUnitScope_Global,
                     0,
                     &callbackInfo,
                     sizeof(callbackInfo));

は、コールバック中にポインタにinputProcRefConなる任意のポインタとして使用できます。inRefCon1 つの変数だけにアクセスしたい場合は簡単です (その変数のアドレスを渡すだけです)。たとえば、TPCircularBuffer だけが必要な場合:

callbackInfo.inputProcRefCon = &buffer;

次に、 yourが呼び出されると、次のように arg を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-30T20:26:41.367 に答える
1

Objective C はプレーン C の純粋なスーパーセットです。オブジェクトとインスタンス変数のポインタを標準 C のグローバル変数、パラメータ変数、構造体 (など) にコピーできます。

1 つの (見苦しい) 可能性は、バッファー ポインターを C グローバル変数にコピーすることです (そして、手動で null にするか、バッファーが解放されたときに使用しないようにしてください)。次に、どこからでも、任意の C 関数からアクセスします。

他の (おそらくもっと洗練された) 可能性としては、バッファー ポインターを構造体にコピーして C コールバックに渡す方法や、オブジェクト自体へのポインターを直接または構造体要素を介して C コールバックに渡す方法があります。次に、.m ファイルの C 関数から「->」構文を使用して、オーディオ ユニット コールバックなどの標準 C 関数に渡される任意のオブジェクトの任意のインスタンス変数にアクセスできます。(オブジェクト定義の目的の C インターフェイスをインポートできるように、C 関数は .m ファイル内で宣言する必要があります。)

さらに別の可能性はありますが、オーディオ コールバックには不適切ですが、モデル オブジェクトの状態 (バッファー ポインターを含む) を取得/設定するために、C 関数 (.m ファイル内) にシングルトン モデル オブジェクトをメッセージさせることです。

于 2012-10-30T21:54:25.010 に答える