ソースの表示以前のリビジョンバックリンク全て展開する/折り畳む文書の先頭へ Share via Share via... Twitter LinkedIn Facebook Pinterest Telegram WhatsApp Yammer Reddit Teams最近の変更Send via e-Mail印刷パーマリンク × 文書の過去の版を表示しています。 <align right>翻訳元:Audio Queue Services Programming Guide: Recording Audio</align> ※以前のwikiで本章は翻訳途中だったため、10.9のリファレンスから再翻訳しています。 音声の記録 Audio Queue Serviceを使って録音する際、その保存先はディスク上のファイル、ネットワークの接続先、メモリ内のオブジェクトなど、殆ど何でも選択出来ます。 本章では最も一般的なシナリオである、ディスクのファイルへの基本的な録音方法を解説します。 本章はMac OS X Core Audio SDKのいくつかのCクラスを用いた、ANSI-Cベースの録音の実装について解説します。Objective-Cベースの例は、[[http://developer.apple.com/devcenter/ios/ iOS Dev Center]]のSpeakHereサンプルコードをご覧ください。</note> アプリケーションに録音機能を追加するには、一般的に以下の手順を踏みます: - 状態(state)、フォーマット、ファイルパス情報を管理する独自構造体を定義する。 - 実際の録音を担うAudio Queueコールバック関数を書く。 - (任意で)Audio Queue Bufferの最適なサイズを決めるコードを書く。マジッククッキーを使うフォーマットで録音するなら、マジッククッキーが機能するコードを書く。 - 独自構造体のフィールドを埋める。これにはファイルへのパスは勿論、Audio Queueがファイルへ送る録音データストリームの指定も含む。 - 録音Audio Queueを生成し、Audio Queue Bufferセット作成のために問い合わせる。また、記録に使うファイルを作成する。 - Audio Queueに録音開始を伝える。 - 録音が終わったらAudio Queueを停止し、そして破棄する。Audio Queueは保持するバッファを破棄する。 以降、本章ではこれら手順の詳細を解説します。 ===== 状態を管理する独自構造体の定義 ===== Audio Queue Serviceを使った録音ソリューション開発の第1ステップは、独自構造体の定義です。 この構造体を使い、音声フォーマットとAudio Queueの状態管理を行います。 リスト2-1は構造体の例です: リスト 2-1 録音Audio Queueの独自構造体 static const int kNumberBuffers = 3; // 1 struct AQRecorderState { AudioStreamBasicDescription mDataFormat; // 2 AudioQueueRef mQueue; // 3 AudioQueueBufferRef mBuffers[kNumberBuffers]; // 4 AudioFileID mAudioFile; // 5 UInt32 bufferByteSize; // 6 SInt64 mCurrentPacket; // 7 bool mIsRunning; // 8 }; この構造体のフィールドの解説です。 - 使用するAudio Queue Bufferの数の設定。 – <ilcode>AudioStreamBasicDescription</ilcode>構造体(<ilcode>CoreAudioType.h</ilcode>より)は、ディスクに書き込む音声データフォーマットを表します。このフォーマットは<ilcode>mQueue</ilcode>フィールドで指定されるAudio Queueによって使用されます。 .. <ilcode>mDataFormat</ilcode>フィールドは、“[[Set Up an Audio Format for Recording]]”で解説されるように、最初はあなたのプログラムのコードによって埋められます。“[[Getting the Full Audio Format from an Audio Queue]]”で解説するように、Audio Queueに<ilcode>kAudioQueueProperty_StreamDescription</ilcode>プロパティを問い合わせて、このフィールドを更新するのが良い方法です。Mac OS X v10.5では、代わりに<ilcode>kAudioConverterCurrentInputStreamDescription</ilcode>プロパティを使います。 .. <ilcode>AudioStreamBasicDescription</ilcode>構造体の詳細は、[[https://developer.apple.com/library/mac/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/Reference/reference.html|Core Audio Data Types Reference]]をご覧ください。 - あなたのアプリケーションによって生成される録音Audio Queue。 - そのAudio Queueによって管理されるAudio Queue Bufferへのポインタの配列。 - プログラムが音声データを記録するファイルを表すAudio Fileオブジェクト。 - 各Audio Queue Bufferの大きさのバイト数。この値は、以下のサンプルの<ilcode>DeriveBufferSize</ilcode>関数で、Audio Queueが生成されAudio Queueが開始される前に計算されます。“[[Write a Function to Derive Recording Audio Queue Buffer Size]]”をご覧ください。 - 現在のAudio Queue Bufferから書き出される最初のパケットのパケットインデックス。 - Audio Queueが実行中かどうかを示すブール値。 ===== 録音Audio Queueコールバックの実装 ===== 次に、録音Audio Queueコールバックを書きます。 このコールバックには2つの目的(main things)があります: * 新しく埋められたAudio Queue Bufferの内容を記録中のファイルに書き出す。 * (先ほど中身をディスクに書き出した)Audio Queue Bufferをバッファーキューに加える。 本項ではコールバック宣言の例を示してから、それら2つの仕事を個別に解説し、最後に録音コールバックの全体を示します。 録音Audio Queueコールバックの役割像については、<imgref fig1-3>を見直して下さい。 ==== 録音Audio Queueコールバックの宣言 ==== リスト2-2は録音Audio Queueコールバック関数の宣言例で、<ilcode>AudioQueue.h</ilcode>ヘッダで<ilcode>AudioQueueInputCallback</ilcode>として宣言されています: リスト 2-2 録音Audio Queueコールバック宣言 static void HandleInputBuffer ( void *aqData, // 1 AudioQueueRef inAQ, // 2 AudioQueueBufferRef inBuffer, // 3 const AudioTimeStamp *inStartTime, // 4 UInt32 inNumPackets, // 5 const AudioStreamPacketDescription *inPacketDesc // 6 ) コードの働きを見てみましょう: - 典型的には<ilcode>aqData</ilcode>は、“状態を管理する独自構造体の定義”で解説したAudio Queueの状態データを含む独自構造体で - このコールバックを所持するAudio Queueです。 - 録音で入ってくる音声データを含むAudio Queue Bufferです。 - Audio Queue Bufferの先頭サンプルのサンプル時間です(簡易的な録音では必要ありません)。 - <ilcode>inPacketDesc</ilcode>パラメータが持つパケット記述子の数。<ilcode>0</ilcode>はCBRデータを表します。 - パケット記述子を必要とする圧縮音声データ形式のための、バッファ内のパケット用のエンコーダが提示するパケット記述子。 ==== Audio Queue Bufferをディスクへ書き出す ==== 録音Audio Queueコールバックの最初の仕事は、Audio Queue Bufferをディスクに書き出す事です。 このバッファは、たった今コールバックのAudio Queueが入力デバイスからの新しい音声データで埋めたものです。 リスト2-3で示すように、コールバックは<ilcode>AudioFile.h</ilcode>ヘッダファイルの<ilcode>AudioFileWritePackets</ilcode>関数を使います。 リスト 2-3 Audio Queue Bufferをディスクに書き出す AudioFileWritePackets ( // 1 pAqData->mAudioFile, // 2 false, // 3 inBuffer->mAudioDataByteSize, // 4 inPacketDesc, // 5 pAqData->mCurrentPacket, // 6 &inNumPackets, // 7 inBuffer->mAudioData // 8 ); コードの働きを見てみましょう: - <ilcode>AudioFile.h</ilcode>ヘッダファイルで宣言されている<ilcode>AudioFileWritePackets</ilcode>関数は1つのバッファの内容を音声データファイルに書き出します。 - 音声ファイルオブジェクト(<ilcode>AudioFileID</ilcode>型)は書き出し先の音声ファイルを表します。<ilcode>pAqData</ilcode>変数はリスト2-1で解説したデータ構造体へのポインタです。 - <ilcode>false</ilcode>は、関数が書き込み時にデータをキャッシュすべきではない事を示します。 - 書き出す音声データのバイト数です。<ilcode>inBuffer</ilcode>変数はAudio Queueがコールバックに渡したAudio Queue Bufferを表します。 - 音声データのパケット記述子配列です。NULLはパケット記述子が必要ない事を示します(CBRの音声データなど)。 - 書き出す先頭パケットのパケットインデックスです。 - 入力では出力するパケット数を表します。出力では実際に出力されたパケット数が返ります。 - 音声ファイルに書き出す新しい音声データです。 ==== Audio Buffer Queueをキューに加える ==== Audio Queue Bufferの音声データは音声ファイルに書き出されたので、リスト2-4で示す通り、コールバックはそのバッファをキューに戻します。 バッファキューに戻した時点で、そのバッファは待ち行列に並び、次なる入力音声データの受け入れ態勢が整います。 リスト 2-4 ディスクへ出力後のAudio Queue Bufferのエンキュー AudioQueueEnqueueBuffer ( // 1 pAqData->mQueue, // 2 inBuffer, // 3 0, // 4 NULL // 5 ); コードの働きを見てみましょう: - <ilcode>AudioQueueEnqueueBuffer<ilcode>関数はAudio Queue BufferをAudio Queueのバッファキューに追加します。 - 指定したAudio Queue Bufferを追加するAudio Queue。<ilcode>pAqData</ilcode>変数はリスト2-1で解説したデータ構造体へのポインタです。 - キューに追加するAudio Queue Buffer。 - Audio Queue Bufferのデータのパケット記述子の数。本パラメータは録音では使わないので、<ilcode>0</ilcode>を設定します。 - Audio Queue Bufferのデータのパケット記述子配列。本パラメータは録音では使わないので、<ilcode>0</ilcode>を設定します。 ==== 完全な録音Audio Queueコールバック ==== リスト2-5は完全な録音Audio Queueコールバックの基礎バージョンです。 本ドキュメント内の他のコード例と同様、以下のリストはエラー処理を考慮していません。 リスト 2-5 録音Audio Queueコールバック関数 static void HandleInputBuffer ( void *aqData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumPackets, const AudioStreamPacketDescription *inPacketDesc ) { AQRecorderState *pAqData = (AQRecorderState *) aqData; // 1 if (inNumPackets == 0 && // 2 pAqData->mDataFormat.mBytesPerPacket != 0) inNumPackets = inBuffer->mAudioDataByteSize / pAqData->mDataFormat.mBytesPerPacket; if (AudioFileWritePackets ( // 3 pAqData->mAudioFile, false, inBuffer->mAudioDataByteSize, inPacketDesc, pAqData->mCurrentPacket, &inNumPackets, inBuffer->mAudioData ) == noErr) { pAqData->mCurrentPacket += inNumPackets; // 4 } if (pAqData->mIsRunning == 0) // 5 return; AudioQueueEnqueueBuffer ( // 6 pAqData->mQueue, inBuffer, 0, NULL ); } コードの働きを見てみましょう: - インスタンス化を行う際にAudio Queueオブジェクトに供給される、様々な状態データと共に書き出し先の音声ファイルを表すAudio Fileオブジェクトを含む独自構造体。“状態を管理する独自構造体の定義”をご覧ください。 - Audio Queue BufferがCBRデータを含む場合、バッファ内のパケット数を算出する。この値はバッファ内の合計バイト数を1パケット毎のバイト数(定数)で割った値に等しい。VBRデータでは、Audio Queueはコールバック呼び出し時のバッファ内のパケットデータ数を提供する。 - バッファの内容を音声データファイルに書き出す。詳しい解説は“Audio Queue Bufferをディスクへ書き出す”をご覧ください。 - 音声データの書き出しが成功すれば、音声データファイルのパケットインデックスをインクリメントし、バッファの次の音声データ書き出しに備える。 - Audio Queueが停止していたら関数を抜ける。 - 今しがた中身が音声ファイルに書き出されたAudio Queue Bufferをキューに戻す。詳しい解説は“Audio Buffer Queueをキューに加える”をご覧ください。 ===== 録音Audio Queue Bufferサイズを計算する関数の実装 ===== Audio Queue Serviceは使用するAudio Queue Bufferサイズの特定を、アプリケーションが行うと期待します。 リスト2-6はその方法の1つです。 It derives a buffer size large enough to hold a given duration of audio data. ここでの計算は録音する音声データ形式を考慮に入れます。 フォーマットは、音声チャンネル数などの、バッファサイズに影響するであろう全ての要因を含みます。 リスト 2-6 録音Audio Queue Bufferサイズの算出 void DeriveBufferSize ( AudioQueueRef audioQueue, // 1 AudioStreamBasicDescription &ASBDescription, // 2 Float64 seconds, // 3 UInt32 *outBufferSize // 4 ) { static const int maxBufferSize = 0x50000; // 5 int maxPacketSize = ASBDescription.mBytesPerPacket; // 6 if (maxPacketSize == 0) { // 7 UInt32 maxVBRPacketSize = sizeof(maxPacketSize); AudioQueueGetProperty ( audioQueue, kAudioQueueProperty_MaximumOutputPacketSize, // in Mac OS X v10.5, instead use // kAudioConverterPropertyMaximumOutputPacketSize &maxPacketSize, &maxVBRPacketSize ); } Float64 numBytesForTime = ASBDescription.mSampleRate * maxPacketSize * seconds; // 8 *outBufferSize = UInt32 (numBytesForTime < maxBufferSize ? numBytesForTime : maxBufferSize); // 9 } コードの働きを見てみましょう: - サイズを特定したいバッファを持つAudio Queue。 - Audio Queueの<ilcode>AudioStreamBasicDescription</ilcode>構造体。 - 音声の秒数を単位とした、必要とするAudio Queue Bufferの大きさ。 - 出力で、バイト数を単位としたAudio Aueue Bufferのサイズ。 - Audio Queue Bufferサイズの上限(バイト数)。この例では320KBに設定されている。これはサンプリング周波数96kHz/24ビット/ステレオでおよそ5秒に対応する。 - CBR音声データ用に、<ilcode>AudioStreamBasicDescription</ilcode>構造体からパケットサイズ(定数)を得る。この値を最大パケットサイズとして使う。 - この割り当ては、その音声データの録音がCBRかVBRかを特定する副作用をもたらす。VBRならば、Audio Queueの<ilcode>AudioStreamBasicDescription</ilcode>構造体のbytes-per-packetの値は0を示す。 - VBR音声データ用に、Audio Queueに見積もり最大パケットサイズを問い合わせる。 - バイト数でバッファサイズを計算する。 - 必要ならば、前述の上限値にバッファサイズを制限する。 ===== Audio File用マジッククッキーの設定 ===== MPEG-4 AACなどのいくつかの圧縮音声形式は、オーディオメタデータを含む構造を利用します。 これら構造をマジッククッキーと呼びます。 Audio Queue Serviceを使ってこのような形式で録音する際は、録音開始前にAudio Queueからマジッククッキーを取得し、それをAudio Fileに追加しなければなりません。 リスト2-7はAudio Queueからマジッククッキーを得る方法と、Audio Fileへの適用方法を示します。 Your code would call a function like this before recording, and then again after recording—some codecs update magic cookie data when recording has stopped. リスト 2-7 Audio File用マジッククッキーの設定 OSStatus SetMagicCookieForFile ( AudioQueueRef inQueue, // 1 AudioFileID inFile // 2 ) { OSStatus result = noErr; // 3 UInt32 cookieSize; // 4 if ( AudioQueueGetPropertySize ( // 5 inQueue, kAudioQueueProperty_MagicCookie, &cookieSize ) == noErr ) { char* magicCookie = (char *) malloc (cookieSize); // 6 if ( AudioQueueGetProperty ( // 7 inQueue, kAudioQueueProperty_MagicCookie, magicCookie, &cookieSize ) == noErr ) result = AudioFileSetProperty ( // 8 inFile, kAudioFilePropertyMagicCookieData, cookieSize, magicCookie ); free (magicCookie); // 9 } return result; // 10 } コードの働きを見てみましょう: - 録音に使うAudio Queue。 - 記録に使うAudio File。 - この関数の成否を表す返値変数。 - マジッククッキーのデータサイズを保持する変数。 - Audio Queueからマジッククッキーのデータサイズを取得し、<ilcode>cookieSize</ilcode>変数に格納します。 - マジッククッキー情報を保持するバイト列を確保します。 - Audio Queueの<ilcode>kAudioQueueProperty_MagicCookie</ilcode>プロパティを問い合わせてマジッククッキーを取得します。 - 記録するAudio Fileにマジッククッキーを設定します。<ilcode>AudioFileSetProperty</ilcode>関数は<ilcode>AudioFile.h</ilcode>ヘッダファイルで宣言されています。 - 一時クッキー変数のメモリを解放します。 - 関数の成否を返します。 ===== 録音用音声フォーマットの構成 ===== 本項ではAudio Queueの音声データ形式の構成方法を説明します。 Audio Queueはファイルへの記録にこのフォーマットを使用します。 音声データ形式の構成には、次の事柄を特定します: * 音声データ形式の種類(リニアPCM, AAC, その他など) * サンプリング周波数(44.1kHzなど) * 音声チャンネル数(ステレオには2など) * ビット深度(16ビットなど) * パケット毎のフレーム数(例えばリニアPCMでは1フレーム毎パケット) * 音声ファイルの種類(CAF, AIFF, その他など) * そのファイル種別が要求する音声データ形式の詳細 リスト2-8は、各属性を固定値とした録音用の音声形式の構成を示します。 製品コードでは、通常、音声形式の幾つかないし全ての項目をユーザーが設定できるようにすべきでしょう。 いずれのアプローチでも、目的は“状態を管理する独自構造体の定義”で解説した<ilcode>AQRecorderState</ilcode>独自構造体の<ilcode>mDataFormat</ilcode>のフィールドを埋めることです。 リスト 2-8 Audio Queueの音声データ形式の指定 AQRecorderState aqData; // 1 aqData.mDataFormat.mFormatID = kAudioFormatLinearPCM; // 2 aqData.mDataFormat.mSampleRate = 44100.0; // 3 aqData.mDataFormat.mChannelsPerFrame = 2; // 4 aqData.mDataFormat.mBitsPerChannel = 16; // 5 aqData.mDataFormat.mBytesPerPacket = // 6 aqData.mDataFormat.mBytesPerFrame = aqData.mDataFormat.mChannelsPerFrame * sizeof (SInt16); aqData.mDataFormat.mFramesPerPacket = 1; // 7 AudioFileTypeID fileType = kAudioFileAIFFType; // 8 aqData.mDataFormat.mFormatFlags = // 9 kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; コードの働きを見てみましょう: - <ilcode>AQRecorderState</ilcode>独自構造体の実体を生成します。構造体の<ilcode>mDataFormat</ilcode>フィールドは<ilcode>AudioStreamBasicDescription</ilcode>構造体を含みます。<ilcode>mDataFormat</ilcode>フィールドでセットされた値は、 - Creates an instance of the AQRecorderState custom structure. The structure’s mDataFormat field contains an AudioStreamBasicDescription structure. The values set in the mDataFormat field provide an initial definition of the audio format for the audio queue—which is also the audio format for the file you record into. In Listing 2-10, you obtain a more complete specification of the audio format, which Core Audio provides to you based on the format type and file type. - Defines the audio data format type as linear PCM. See Core Audio Data Types Reference for a complete listing of the available data formats. - Defines the sample rate as 44.1 kHz. - Defines the number of channels as 2. - Defines the bit depth per channel as 16. - Defines the number of bytes per packet, and the number of bytes per frame, to 4 (that is, 2 channels times 2 bytes per sample). - Defines the number of frames per packet as 1. - Defines the file type as AIFF. See the audio file types enumeration in the AudioFile.h header file for a complete listing of the available file types. You can specify any file type for which there is an installed codec, as described in “Using Codecs and Audio Data Formats.” - Sets the format flags needed for the specified file type. ===== 録音Audio Queueの生成 ===== Now, with the recording callback and audio data format set up, you create and configure an audio queue for recording. ==== 録音Audio Queueを生成する ==== Listing 2-9 illustrates how to create a recording audio queue. Notice that the AudioQueueNewInput function uses the callback, the custom structure, and the audio data format that were configured in previous steps. Listing 2-9 Creating a recording audio queue AudioQueueNewInput ( // 1 &aqData.mDataFormat, // 2 HandleInputBuffer, // 3 &aqData, // 4 NULL, // 5 kCFRunLoopCommonModes, // 6 0, // 7 &aqData.mQueue // 8 ); コードの働きを見てみましょう: - The AudioQueueNewInput function creates a new recording audio queue. - The audio data format to use for the recording. See “Set Up an Audio Format for Recording.” - The callback function to use with the recording audio queue. See “Write a Recording Audio Queue Callback.” - The custom data structure for the recording audio queue. See “Define a Custom Structure to Manage State.” - The run loop on which the callback will be invoked. Use NULL to specify default behavior, in which the callback will be invoked on a thread internal to the audio queue. This is typical use—it allows the audio queue to record while your application’s user interface thread waits for user input to stop the recording. - The run loop modes in which the callback can be invoked. Normally, use the kCFRunLoopCommonModes constant here. - Reserved. Must be 0. - On output, the newly allocated recording audio queue. ==== Audio Queueから完全な音声形式を取得する ==== When the audio queue came into existence (see “Creating a Recording Audio Queue”), it may have filled out the AudioStreamBasicDescription structure more completely than you have, particularly for compressed formats. To obtain the complete format description, call the AudioQueueGetProperty function as shown in Listing 2-10. You use the complete audio format when you create an audio file to record into (see “Create an Audio File”). Listing 2-10 Getting the audio format from an audio queue UInt32 dataFormatSize = sizeof (aqData.mDataFormat); // 1 AudioQueueGetProperty ( // 2 aqData.mQueue, // 3 kAudioQueueProperty_StreamDescription, // 4 // in Mac OS X, instead use // kAudioConverterCurrentInputStreamDescription &aqData.mDataFormat, // 5 &dataFormatSize // 6 ); コードの働きを見てみましょう: - Gets an expected property value size to use when querying the audio queue about its audio data format. - The AudioQueueGetProperty function obtains the value for a specified property in an audio queue. - The audio queue to obtain the audio data format from. - The property ID for obtaining the value of the audio queue’s data format. - On output, the full audio data format, in the form of an AudioStreamBasicDescription structure, obtained from the audio queue. - On input, the expected size of the AudioStreamBasicDescription structure. On output, the actual size. Your recording application does not need to make use of this value. ===== Audio Fileの生成 ===== With an audio queue created and configured, you create the audio file that you’ll record audio data into, as shown in Listing 2-11. The audio file uses the data format and file format specifications previously stored in the audio queue’s custom structure. Listing 2-11 Creating an audio file for recording CFURLRef audioFileURL = CFURLCreateFromFileSystemRepresentation ( // 1 NULL, // 2 (const UInt8 *) filePath, // 3 strlen (filePath), // 4 false // 5 ); AudioFileCreateWithURL ( // 6 audioFileURL, // 7 fileType, // 8 &aqData.mDataFormat, // 9 kAudioFileFlags_EraseFile, // 10 &aqData.mAudioFile // 11 ); コードの働きを見てみましょう: - The CFURLCreateFromFileSystemRepresentation function, declared in the CFURL.h header file, creates a CFURL object representing a file to record into. - Use NULL (or kCFAllocatorDefault) to use the current default memory allocator. - The file-system path you want to convert to a CFURL object. In production code, you would typically obtain a value for filePath from the user. - The number of bytes in the file-system path. - A value of false indicates that filePath represents a file, not a directory. - The AudioFileCreateWithURL function, from the AudioFile.h header file, creates a new audio file or initializes an existing file. - The URL at which to create the new audio file, or to initialize in the case of an existing file. The URL was derived from the CFURLCreateFromFileSystemRepresentation in step 1. - The file type for the new file. In the example code in this chapter, this was previously set to AIFF by way of the kAudioFileAIFFType file type constant. See “Set Up an Audio Format for Recording.” - The data format of the audio that will be recorded into the file, specified as an AudioStreamBasicDescription structure. In the example code for this chapter, this was also set in “Set Up an Audio Format for Recording.” - Erases the file, in the case that the file already exists. - On output, an audio file object (of type AudioFileID) representing the audio file to record into. ===== Audio Queue Bufferサイズの設定 ===== Before you prepare a set of audio queue buffers that you’ll use while recording, you make use of the DeriveBufferSize function you wrote earlier (see “Write a Function to Derive Recording Audio Queue Buffer Size”). You assign this size to the recording audio queue you are using. Listing 2-12 illustrates this: Listing 2-12 Setting an audio queue buffer size DeriveBufferSize ( // 1 aqData.mQueue, // 2 aqData.mDataFormat, // 3 0.5, // 4 &aqData.bufferByteSize // 5 ); コードの働きを見てみましょう: - The DeriveBufferSize function, described in “Write a Function to Derive Recording Audio Queue Buffer Size,” sets an appropriate audio queue buffer size. - The audio queue that you’re setting buffer size for. - The audio data format for the file you are recording. See “Set Up an Audio Format for Recording.” - The number of seconds of audio that each audio queue buffer should hold. One half second, as set here, is typically a good choice. - On output, the size for each audio queue buffer, in bytes. This value is placed in the custom structure for the audio queue. ===== Audio Queue Bufferセットの準備 ===== You now ask the audio queue that you’ve created (in “Create a Recording Audio Queue”) to prepare a set of audio queue buffers. Listing 2-13 demonstrates how to do this. Listing 2-13 Preparing a set of audio queue buffers for (int i = 0; i < kNumberBuffers; ++i) { // 1 AudioQueueAllocateBuffer ( // 2 aqData.mQueue, // 3 aqData.bufferByteSize, // 4 &aqData.mBuffers[i] // 5 ); AudioQueueEnqueueBuffer ( // 6 aqData.mQueue, // 7 aqData.mBuffers[i], // 8 0, // 9 NULL // 10 ); } コードの働きを見てみましょう: - Iterates to allocate and enqueue each audio queue buffer. - The AudioQueueAllocateBuffer function asks an audio queue to allocate an audio queue buffer. - The audio queue that performs the allocation and that will own the buffer. - The size, in bytes, for the new audio queue buffer being allocated. See “Write a Function to Derive Recording Audio Queue Buffer Size.” - On output, the newly allocated audio queue buffer. The pointer to the buffer is placed in the custom structure you’re using with the audio queue. - The AudioQueueEnqueueBuffer function adds an audio queue buffer to the end of a buffer queue. - The audio queue whose buffer queue you are adding the buffer to. - The audio queue buffer you are enqueuing. - This parameter is unused when enqueuing a buffer for recording. - This parameter is unused when enqueuing a buffer for recording. ===== 録音 ===== リスト2-14で示されるように、これまでのコードの全てが録音のとてもシンプルな工程に繋がりました。 リスト 2-14 録音 aqData.mCurrentPacket = 0; // 1 aqData.mIsRunning = true; // 2 AudioQueueStart ( // 3 aqData.mQueue, // 4 NULL // 5 ); // ユーザーインターフェーススレッドにおいてユーザーが録音を止めるまで待つ AudioQueueStop ( // 6 aqData.mQueue, // 7 true // 8 ); aqData.mIsRunning = false; // 9 コードの働きを見てみましょう: - Audio Fileの先頭から記録するためにパケットインデックスを<ilcode>0</ilcode>に初期化します。 - Audio Queueが実行中を表すフラグを独自構造体にセットします。このフラグは録音Audio Queueコールバックで使用されます。 - <ilcode>AudioQueueStart</ilcode>関数は、Audio Queue自身のスレッドでAudio Queueを開始します。 - 開始するAudio Queue。 - <ilcode>NULL</ilcode>を使うと、Audio Queueが直ちに録音を開始する事を示します。 - <ilcode>AudioQueueStop</ilcode>関数は録音Audio Queueを停止しリセットします。 - 停止するAudio Queue。 - <ilcode>true</ilcode>を使うと、同期的に止めます。停止における同期と非同期の説明は“Audio Queueの状態と制御”をご覧ください。 - Audio Queueが非実行中を示すフラグを独自構造体にセットします。 ===== 録音後の後始末 ===== 録音が終わったら、Audio Queueを破棄しAudio Fileを閉じます。 リスト 2-15はこれらの手順を示します。 リスト 2-15 録音後の後始末 AudioQueueDispose ( // 1 aqData.mQueue, // 2 true // 3 ); AudioFileClose (aqData.mAudioFile); // 4 コードの働きを見てみましょう: - <ilcode>AudioQueueDispose</ilcode>関数はAudio Queueと、バッファを含むその全ての資源を破棄します。 - 破棄したいAudio Queue。 - <ilcode>true</ilcode>を使うとAudio Queueを同期的に(すなわち、即座に)破棄します - 記録に使ったAudio Fileを閉じます。<ilcode>AudioFileClose</ilcode>関数は<ilcode>AudioFile.h</ilcode>ヘッダファイルで宣言されています。 translation/adc/audio/audio_queue_services_programming_guide/0300_recordingaudio.1409571471.txt.gz 最終更新: 2014-09-01 20:37by Decomo