オーディオキューを使用して、学習目的で単純なレコーダーを構築しています。コールバック関数は、次のように定義された構造体へのポインターを受け取ります。
typedef struct RecorderUserData {
AudioFileID outputFileID;
SInt64 recordPacket;
BOOL recording;
} RecorderUserData;
コールバック関数内で、この構造体のフィールドにアクセスします。このコールバック関数は、Core Audio によって非同期的に呼び出されます。
static void RecorderAudioQueueInputCallback(void *inUserData,
AudioQueueRef inQueue,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc) {
UXAudioRecorderUserData *recorderUserData = (UXAudioRecorderUserData *)inUserData;
if (recorderUserData->recording) {
// do something while recording
}
// much more code
}
問題は、外部のメソッド呼び出しから記録を開始/停止したいということです。記録が開始されると、記録フィールドが YES に設定された構造体が準備されます。
録音を終了する必要がある場合は、録音フィールドを NO に設定する必要があります。
Kevin Avila と Chris Adamson によるコア オーディオ ブックでは、それらはすべて大きなモノリシックなメイン関数で行われており、この構造体にはまだ足元からアクセスできます。
しかし、Core Audio はこの構造体に非同期でアクセスしているので、-stopRecording メソッドが呼び出されたら、録音フィールドを安全に NO に設定するにはどうすればよいでしょうか? 問題は、おそらくレコーダー クラスでこの構造体へのポインターが必要になることですが、それへのアクセスをロックする方法も必要になるため、コールバック関数がそれを読み取っている間は NO に変更しません。