ALSA:PCM

PCM
snd_pcm_openPCM を開く
snd_pcm_open_lconfローカル設定で PCM を開く
snd_pcm_open_fallbackフォールバック PCM を開く
snd_pcm_closePCM を閉じる
snd_pcm_nonblock非ブロックモードの設定
取得
snd_pcm_namePCM 定義名を返す
snd_pcm_typePCM タイプを返す
snd_pcm_streamストリームタイプを返す
文字列
snd_pcm_type_namePCM タイプの名前を取得
snd_pcm_stream_nameストリームタイプの名前を取得
poll
snd_pcm_poll_descriptors_count必要な pollfd の数を返す
snd_pcm_poll_descriptorspollfd の情報をセットする
snd_pcm_poll_descriptors_reventspoll 後のイベントを取得
非同期ハンドラ
snd_async_add_pcm_handlerPCMの非同期ハンドラを追加
snd_async_handler_get_pcm非同期ハンドラから snd_pcm_t を取得
構成
snd_pcm_set_paramsハードウェア構成を簡単に設定
snd_pcm_get_paramsピリオドとバッファサイズを取得
実行
snd_pcm_preparePCM を使用するために準備する
snd_pcm_resetPCM 位置をリセット
snd_pcm_startPCM を開始する
snd_pcm_dropPCM を停止 (即時)
snd_pcm_drainPCM を停止 (保持)
snd_pcm_pausePCM を一時停止/再開
snd_pcm_recoverエラーまたはサスペンドから回復
snd_pcm_resumeサスペンドから正常に再開
snd_pcm_rewindアプリケーションフレームの位置を後方に移動
snd_pcm_forwardアプリケーションフレームの位置を前方に移動
snd_pcm_waitイベントが起こるまで待つ
snd_pcm_hwsyncストリームの位置をハードウェアと同期する [非推奨]
実行情報
snd_pcm_htimestampタイムスタンプを取得
snd_pcm_avail読み書きの準備ができているフレームの数を返す (同期あり)
snd_pcm_avail_update読み書きの準備ができているフレームの数を返す (同期なし)
snd_pcm_delayレイテンシを返す
snd_pcm_avail_delaysnd_pcm_avail と snd_pcm_delay
snd_pcm_rewindable巻き戻すことができる安全なフレーム数を取得
snd_pcm_forwardable前進できる安全なフレーム数を取得
リンク
snd_pcm_link2つのPCMをリンク
snd_pcm_unlinkリンクグループから除外
PCM
int snd_pcm_open(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);
PCM を開く
pcmp
PCM ハンドラが返る
name
PCM ハンドラの定義名
stream
ストリームタイプ。
SND_PCM_STREAM_PLAYBACK: 再生
SND_PCM_STREAM_CAPTURE: 録音
mode
開くモード
SND_PCM_NONBLOCK: 非ブロッキング
SND_PCM_ASYNC: 非同期通知
戻り値
0 で成功、負でエラーコード
int snd_pcm_open_lconf(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode, snd_config_t *lconf);
ローカル設定で PCM を開く
戻り値
0 で成功、負でエラーコード
int snd_pcm_open_fallback(snd_pcm_t **pcm, snd_config_t *root, const char *name, const char *orig_name, snd_pcm_stream_t stream, int mode);
フォールバック PCM を開く
戻り値
0 で成功、負でエラーコード
int snd_pcm_close(snd_pcm_t *pcm);
PCM を閉じる
戻り値
0 で成功、負でエラーコード
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
非ブロックモードの設定。
nonblock
0 = ブロックモード
1 = 非ブロックモード
2 = abort
戻り値
0 で成功、負でエラーコード
取得
const char *snd_pcm_name(snd_pcm_t *pcm);
PCM 定義名を返す
snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
PCM タイプを返す
snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm);
ストリームタイプを返す
文字列
const char *snd_pcm_type_name(snd_pcm_type_t type);
PCM タイプの名前を取得
const char *snd_pcm_stream_name(const snd_pcm_stream_t stream);
ストリームタイプの名前を取得
poll
int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm);
必要な pollfd の数を返す
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
poll() を使用するために、pollfd 構造体に情報をセットする。

なお、pollfd 構造体の値は、ストリームの方向に反している可能性がある。
POLLIN は読み込み方向を意味しない可能性があり、POLLOUT は書き込みを意味しない可能性があるが、snd_pcm_poll_descriptors_revents() 関数は、それを正しく修正する。

セットされた情報を、select() で使用することもできる。
POLLIN および POLLOUT イベントを、対応する FD_SET 配列に変換する。
snd_pcm_poll_descriptors_revents() を使用して、イベントを正しく修正すること。
space
配列の個数
戻り値
実際にセットされた個数
int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
poll() から返された revents を修正して、POLLIN = 読み込み可、POLLOUT = 書き込み可のイベントを返す。

