翻訳元:[[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]]//をご覧下さい。