翻訳元:[[https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/AboutAudioQueues/AboutAudioQueues.html|Audio Queue Services Programming Guide: About Audio Queues]] ====== Audio Queueについて ====== 本章では、Mac OS XにおけるAudio Queueの能力、アーキテクチャ、そして内部の仕組みを学びます。 Audio Queueサービスが録音や再生に使用する、Audio Queue、Audio Queue Buffer、そしてコールバック関数を紹介します。 また、Audio Queueのステータスやパラメータについても見ていきます。 本章を終える頃には、あなたはこの技術を効果的に使うために必要となる概念を、理解していることでしょう。 ===== Audio Queueとは? ===== **Audio Queue**は、Mac OS Xで音声の記録、再生を行うために使用するソフトウェアオブジェクトです。 AudioQueueRefという不透明型で表され、AudioQueue.hヘッダファイルで宣言されています。 Audio Queueは以下の働きをします: * 音声装置との接続 * メモリ管理 * 必要に応じて、音声圧縮形式に見合ったコーデックの使用 * 録音や再生の調停(mediating) Audio Queueは他のCore Audioインタフェースと一緒に利用することが出来、比較的少ないコード量でアプリケーションに完全なデジタル音声の記録、再生策を構築します。 ==== Audio Queueのアーキテクチャ ==== 全てのAudio Queueは、以下の構成要素から成る同じ一般的な構造を持ちます: * 少数の音声データの一時的な保管場所となる、一組の**Audio Queue Buffer**(a set of audio queue buffers) * Audio Queue Bufferの規則正しい列である**Audio Buffer Queue** * あなたが記述する**Audio Queueコールバック**関数 アーキテクチャは、Audio Queueの用途が録音なのか再生なのかによって変わります。 その違いは、Audio Queueが自身の入出力を接続方法と、コールバック関数の役割にあります。 === 録音用のAudio Queue === 録音用途のAudio QueueはAudioQueueNewInput関数で生成され、図1-1で示す構造を持ちます。 **図1-1** 録音用Audio Queue \\ {{recording_architecture.jpg|}} 録音用Audio Queueの入力側は通常、マイクといった外部の音声ハードウェアと接続されます。 標準の状態では(in the default case)、音声はユーザーがシステム環境設定で設定した、システムのデフォルト音声入力装置から入ってきます。 録音用Audio Queueの出力側は、あなたが記述するコールバック関数を利用します。 ディスクに記録する時は、バッファがAudio Queueから受信した新しい音声データを、コールバックが音声ファイルへと記録します。 しかし、録音用Audio Queueの用途はファイルへの書き込みだけに留まりません。 例えばもう1つの使い方として、リアルタイム音声解析にも利用できます。 このような場合、コールバックは音声データを直接アプリケーションに提供すればよいでしょう。 [[#録音用Audio Queueのコールバック関数|“録音用Audio Queueのコールバック関数”]] で、このコールバックについてより詳しく学びます。 全てのAudio Queueは、録音であろうが再生であろうが、1つないしそれ以上のAudio Queue Bufferを持ちます。 これらバッファは、Buffer Queueと呼ばれる特定の配列の中に配置されます。 図中、Audio Queue Bufferは(データで)埋められた順に番号付けがなされます。これは、バッファがコールバックに渡された順番と一致します。 [[#Buffer Queueとエンキュー|“Buffer Queueとエンキュー”]]で、Audio Queueがそのバッファを扱う方法について学びます。 === 再生用Audio Queue === 再生用途のAudio Queue(AudioQueueNewOutput関数で生成されます)は、図1-2に示す構造を持ちます。 **図1-2** 再生用Audio Queue \\ {{playback_architecture.jpg| }} 再生用Audio Queueでは、コールバックは入力側にあります。 そのコールバックは、ディスク(または他のソース)から音声データの取得と、Audio Queueへのデータ引き渡しの責任を負います。 また、再生コールバックは再生するデータが無くなった際、Audio Queueに停止指示を伝えます。 [[#再生用Audio Queueのコールバック関数|“再生用Audio Queueのコールバック関数”]] で、このコールバックについてより詳しく学びます。 再生用Audio Queueの出力は通常、スピーカといった外部音声ハードウェアに接続されます。 標準の状態では(in the default case)、音声はユーザーがシステム環境設定で設定した、システムのデフォルト音声出力装置から出力されます。 ==== Audio Queue Buffer ==== **Audio Queue Buffer**は、AudioQueue.hヘッダファイルで宣言されている、AudioQueueBufferRef型のデータ構造です: typedef struct AudioQueueBuffer { const UInt32 mAudioDataBytesCapacity; void *const mAudioData; UInt32 mAudioDataByteSize; void *mUserData; } AudioQueueBuffer; typedef AudioQueueBuffer *AudioQueueBufferRef; 上記リスト中で強調表記されている(訳註:本Wikiの仕様上、ここでは強調表記されていません)mAudioData領域はバッファを指していますが、本質的には、録音や再生に使用される音声データの一時的な塊を格納する、メモリ区画です。 (構造体の)他のメンバが持つ情報は、Audio Queueがバッファを管理するのに使用されます。 Audio QueueはAudio Queue Bufferをいくつでも持つことが出来ます−つまり、アプリケーションで幾つ必要かを決めます。 通常、この個数は3個です。 これにより、バッファの1つがディスクへの書き出しで使用される一方で、2つめのバッファで新しい音声データの受け取りを可能にします。 残りの3つ目のバッファは、ディスク入出力の遅延等を吸収する目的で、必要となれば利用されます。 図1-3は、その様子を示しています。 Audio Queueは、これらバッファの全てのメモリ管理を行います。 この仕掛け(helps)は、開発者がアプリケーションに録再機能を追加する労力を低減(improve)します。 またこれは、資源利用の最適化も図ります。 AudioQueueBufferデータ構造の完全な解説は、[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/index.html|Audio Queue Services Reference]]をご覧下さい。 ==== Buffer Queueとエンキュー ==== The buffer queue is what gives audio queues, and indeed Audio Queue Services, their names. [[#Audio Queueのアーキテクチャ|“Audio Queueのアーキテクチャ”]]では、Buffer Queue−順番に並んだバッファ列-を見て来ました。 それでは、録音、再生におけるBuffer Queueの管理のし方について学びましょう。 特に、Audio Queue BufferをBuffer Queueに追加する、エンキューについて学習します。 実装するものが録音か再生かに因らず、エンキューはコールバックがしなければならない仕事です。 === 録音プロセス === 録音の場合、Audio Queue Bufferの1つは、マイクなどの入力装置から得られる音声データで埋められます。 Buffer Queue中の残りのバッファは、現在使用中のバッファの後ろに並べられ、音声データで埋められる順番を待ちます。 Audio Queueは得られたバッファ順に、バッファを音声データで満たし、コールバックに渡します。 図1-3はAudio Queueを用いた録音作業の様子を示しています。 **図1-3** 録音プロセス \\ {{recording_callback_function.jpg| }} 図1-3の手順1で、録音を開始します。 Audio Queueは得た音声データでバッファを埋めます。 手順2において、最初のバッファは既に埋められています。 Audio Queueはコールバックを呼び出し、コールバックに満タンのバッファ(buffer 1)を渡します。 手順3で、コールバックはそのバッファの中身を音声ファイルへ書き出します。 時を同じくして、Audio Queueは別のバッファ(buffer 2)を新しく得られたデータで埋めます。 手順4で、コールバックは書き出しが終わったバッファ(buffer 1)を、キューの最後に加え(enqueue)、そして再度データで埋められる状態にします。 手順5で、Audio Queueは再びコールバックを呼び、満タンとなった次のバッファ(buffer 2)を渡します。 手順6で、コールバックはこのバッファの中身を音声ファイルに書き出します。 この定常データ取得状態(looping steady state)は、ユーザーが録音を停止するまで続けられます。 === 再生プロセス === 再生の場合、Audio Bufferの1つが、スピーカなどの出力装置に送られます。 Buffer Queue中の残りのバッファは、現在使用中のバッファの後ろに並べられ、再生される番を待ちます。 Audio Queueは再生される順番に、音声データを入れるバッファをコールバックに渡します。 コールバックは新しい音声データを読み込みこんでバッファへと格納し、それからバッファをキューの最後尾へと追加します(enqueue)。 図1-4はAudio Queueを用いた再生作業の方法を示しています。 **図1-4** 再生プロセス \\ {{playback_callback_function.jpg| }} 図1-4の手順1で、アプリケーションは再生用Audio Queueの準備をします。 アプリケーションは、個々のAudio Queue Bufferのために1度コールバックを呼び出し、それらを音声データで満たしBuffer Queueへと追加します。 このデータ充填作業は、アプリケーションがAudioQueueStart関数を呼んだ際(手順2)、再生が直ぐに始まる事を保証します。 手順3で、Audio Queueは最初のバッファ(buffer 1)を出力に送ります。 最初のバッファが再生されると直ちに、再生用Audio Queueは定常データ取得状態(looping steady state)へと移行します。 Audio Queueは次のバッファ(buffer2)の再生を開始し(手順4)、コールバックを呼び(手順5)、先ほど再生されたバッファ(buffer 1)を渡します。 手順6で、コールバックはそのバッファを音声ファイルからのデータで埋め、再生に向けバッファをキューに追加します。 === 再生プロセスの制御 === Audio Queue Bufferは必ず、キューに追加された順番で再生されます。 しかし、Audio Queue ServiceはAudioQueueEnqueueBufferWithParameters関数で、この再生過程の制御を可能としています。 この関数で出来る事は以下の通りです: * バッファを再生する正確な時間の設定。これにより同期に対応します。 * Audio Queue Bufferの開始・終了フレームの調整(trim)。これにより先頭や終端の無音部分を除去できます。 * バッファ単位による再生利得の設定(Set the playback gain at the granularity of a buffer.) 再生利得に関するより詳しい情報は、[[#Audio Queueのパラメータ|“Audio Queueのパラメータ”]]をご覧下さい。 AudioQueueEnqueueBufferWithParameters関数の完全な解説については、[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/index.html|Audio Queue Services Reference]]をご覧下さい。 ==== Audio Queueコールバック関数 ==== 典型的に、Audio Queue Serviceを利用したプログラミング作業の大部分が、Audio Queueコールバック関数の記述に費やされます。 録音中や再生中は、Audio QueueコールバックはAudio Queueによって繰り返し呼び出されます。 呼び出し間隔(the time between calls)は、Audio Queueのバッファ容量に依存し、通常、0.5秒〜3、4秒(several seconds)程度の範囲になります。 Audio Queueコールバックの責任の1つは、それが録音か再生かに拘らず、Buffer QueueへAudio Queue Bufferを返す事です。 コールバックは、AudioQueueEnqueueBuffer関数を用いて、バッファをBuffer Queueの最後へ加えます。 再生の場合は、必要とあればその代わりに、[[#再生過程の制御|“再生過程の制御”]]で解説したAudioQueueEnqueueBufferWithParameters関数を使う事ができます。 === 録音用Audio Queueのコールバック関数 === 本項は、あなたが記述するであろう、ディスク上のファイルへ録音するという一般的なコールバックを紹介します。 以下はAudioQueue.hヘッダファイルで宣言されている、録音用Audio Queueコールバックのプロトタイプです: AudioQueueInputCallback ( void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime; UInt32 inNumberPacketDescriptions, const AudioStreamPacketDescription *inPacketDescs ); コールバック呼び出しにおいて、録音用Audio Queueは、コールバックが前に続く次の音声データ集合を音声ファイルに書き出すために必要となる、全ての情報を提供します: * //inUserData// は通常、Audio Queueとそのバッファ用のステータス情報、データ書き込み先のファイルを表すAudio Fileオブジェクト(AudioFileID型)、そしてそのファイルの音声データ形式を含む、あなたの設定した独自の構造体です。 * //inAQ// は、コールバックを呼び出したAudio Queueです。 * //inBuffer// は、Audio Queueによって新しく埋められたAudio Queue Bufferで、コールバックがディスクに書き出すために必要となる新しいデータが含まれています。このデータは、(//inUserData//引数で渡される)独自構造体に含まれる、あなたが指定した音声データ形式情報に合わせて、既に形式が整えられています。より詳しい情報については、[[#コーデックと音声データ形式を使う|“コーデックと音声データ形式を使う”]]をご覧下さい。 * //inStartTime// は、バッファの最初のサンプルのサンプル時間です。基本的な録音では、このパラメータを使う必要はないでしょう。 * //inNumberPacketDescriptions// は、//inPacketDescs//引数で記述されるパケットの番号です。VBR(可変ビットレート)形式で記録する場合、Audio Queueがこのパラメータをコールバックに提供します。そして、これを順番にAudioFileWritePackets関数に渡します。CBR(固定ビットレート)形式では、パケット記述子は使いません。CBR記録の場合、Audio Queueは本引数と//inPacketDescs//引数をNULLにします。 * //inPacketDescs// は、バッファ中のサンプルと合致するパケット記述子が設定されます。繰り返しになりますが、音声データがVBR形式の場合、Audio Queueはこのパラメータに値を提供するので、コールバックはこれをAudioFileWritePackets関数(Audiofile.hヘッダで宣言)に渡します。 録音コールバックのより詳しい情報については、本資料の[[音声の記録|“音声の記録”]]をご覧下さい。また、合わせて[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/index.html|Audio Queue Services Reference]]もご覧下さい。 === 再生用Audio Queueのコールバック関数 === 本項は、あなたが記述するであろう、ディスク上のファイルから音声を再生するという一般的なコールバックを紹介します。 以下はAudioQueue.hヘッダファイルで宣言されている、再生用Audio Queueコールバックのプロトタイプです: AudioQueueOutputCallback ( void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer ); コールバック呼び出しにおいて、再生用Audio Queueは、コールバックが次の音声データ集合を音声ファイルから読み出すために必要となる、全ての情報を提供します: * //inUserData// は通常、Audio Queueとそのバッファ用のステータス情報、データ読み込み元のファイルを表すAudio Fileオブジェクト(AudioFileID型)、そしてそのファイルの音声データ形式を含む、あなたの設定した独自の構造体です。再生用Audio Queueでは、コールバックはこの構造体中に要素を設けて、現在のパケット番号(packet index)を保持しなければなりません。 * //inAQ// は、コールバックを呼び出したAudio Queueです。 * //inBuffer// は、Audio Queueによって生成されたAudio Queue Bufferで、コールバックが再生中のファイルから次のデータ集合を読み、そのデータを格納するために使用されます。 アプリケーションがVBRのデータを再生する場合、コールバックは読み込んだ音声データのパケット情報を必要とします。 これにはAudioFile.hヘッダファイルで宣言されている、AudioFileReadPackets関数を呼びます。 それから、再生用Audio Queueがパケット情報を利用できるように、それを独自データ構造体の中に設置します。 再生用コールバックのより詳しい情報は、本資料の[[音声の再生|“音声の再生”]]をご覧下さい。また、併せて // [[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/index.html|Audio Queue Services Reference]] // もご覧下さい。 ===== コーデックと音声データ形式を使う ===== Audio Queue Serviceは、必要とあらば音声形式の変換にコーデック(音声データの符号化/復号を行うコンポーネント)を使用します。 録音、再生アプリケーションはインストールされているコーデックの、全ての音声形式を使う事が出来ます。 様々な音声形式を扱うために、独自のコードを記述する必要はありません。 具体的に言うと、コールバックはデータ形式について知る必要がありません。 コーデックが作用する様子を見ていきましょう。 各々のAudio Queueは、AudioStreamBasicDescription構造体で表現される、音声データ形式を持ちます。 あなたが−構造体のmFormatIDフィールドで−形式を指定すると、Audio Queueは適切なコーデックを使用します。 更にまた、標本化周波数やチャンネル数を指定すると、同様に反映されます。 [[音声の記録|“音声の記録”]]や[[音声の再生|“音声の再生”]]で、音声データ形式の設定例を見る事ができます。 録音用Audio Queueは、図1-5に示すようにインストール済みのコーデックを使用します。 **図1-5** 録音中の音声形式の変換 \\ {{recording_codec.jpg| }} 図1-5の手順1で、アプリケーションはAudio Queueに録音の開始を伝え、そしてまた、使用するデータ形式も伝えます。 手順2で、Audio Queueは新しい音声データを取得し、あまたが指定した形式に基づくコーデックを使い、データを変換します。 それからAudio Queueはコールバックを呼び、変換済み音声データを含むバッファを渡します。 手順3で、コールバックは変換済み音声データをディスクへ書き出します。 もう一度言いますが、コールバックはデータ形式について知っている必要はないのです。 再生用Audio Queueは、図1-6に示すようにインストール済みのコーデックを使用します。 **図1-6** 再生中の音声形式の変換 \\ {{playback_codec.jpg| }} 図1-6の手順1は、アプリケーションがAudio Queueに再生の開始を伝え、そしてまた、再生する音声ファイルが持つでデータ形式も伝えます。 手順2で、Audio Queueがコールバックを呼び出し、音声ファイルからデータを読み込みます。 コールバックはそのデータを、読み込んだままの形式でAudio Queueに渡します。 手順3で、Audio Queueは適切なコーデックを使用し、音声を出力先へと送ります。 Audio Queueは、Mac OS Xが最初から対応しているものだろうが、サードパーティが提供したものだろうが、インストール済みの全コーデックを使う事が出来ます。 使用するコーデックを指定するには、Audio QueueのAudioStreamBasicDescription構造体に、4文字から成るコーデックIDを設定します。 この設定例は[[音声の記録|“音声の記録”]]で見る事が出来ます。 Mac OS Xは、CoreAudioTypes.hヘッダファイルで宣言され、//[[http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/index.html|Core Audio Data Types Reference]]//で明文化されている、形式ID列挙子一覧からわかるように、広範囲に渡る音声コーデックを持ちます。 あなたは、Audio ToolboxフレームワークのAudioFormat.hヘッダファイルに含まれるインタフェースを用いて、システムで利用可能なコーデックの中から決定することができます。 Fiendishthngsアプリケーションを使って、システムの持つコーデックを表示することが出来ます。このサンプルコードは[[http://developer.apple.com/samplecode/Fiendishthngs/]]にあります。 ===== Audio Queueの状態と制御 ===== Audio Queueの一生は、生成(creation)で始まり開放(disposal)で終わります。 アプリケーションはこのライフサイクルの管理と、Audio Queueの状態の制御をAudioQueue.hヘッダファイルで宣言される、6つの関数で行います: * **開始**([[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueStart|AudioQueueStart]])- 録音/再生の初期化のために呼びます。 * **準備**([[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueuePrime|AudioQueuePrime]])- 再生において、Audio Queueが再生に必要なデータを直ぐに利用できる事を保証するために、[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueStart|AudioQueueStart]]を呼ぶ前に呼びます。この関数は録音には関係ありません。 * **停止**([[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueStop|AudioQueueStop]])- Audio Queueのリセット(後述の[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueReset|AudioQueueReset]]の解説をご覧下さい)と、録音/再生を停止するために呼びます。再生用Audio Queueのコールバックは、再生するデータが無くなった時に本関数を呼び出さなければなりません。 * **一時停止**([[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueuePause|AudioQueuePause]])- バッファに影響を与えたり、Audio Queueをリセットする事なく録音/再生を一時停止するために呼びます。再開するには[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueStart|AudioQueueStart]]関数を呼びます。 * **更新**([[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueFlush|AudioQueueFlush]])- 最後のAudio Queue Bufferのエンキューが終わった後で、全てのバッファ済みデータと処理中の全音声データが、確実に録音/再生されるように呼び出します。 * **リセット**([[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueReset|AudioQueueReset]])- 前もって決められていた使用予定(previously scheduled use)から全てのバッファを削除し、直ちにAudio Queueを停止する(silence)と共に、全デコーダとDSPの状態をリセットするために呼びます。 [[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueStop|AudioQueueStop]])は、同期モードと非同期モードで使う事ができます: * **同期**停止は、バッファリング中の音声データ(の有無)に関係なく、直ちに停止します。 * **非同期**停止は、キューにあるバッファの再生/録音の完了後に停止します。 Audio Queueの同期/非同期停止の詳しい情報も含め、これら関数の完全な解説は//[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/index.html|Audio Queue Services Reference]]//をご覧下さい。 ===== Audio Queueのパラメータ ===== Audio Queueは**パラメータ**と呼ばれる、変更可能な設定を持ちます。 それぞれのパラメータは、キーとなる列挙定数と、値となる浮動小数点値を持ちます。 通常、パラメータは再生で使用され、録音では使用されません。 Mac OS X v10.5で、唯一使用可能なAudio Queueパラメータは、利得(gain)です。 このパラメータの値の設定や取得は、kAudioQueueParam_Volume定数を使い、0.0の無音から1.0の単位利得(unity gain)までの値が利用できます。 アプリケーションがAudio Queueパラメータを設定するには、2つの方法があります: * [[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueSetParameter|AudioQueueSetParameter]]関数を用いてAudio Queue単位で設定する。これによる設定の変更はAudio Queueに対して直接行われます。この変更は直ぐに反映されます。 * [[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueEnqueueBufferWithParameters|AudioQueueEnqueueBufferWithParameters]]関数を用いて、Audio Queue Buffer単位で設定する。 #未訳:This lets you assign audio queue settings that are, in effect, carried by an audio queue buffer as you enqueue it. この変更はAudio Queue Bufferが再生を開始したときに反映されます。 どちらの場合も、Audio Queueのパラメータ設定は、それらを変更するまで持続(remain)します。 [[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/c_ref/AudioQueueGetParameter|AudioQueueGetParameter]]関数で、いつでもAudio Queueの現在のパラメータ値にアクセスできます。 パラメータ値の設定/取得に関係する関数の完全な解説は、//[[http://developer.apple.com/documentation/MusicAudio/Reference/AudioQueueReference/index.html|Audio Queue Services Reference]]//をご覧下さい。