カード情報の取得
次に、カード情報を取得します。
カードとは、ハードウェア構成のことです。
カード情報を取得するには、3つの方法があります。
by_index はインデックス番号から、by_name はカード名から、単体の情報を取得します。
list は、すべてのカード情報を取得します。
カードとは、ハードウェア構成のことです。
関数
pa_operation *pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata); pa_operation *pa_context_get_card_info_by_name(pa_context *c, const char *name, pa_card_info_cb_t cb, void *userdata); pa_operation *pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata); //コールバック関数 typedef void (*pa_card_info_cb_t)(pa_context *c, const pa_card_info *i, int eol, void *userdata);
カード情報を取得するには、3つの方法があります。
by_index はインデックス番号から、by_name はカード名から、単体の情報を取得します。
list は、すべてのカード情報を取得します。
プログラム
情報が多いので、まずはプログラムを提示します。
すべてのカード情報を取得して、出力します。
すべてのカード情報を取得して、出力します。
$ cc -o 06-card 06-card.c util.c -lpulse
#include <stdio.h> #include <pulse/pulseaudio.h> #include "util.h" PulseData *pulse; static void _card_callback(pa_context *c,const pa_card_info *i,int eol,void *userdata) { int j,k; pa_card_profile_info2 *prof; pa_card_port_info *port; if(!i) { pa_threaded_mainloop_signal(pulse->mainloop, 0); return; } printf("[index:%u]\n", i->index); printf("name: %s\n", i->name); printf("owner_module: %u\n", i->owner_module); printf("driver: %s\n", i->driver); printf("n_profiles: %u\n", i->n_profiles); printf("n_ports: %u\n", i->n_ports); pulse_put_proplist(i->proplist); //profile printf("\n=== profile ===\n"); for(j = 0; j < i->n_profiles; j++) { prof = i->profiles2[j]; printf("---[%d](%c)---\n", j, (prof == i->active_profile2)? '*': '-'); printf(" name: '%s'\n", prof->name); printf(" description: '%s'\n", prof->description); printf(" n_sinks: %u\n", prof->n_sinks); printf(" n_sources: %u\n", prof->n_sources); printf(" priority: %u\n", prof->priority); printf(" available: %d\n", prof->available); } //ports printf("\n=== ports ===\n"); for(j = 0; j < i->n_ports; j++) { port = i->ports[j]; printf("---[%d]---\n", j); printf(" name: '%s'\n", port->name); printf(" description: '%s'\n", port->description); printf(" priority: %u\n", port->priority); printf(" available: %d\n", port->available); printf(" direction: %s\n", (port->direction == PA_DIRECTION_OUTPUT)? "OUT": "IN"); printf(" n_profiles: %u\n", port->n_profiles); printf(" latency_offset: %ld\n", port->latency_offset); printf(" availability_group: %s\n", port->availability_group); printf(" type: %u\n", port->type); printf(" <profiles>\n"); for(k = 0; k < port->n_profiles; k++) printf(" [%d] %s\n", k, (port->profiles2[k])->description); pulse_put_proplist(port->proplist); } printf("\n"); } static pa_operation *_get_info(PulseData *p,void *data) { return pa_context_get_card_info_list(pulse->ctx, _card_callback, NULL); } int main(void) { pulse = pulse_connect(0); if(!pulse) return 1; pulse_wait_operation(pulse, _get_info, NULL); pulse_free(pulse); return 0; }
カード情報 (pa_card_info)
まずは、struct pa_card_info のカード情報です。
profiles と active_profile は、現在廃止されています。
代わりに、profiles2 と active_profile2 を使います。
サウンドカードが1つなら、基本的にカード情報は1つです。
プロパティリストには、ハードウェアの情報などが格納されています。
typedef struct pa_card_info { uint32_t index; const char *name; uint32_t owner_module; const char *driver; uint32_t n_profiles; pa_card_profile_info *profiles; //廃止 pa_card_profile_info *active_profile; //廃止 pa_proplist *proplist; uint32_t n_ports; pa_card_port_info **ports; pa_card_profile_info2 **profiles2; pa_card_profile_info2 *active_profile2; } pa_card_info;
profiles と active_profile は、現在廃止されています。
代わりに、profiles2 と active_profile2 を使います。
index | サーバー上で認識されるインデックス番号 |
---|---|
name | カード名 |
owner_module | 所有モジュールのインデックス、または PA_INVALID_INDEX |
driver | ドライバ名 |
n_profiles | プロファイルの数 |
proplist | プロパティリスト |
n_ports | ポートの数 |
ports | 利用可能なポートのポインタの配列、または NULL |
profiles2 | 利用可能なプロファイルのポインタの配列、または NULL |
active_profile2 | 現在アクティブなプロファイル。 profiles2 配列内の一つのポインタ、または NULL。 |
実行結果
[index:0] name: alsa_card.pci-0000_00_1f.3 owner_module: 6 driver: module-alsa-card.c n_profiles: 18 n_ports: 8 <proplist> alsa.card = "0" alsa.card_name = "HDA Intel PCH" alsa.long_card_name = "HDA Intel PCH at 0xdf140000 irq 130" alsa.driver_name = "snd_hda_intel" device.bus_path = "pci-0000:00:1f.3" sysfs.path = "/devices/pci0000:00/0000:00:1f.3/sound/card0" device.bus = "pci" device.vendor.id = "8086" device.vendor.name = "Intel Corporation" device.product.id = "a170" device.product.name = "100 Series/C230 Series Chipset Family HD Audio Controller" device.form_factor = "internal" device.string = "0" device.description = "内部オーディオ" module-udev-detect.discovered = "1" device.icon_name = "audio-card-pci"
サウンドカードが1つなら、基本的にカード情報は1つです。
プロパティリストには、ハードウェアの情報などが格納されています。
プロファイル情報 (pa_card_profile_info2)
pa_card_info 構造体の profiles2 メンバは、このカードで利用できるプロファイル情報の、ポインタの配列です。
n_profiles の個数分あります。
n_profiles の個数分あります。
typedef struct pa_card_profile_info2 { const char *name; const char *description; uint32_t n_sinks; uint32_t n_sources; uint32_t priority; int available; } pa_card_profile_info2;
name | プロファイル名 |
---|---|
description | プロファイルの詳細説明 |
n_sinks | このプロファイルが作成するシンクの数。 シンクは、出力のことです。 |
n_sources | このプロファイルが作成するソースの数。 ソースは、入力のことです。 PulseAudio が仮想的に作成するソースの数は含まれません。 |
priority | 優先度。 値が高いほど、デフォルトに近くなる。 |
available | このプロファイルが利用できるか。 0 の場合、使用不可。 0 以外であっても、このプロファイルを有効しても、意味がない場合もある。 |
実行結果
=== profile === ---[0](-)--- name: 'input:analog-stereo' description: 'アナログステレオ 入力' n_sinks: 0 n_sources: 1 priority: 65 available: 0 ---[1](-)--- name: 'output:analog-stereo' description: 'アナログステレオ 出力' n_sinks: 1 n_sources: 0 priority: 39268 available: 1 ---[2](*)--- name: 'output:analog-stereo+input:analog-stereo' description: 'アナログステレオデュプレックス' n_sinks: 1 n_sources: 1 priority: 6565 available: 1 ---[3](-)--- name: 'output:hdmi-stereo' description: 'Digital Stereo (HDMI) 出力' n_sinks: 1 n_sources: 0 priority: 38668 available: 1 ---[4](-)--- name: 'output:hdmi-stereo+input:analog-stereo' description: 'Digital Stereo (HDMI) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 5965 available: 1 ---[5](-)--- name: 'output:hdmi-stereo-extra1' description: 'Digital Stereo (HDMI 2) 出力' n_sinks: 1 n_sources: 0 priority: 5700 available: 0 ---[6](-)--- name: 'output:hdmi-stereo-extra1+input:analog-stereo' description: 'Digital Stereo (HDMI 2) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 5765 available: 0 ---[7](-)--- name: 'output:hdmi-surround-extra1' description: 'Digital Surround 5.1 (HDMI 2) 出力' n_sinks: 1 n_sources: 0 priority: 600 available: 0 ---[8](-)--- name: 'output:hdmi-surround-extra1+input:analog-stereo' description: 'Digital Surround 5.1 (HDMI 2) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 665 available: 0 ---[9](-)--- name: 'output:hdmi-surround71-extra1' description: 'Digital Surround 7.1 (HDMI 2) 出力' n_sinks: 1 n_sources: 0 priority: 600 available: 0 ---[10](-)--- name: 'output:hdmi-surround71-extra1+input:analog-stereo' description: 'Digital Surround 7.1 (HDMI 2) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 665 available: 0 ---[11](-)--- name: 'output:hdmi-stereo-extra2' description: 'Digital Stereo (HDMI 3) 出力' n_sinks: 1 n_sources: 0 priority: 5700 available: 0 ---[12](-)--- name: 'output:hdmi-stereo-extra2+input:analog-stereo' description: 'Digital Stereo (HDMI 3) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 5765 available: 0 ---[13](-)--- name: 'output:hdmi-surround-extra2' description: 'Digital Surround 5.1 (HDMI 3) 出力' n_sinks: 1 n_sources: 0 priority: 600 available: 0 ---[14](-)--- name: 'output:hdmi-surround-extra2+input:analog-stereo' description: 'Digital Surround 5.1 (HDMI 3) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 665 available: 0 ---[15](-)--- name: 'output:hdmi-surround71-extra2' description: 'Digital Surround 7.1 (HDMI 3) 出力' n_sinks: 1 n_sources: 0 priority: 600 available: 0 ---[16](-)--- name: 'output:hdmi-surround71-extra2+input:analog-stereo' description: 'Digital Surround 7.1 (HDMI 3) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 665 available: 0 ---[17](-)--- name: 'off' description: 'オフ' n_sinks: 0 n_sources: 0 priority: 0 available: 1
解説
プロファイルとは、ハードウェア上のどの端子を組み合わせて、出力と入力を行うか、という構成です。
HDMI 端子でモニタが繋がっていて、アナログオーディオ端子にも接続がある場合は、どちらに出力を行うかを、選択する必要があります。
それぞれの priority の数値を見ると、値が一番高いのは「アナログステレオ 出力」なので、ユーザーによる選択がなければ、このプロファイルが優先されます。
index = 1 の「アナログステレオ 出力」を見てみると、n_sinks は 1 で、シンク(出力)は1つだけ作成されます。
n_sources は 0 なので、ソース(入力)は使用されません。つまり、ハードウェアからの録音はできないということです。
available が 1 なので、このプロファイルは利用可能です。
「アナログステレオデュプレックス」は、アナログオーディオの出力と入力を使います。
アナログ端子への出力と、アナログ端子からの入力が可能になります。
この場合、HDMI へのオーディオ出力は行われません。
なお、サーバー上では、このプロファイルが現在アクティブになっているので、profiles2[2] == active_profile2 となります。
HDMI で繋がっているモニタのスピーカー、あるいは、モニタのヘッドホン端子に出力する場合は、HDMI 出力のプロファイルを使います。
この場合、PC 本体のアナログ端子への出力は行われません。
ただし、「+アナログステレオ入力」の場合は、入力として、本体のアナログ入力端子を使います。
他にも、HDMI2 や HDMI3 がありますが、この PC には HDMI 端子が1つしかないので、これらは利用不可の状態になっています。
HDMI 端子でモニタが繋がっていて、アナログオーディオ端子にも接続がある場合は、どちらに出力を行うかを、選択する必要があります。
それぞれの priority の数値を見ると、値が一番高いのは「アナログステレオ 出力」なので、ユーザーによる選択がなければ、このプロファイルが優先されます。
アナログステレオ 出力
---[1](-)--- name: 'output:analog-stereo' description: 'アナログステレオ 出力' n_sinks: 1 n_sources: 0 priority: 39268 available: 1
index = 1 の「アナログステレオ 出力」を見てみると、n_sinks は 1 で、シンク(出力)は1つだけ作成されます。
n_sources は 0 なので、ソース(入力)は使用されません。つまり、ハードウェアからの録音はできないということです。
available が 1 なので、このプロファイルは利用可能です。
アナログステレオデュプレックス
---[2](*)--- name: 'output:analog-stereo+input:analog-stereo' description: 'アナログステレオデュプレックス' n_sinks: 1 n_sources: 1 priority: 6565 available: 1
「アナログステレオデュプレックス」は、アナログオーディオの出力と入力を使います。
アナログ端子への出力と、アナログ端子からの入力が可能になります。
この場合、HDMI へのオーディオ出力は行われません。
なお、サーバー上では、このプロファイルが現在アクティブになっているので、profiles2[2] == active_profile2 となります。
HDMI
---[3](-)--- name: 'output:hdmi-stereo' description: 'Digital Stereo (HDMI) 出力' n_sinks: 1 n_sources: 0 priority: 38668 available: 1 ---[4](-)--- name: 'output:hdmi-stereo+input:analog-stereo' description: 'Digital Stereo (HDMI) 出力 + アナログステレオ 入力' n_sinks: 1 n_sources: 1 priority: 5965 available: 1
HDMI で繋がっているモニタのスピーカー、あるいは、モニタのヘッドホン端子に出力する場合は、HDMI 出力のプロファイルを使います。
この場合、PC 本体のアナログ端子への出力は行われません。
ただし、「+アナログステレオ入力」の場合は、入力として、本体のアナログ入力端子を使います。
他にも、HDMI2 や HDMI3 がありますが、この PC には HDMI 端子が1つしかないので、これらは利用不可の状態になっています。
ポート情報 (pa_card_port_info)
pa_card_info 構造体の ports メンバは、このカードで利用可能なポート情報の、ポインタの配列です。
n_ports の個数分あります。
ポートは、ハードウェア上の端子を意味します。
「マイクロフォン」はマイク端子のことです。
PC 前面に「マイク端子」「ヘッドホン端子」、PC 背面に「マイク端子」「ラインイン」「ラインアウト」「HDMI」があります。
「フロント」は PC 前面を意味し、「リア」は PC 背面を意味します。
プロパティリストには、その端子を表示するためのアイコン名や、HDMI に接続されているモニタ名が格納されています。
n_ports の個数分あります。
ポートは、ハードウェア上の端子を意味します。
typedef struct pa_card_port_info { const char *name; const char *description; uint32_t priority; int available; int direction; uint32_t n_profiles; pa_card_profile_info **profiles; //廃止 pa_proplist *proplist; int64_t latency_offset; pa_card_profile_info2 **profiles2; const char *availability_group; //ver 14.0 uint32_t type; //ver 14.0 } pa_card_port_info;
name | ポート名 |
---|---|
description | ポートの詳細説明 |
priority | 優先度。値が高いほどデフォルトに近い。 |
available | このポートが実際に使用できるかを示す、pa_port_available 列挙型。 PA_PORT_AVAILABLE_UNKNOWN (0) : 端子の接続判定をサポートしていない。 PA_PORT_AVAILABLE_NO (1) : 使用できない。端子が接続されていない可能性がある。 PA_PORT_AVAILABLE_YES (2) : 使用可能。 |
direction | このポートの方向を示す、pa_direction 列挙型。 PA_DIRECTION_OUTPUT : 出力 PA_DIRECTION_INPUT : 入力 |
n_profiles | プロファイルの配列の数 |
proplist | プロパティリスト |
latency_offset | ポートがアクティブなときに、シンク/ソースの遅延に追加されるオフセット |
profiles2 | このポートを利用できるプロファイルの、ポインタの配列 |
availability_group | ポートのグループ識別子名。 available の状態を相互に共有する。 |
type | ポートタイプ (pa_device_port_type 列挙型) |
実行結果
=== ports === ---[0]--- name: 'analog-input-front-mic' description: 'フロントマイクロフォン' priority: 8500 available: 1 direction: IN n_profiles: 9 latency_offset: 0 availability_group: (null) type: 5 <profiles> [0] アナログステレオ 入力 [1] アナログステレオデュプレックス [2] Digital Stereo (HDMI) 出力 + アナログステレオ 入力 [3] Digital Stereo (HDMI 2) 出力 + アナログステレオ 入力 [4] Digital Surround 5.1 (HDMI 2) 出力 + アナログステレオ 入力 [5] Digital Surround 7.1 (HDMI 2) 出力 + アナログステレオ 入力 [6] Digital Stereo (HDMI 3) 出力 + アナログステレオ 入力 [7] Digital Surround 5.1 (HDMI 3) 出力 + アナログステレオ 入力 [8] Digital Surround 7.1 (HDMI 3) 出力 + アナログステレオ 入力 <proplist> device.icon_name = "audio-input-microphone" ---[1]--- name: 'analog-input-rear-mic' description: 'リアマイクロフォン' priority: 8200 available: 1 direction: IN n_profiles: 9 latency_offset: 0 availability_group: (null) type: 5 <profiles> [0] アナログステレオ 入力 [1] アナログステレオデュプレックス [2] Digital Stereo (HDMI) 出力 + アナログステレオ 入力 [3] Digital Stereo (HDMI 2) 出力 + アナログステレオ 入力 [4] Digital Surround 5.1 (HDMI 2) 出力 + アナログステレオ 入力 [5] Digital Surround 7.1 (HDMI 2) 出力 + アナログステレオ 入力 [6] Digital Stereo (HDMI 3) 出力 + アナログステレオ 入力 [7] Digital Surround 5.1 (HDMI 3) 出力 + アナログステレオ 入力 [8] Digital Surround 7.1 (HDMI 3) 出力 + アナログステレオ 入力 <proplist> device.icon_name = "audio-input-microphone" ---[2]--- name: 'analog-input-linein' description: 'ラインイン' priority: 8100 available: 1 direction: IN n_profiles: 9 latency_offset: 0 availability_group: (null) type: 4 <profiles> [0] アナログステレオ 入力 [1] アナログステレオデュプレックス [2] Digital Stereo (HDMI) 出力 + アナログステレオ 入力 [3] Digital Stereo (HDMI 2) 出力 + アナログステレオ 入力 [4] Digital Surround 5.1 (HDMI 2) 出力 + アナログステレオ 入力 [5] Digital Surround 7.1 (HDMI 2) 出力 + アナログステレオ 入力 [6] Digital Stereo (HDMI 3) 出力 + アナログステレオ 入力 [7] Digital Surround 5.1 (HDMI 3) 出力 + アナログステレオ 入力 [8] Digital Surround 7.1 (HDMI 3) 出力 + アナログステレオ 入力 <proplist> ---[3]--- name: 'analog-output-lineout' description: 'ライン出力' priority: 9000 available: 1 direction: OUT n_profiles: 2 latency_offset: 0 availability_group: (null) type: 4 <profiles> [0] アナログステレオ 出力 [1] アナログステレオデュプレックス <proplist> ---[4]--- name: 'analog-output-headphones' description: 'アナログヘッドフォン' priority: 9900 available: 2 direction: OUT n_profiles: 2 latency_offset: 0 availability_group: (null) type: 3 <profiles> [0] アナログステレオ 出力 [1] アナログステレオデュプレックス <proplist> device.icon_name = "audio-headphones" ---[5]--- name: 'hdmi-output-0' description: 'HDMI / DisplayPort' priority: 5900 available: 2 direction: OUT n_profiles: 2 latency_offset: 0 availability_group: (null) type: 10 <profiles> [0] Digital Stereo (HDMI) 出力 [1] Digital Stereo (HDMI) 出力 + アナログステレオ 入力 <proplist> device.icon_name = "video-display" device.product.name = "PHL 224E5" ---[6]--- name: 'hdmi-output-1' description: 'HDMI / DisplayPort 2' priority: 5800 available: 1 direction: OUT n_profiles: 6 latency_offset: 0 availability_group: (null) type: 10 <profiles> [0] Digital Stereo (HDMI 2) 出力 [1] Digital Stereo (HDMI 2) 出力 + アナログステレオ 入力 [2] Digital Surround 5.1 (HDMI 2) 出力 [3] Digital Surround 5.1 (HDMI 2) 出力 + アナログステレオ 入力 [4] Digital Surround 7.1 (HDMI 2) 出力 [5] Digital Surround 7.1 (HDMI 2) 出力 + アナログステレオ 入力 <proplist> device.icon_name = "video-display" ---[7]--- name: 'hdmi-output-2' description: 'HDMI / DisplayPort 3' priority: 5700 available: 1 direction: OUT n_profiles: 6 latency_offset: 0 availability_group: (null) type: 10 <profiles> [0] Digital Stereo (HDMI 3) 出力 [1] Digital Stereo (HDMI 3) 出力 + アナログステレオ 入力 [2] Digital Surround 5.1 (HDMI 3) 出力 [3] Digital Surround 5.1 (HDMI 3) 出力 + アナログステレオ 入力 [4] Digital Surround 7.1 (HDMI 3) 出力 [5] Digital Surround 7.1 (HDMI 3) 出力 + アナログステレオ 入力 <proplist> device.icon_name = "video-display"
「マイクロフォン」はマイク端子のことです。
PC 前面に「マイク端子」「ヘッドホン端子」、PC 背面に「マイク端子」「ラインイン」「ラインアウト」「HDMI」があります。
「フロント」は PC 前面を意味し、「リア」は PC 背面を意味します。
プロパティリストには、その端子を表示するためのアイコン名や、HDMI に接続されているモニタ名が格納されています。
プロファイルの変更
現在接続されているサーバー上で、アクティブになっているプロファイルを変更したい場合は、以下の関数を使います。
そのサーバーに接続されている、他のクライアントも影響を受けるので、注意してください。
by_index は、設定を変更したいカードのインデックス番号を指定し、by_name はカードの名前を指定します。
profile 引数に、変更するプロファイルの名前を指定します。
コールバック関数の success 引数で、操作が成功したか失敗したかが判断できます。
そのサーバーに接続されている、他のクライアントも影響を受けるので、注意してください。
pa_operation *pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx, const char *profile, pa_context_success_cb_t cb, void *userdata); pa_operation *pa_context_set_card_profile_by_name(pa_context *c, const char *name, const char *profile, pa_context_success_cb_t cb, void *userdata); //コールバック関数 typedef void (*pa_context_success_cb_t)(pa_context *c, int success, void *userdata);
by_index は、設定を変更したいカードのインデックス番号を指定し、by_name はカードの名前を指定します。
profile 引数に、変更するプロファイルの名前を指定します。
コールバック関数の success 引数で、操作が成功したか失敗したかが判断できます。