この関数は、空のイベントセットを返す可能性があるため、その場合は、次のイベント待ちを行う必要がある。
nfds
pollfd 配列の個数
revents
修正された revents の値が返る。
※この関数は、常に1つのイベントのみを返す。
戻り値
0 で成功、負でエラーコード
非同期ハンドラ
int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, snd_async_callback_t callback, void *private_data);
PCMの非同期ハンドラを追加。
ピリオドの境界が経過すると、非同期コールバックが呼び出される。
戻り値
0 で成功、負でエラーコード
snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler);
非同期ハンドラから snd_pcm_t を取得
構成
int snd_pcm_set_params(snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels,
    unsigned int rate, int soft_resample, unsigned int latency);
指定した値のみで、ハードウェア構成を簡単に設定する。
rate
サンプリングレート
soft_resample
0 = リサンプリングを禁止、1 = リサンプリングを許可
latency
マイクロ秒単位のレイテンシ (バッファの長さの目安)
戻り値
0 で成功。負の値でエラーコード
int snd_pcm_get_params(snd_pcm_t *pcm, snd_pcm_uframes_t *buffer_size, snd_pcm_uframes_t *period_size);
ハードウェア構成を使わずに、ピリオドサイズとバッファサイズを取得する。
buffer_size
バッファのフレーム数
period_size
ピリオドのフレーム数
戻り値
0 で成功。負の値でエラーコード
実行
int snd_pcm_prepare(snd_pcm_t *pcm);
PCM を使用するために準備する。

snd_pcm_hw_params() でハードウェア構成をインストールした場合、すでに実行されている。
PCM が停止すると SETUP 状態になるため、再度開始する場合は、この関数を実行する必要がある。
戻り値
0 で成功、負でエラーコード。
int snd_pcm_reset(snd_pcm_t *pcm);
delay を 0 に減らして、位置をリセットする。
戻り値
0 で成功、負でエラーコード。
int snd_pcm_start(snd_pcm_t *pcm);
PCM を開始して、再生/録音を開始する。

デフォルトでは、一定サイズのデータがバッファにあれば、自動的に開始されるようになっているので、この関数を実行しなくても開始される。
戻り値
0 で成功、負でエラーコード。
int snd_pcm_drop(snd_pcm_t *pcm);
PCM を停止し、保留中のフレームを破棄する。

PCM を即時に停止し、バッファ上の保留中のサンプルは無視する。
すべての保留中のサンプルを処理するには、snd_pcm_drain() を使う。

停止した場合は、PCM が SETUP 状態になる。
戻り値
0 で成功、負でエラーコード。
int snd_pcm_drain(snd_pcm_t *pcm);
保留中のフレームを保持して、PCM を停止する。

再生の場合、すべての保留中のフレームが再生されるまで待ってから、PCM を停止する。
録音の場合、現在までに残っているフレームの取得が許可される。
※非ブロッキングモードの場合、関数はブロックされない。

PCM をすぐに停止するには、snd_pcm_drop() を使う。
戻り値
0 で成功、負でエラーコード。
-EAGAIN: バッファがまだ残っている。
-ESTRPIPE: サスペンドイベントが発生した。
int snd_pcm_pause(snd_pcm_t *pcm, int enable);
PCM を一時停止、または再開させる。

※一時停止機能をサポートするハードウェアでのみ動作する。
snd_pcm_hw_params_can_pause() 関数で確認できる。
enable
0 = 再開、1 = 一時停止
int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent);
エラーまたはサスペンド状態から回復させる。

この関数は、以下のエラーを回復し、次の読み書きができるように準備する。

  • -EINTR: システムコールで中断。
    実際は何もせずに 0 を返すだけ。
  • -EPIPE: オーバーランまたはアンダーラン。
    エラー出力の上、snd_pcm_prepare() を実行する。
  • -ESTRPIPE: サスペンド状態。
    内部で snd_pcm_resume() が行われている。
err
エラー番号
silent
0 の場合、stderr にエラーが出力される。0 以外で出力しない。
戻り値
エラーコードが正常に処理された場合は 0。そうでない場合は負のエラーコード。
この関数内で処理されないエラーの場合、元のエラーコードを返す (-EAGAIN など)。
int snd_pcm_resume(snd_pcm_t *pcm);
ストリームがサスペンド状態にあるとき、正常に再開するために使用できる。
※すべてのハードウェアがこの機能をサポートしているわけではない。

読み書きなどで -ESTRPIPE が返った場合、snd_pcm_resume() を実行する。
0 が返った場合は、すでに再開しているので、そのまま読み書きを続ける。
-EAGAIN が返った場合は、少し待つなどした後、resume を続けて実行する。
その他のエラーの場合は、snd_pcm_prepare() を呼び出す必要がある。
戻り値
0 で成功。負の値でエラーコード。
-EAGAIN: 再開をすぐに続行できない (ハードウェアがまだ中断されている可能性がある)
-ENOSYS: ハードウェアはこの機能をサポートしていない
snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
アプリケーションフレームの位置を後方に移動
frames
移動するフレーム数
戻り値
実際の変位を示す値。それ以外の場合は、負のエラーコード
snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
アプリケーションフレームの位置を前方に移動
frames
スキップするフレーム数
戻り値
正の値で、実際にスキップした数。それ以外の場合は、負のエラーコード。
0 で何も起こらなかった。
int snd_pcm_wait(snd_pcm_t *pcm, int timeout);
poll() を使って、読み書きが可能になったなどのイベントが起こるまで待つ。
timeout
最大待機時間 (ミリ秒)。

SND_PCM_WAIT_INFINITE (-1) : 無限。
SND_PCM_WAIT_IO (-10001) : 読み書きが可能になるまで。
SND_PCM_WAIT_DRAIN (-10002) : drain が終わるまで。
戻り値
成功した場合は正の値。それ以外の場合は、負のエラーコード。

0: タイムアウトが発生した。
1: I/O の準備ができている。
-EPIPE : xrun
-ESTRPIPE : サスペンド状態
その他の負の値は、一般エラー。
int snd_pcm_hwsync(snd_pcm_t *pcm);
ストリームの位置をハードウェアと同期する [非推奨]。

この関数は、アプリケーションの実際の r/w ポインタを更新しない。
関数 snd_pcm_avail_update() は、mmap begin+commit 操作の前に呼び出す必要がある。
戻り値
0 で成功、負でエラーコード。
実行情報
int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
最終更新位置の、高解像度タイムスタンプを取得する。
この関数は、アプリケーションの実際の読み込み/書き込みポインタを更新しない。
avail
タイムスタンプが取得されたときに使用可能なフレームの数が返る
tstamp
タイムスタンプが返る
戻り値
0 で成功、負の値でエラーコード
snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm);
バッファ内で読み書きの準備ができているフレームの数を返す。

録音では、下層のレイヤ全体で、すべての準備完了フレームをアプリケーションレベルに転送するために必要なすべてのアクションが実行される。
この関数では、位置は、サウンドリングバッファ内のハードウェア (ドライバ) の位置と同期される。
戻り値
準備ができているフレーム数。負の場合は、エラーコード
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
読み書きの準備ができているフレームの数を返す。

位置は、サウンドリングバッファ内のハードウェア (ドライバ) の位置と同期しない。
この関数は snd_pcm_avail() の軽量バージョン。

この関数の使用は、poll() または select() の後で、オーディオの fd がイベントを作成し、アプリケーションがピリオドタイミングだけを期待している場合に最適。

また、この関数は、alsa-lib 内の、内部のリングバッファポインタを移動するために、snd_pcm_delay() または snd_pcm_hwsync() の後に呼び出される場合もある。
戻り値
準備ができているフレーム数。負の場合は、エラーコード
int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
再生の場合、delay は、この呼び出しの直後に PCM ストリームに書き込まれたフレームが、実際に聞こえるようになるまでの時間として定義される。
これは、書き込み呼び出しから、最終 DAC までの全体的なレイテンシ。

録音の場合、delay は、オーディオデバイスによってデジタル化されたフレームが、この呼び出しが返された直後に、PCM ストリームから読み取れるようになるまでの時間として定義される。
これは、最初の ADC から、読み込み呼び出しまでの全体的なレイテンシ。

したがって、再生時のアンダーランの場合、この値は必ずしも 0 になるわけではない。

アプリケーションが、デバイスの再生バッファのフィルレベルに関心がある場合は、snd_pcm_avail*() 関数を使用する必要がある。
その呼び出しによって返される値は、delay とは直接関係ない。
delay には、前者には含まれない、追加の固定レイテンシが含まれる可能性があるため。

この関数は、アプリケーションの実際の r/w ポインタを更新しない。
関数 snd_pcm_avail_update() は、mmap の begin+commit 操作の前に呼び出す必要がある。
delayp
レイテンシのフレーム数が返る
戻り値
0 で成功、負の値でエラーコード
int snd_pcm_avail_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp);
snd_pcm_avail() と snd_pcm_delay() を行う。
返される avail 値と delay 値は同期している。
availp
リングバッファ内の利用可能なフレームの数が返る
delayp
フレーム単位の合計 I/O レイテンシが返る
戻り値
0 で成功。負の値でエラーコード
snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm);
巻き戻すことができる安全なフレーム数を取得。

snd_pcm_rewind() は、この関数によって返される値よりも、大きな値を受け入れることができる。
ただし、出力ストリームがより大きな値と一致するかどうかは保証されない。
戻り値
正の値でフレーム数。負の値でエラーコード
snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm);
前進できる安全なフレーム数を取得。

snd_pcm_forward() は、この関数によって返される値よりも、大きな値を受け入れることができる。
ただし、出力ストリームがより大きな値と一致するかどうかは保証されない。
戻り値
正の値でフレーム数。負の値でエラーコード
リンク
int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
2つの PCM をリンクする。
2つの PCM は、同期して、開始/停止/準備を行う。
戻り値
0 で成功、負の値でエラーコード
int snd_pcm_unlink(snd_pcm_t *pcm);
リンクグループから除外
戻り値
0 で成功、負の値でエラーコード