サーバー情報
前回までで、サーバーとの接続が出来たので、まずは、サーバーの情報を取得してみます。
サーバーから情報を取得する際も非同期になるので、情報の取得には、コールバック関数を使います。
現在接続されているサーバーの情報を取得します。
cb で、コールバック関数を指定します。
サーバーから情報が来た場合は、指定されたコールバック関数が実行されるので、引数の構造体ポインタから、情報を参照します。
※このデータは、コールバック関数の実行中のみ有効。
サーバーから情報を取得する際も非同期になるので、情報の取得には、コールバック関数を使います。
サーバーの情報を取得
pa_operation *pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata); //コールバック関数 typedef void (*pa_server_info_cb_t)(pa_context *c, const pa_server_info *i, void *userdata);
現在接続されているサーバーの情報を取得します。
cb で、コールバック関数を指定します。
サーバーから情報が来た場合は、指定されたコールバック関数が実行されるので、引数の構造体ポインタから、情報を参照します。
※このデータは、コールバック関数の実行中のみ有効。
サーバー情報構造体
typedef struct pa_server_info { const char *user_name; const char *host_name; const char *server_version; const char *server_name; pa_sample_spec sample_spec; const char *default_sink_name; const char *default_source_name; uint32_t cookie; pa_channel_map channel_map; } pa_server_info;
user_name | ユーザー名 |
---|---|
host_name | ホスト名 |
server_version | サーバーのバージョン文字列 |
server_name | サーバー名 |
sample_spec | デフォルトのサンプルスペック情報 |
default_sink_name | デフォルトのシンク名 |
default_source_name | デフォルトのソース名 |
cookie | PulseAudio インスタンスのランダムクッキー |
channel_map | デフォルトのチャンネルマップ情報 |
pa_operation
pa_context_get_server_info() の戻り値が、pa_operation * になっていることに注意してください。
これは、非同期の操作の状態を、監視するためのオブジェクトです。
これにより、現在の状態を取得したり、操作をキャンセルしたりすることができます。
pa_operation 関連の詳細はこちら。
pa_operation は参照カウントされるので、解放関数はありません。
戻り値で pa_operation が返る関数の場合は、実際に pa_operation を使わなかったとしても、常に pa_operation_unref() を使って、カウンタを -1 する必要があります。
現在の操作の状態を取得します。
これは、非同期の操作の状態を、監視するためのオブジェクトです。
これにより、現在の状態を取得したり、操作をキャンセルしたりすることができます。
pa_operation 関連の詳細はこちら。
参照カウント
pa_operation *pa_operation_ref(pa_operation *o); void pa_operation_unref(pa_operation *o);
pa_operation は参照カウントされるので、解放関数はありません。
戻り値で pa_operation が返る関数の場合は、実際に pa_operation を使わなかったとしても、常に pa_operation_unref() を使って、カウンタを -1 する必要があります。
状態を取得
pa_operation_state_t pa_operation_get_state(const pa_operation *o);
現在の操作の状態を取得します。
PA_OPERATION_RUNNING | 操作がまだ実行中 |
---|---|
PA_OPERATION_DONE | 操作が完了した |
PA_OPERATION_CANCELLED | キャンセルされた。 アプリケーションによってキャンセルされた、または、操作の保留中にコンテキストが切断された。 |
使い方
戻り値で pa_operation * を返す関数を使った後、操作が完了するまで待ちたい場合は、スレッドメインループなら、以下のような形になります。
まず、pa_threaded_mainloop_lock() で、イベントループをロックするのを忘れないでください。
ロックした後に、情報取得の関数を実行します。
サーバーの接続時と同じように、pa_operation_get_state() で現在の状態を確認して、まだ実行中であれば、イベントが来るのを待ちます。
コールバック関数が来て、処理が終わったら、pa_threaded_mainloop_signal() を実行して、wait から抜けます。
最後に、pa_operation_unref() で、pa_operation の参照カウンタを -1 した後、ロックを解除します。
pa_operation *op; pa_threaded_mainloop_lock(mainloop); op = pa_context_get_server_info(ctx, callback, NULL); while(pa_operation_get_state(op) == PA_OPERATION_RUNNING) pa_threaded_mainloop_wait(mainloop); pa_operation_unref(op); pa_threaded_mainloop_unlock(mainloop);
まず、pa_threaded_mainloop_lock() で、イベントループをロックするのを忘れないでください。
ロックした後に、情報取得の関数を実行します。
サーバーの接続時と同じように、pa_operation_get_state() で現在の状態を確認して、まだ実行中であれば、イベントが来るのを待ちます。
コールバック関数が来て、処理が終わったら、pa_threaded_mainloop_signal() を実行して、wait から抜けます。
最後に、pa_operation_unref() で、pa_operation の参照カウンタを -1 した後、ロックを解除します。
プログラム
接続したサーバーの情報を取得して、出力するプログラムです。
なお、PulseAudio の共通処理は、util.c にまとめておいたので、以降はこの関数を使います。
ソースコードをダウンロードして、util.c も一緒にコンパイルしてください。
メインループは、スレッドの方を使っています。
なお、PulseAudio の共通処理は、util.c にまとめておいたので、以降はこの関数を使います。
ソースコードをダウンロードして、util.c も一緒にコンパイルしてください。
メインループは、スレッドの方を使っています。
$ cc -o 04-serverinfo 04-serverinfo.c util.c -lpulse
#include <stdio.h> #include <pulse/pulseaudio.h> #include "util.h" PulseData *pulse; static void _callback(pa_context *c,const pa_server_info *i,void *userdata) { int j; char m[64]; printf("user_name: %s\n", i->user_name); printf("host_name: %s\n", i->host_name); printf("server_version: %s\n", i->server_version); printf("server_name: %s\n", i->server_name); printf("default_sink_name: %s\n", i->default_sink_name); printf("default_source_name: %s\n", i->default_source_name); printf("cookie: 0x%08x\n", i->cookie); //sample_spec printf("\n[sample_spec]\n"); printf("format: (%d) '%s'\n", i->sample_spec.format, pa_sample_format_to_string(i->sample_spec.format)); printf("rate: %u\n", i->sample_spec.rate); printf("channels: %d\n", i->sample_spec.channels); pa_sample_spec_snprint(m, 64, &i->sample_spec); printf("<snprint> '%s'\n", m); //channel_map printf("\n[channel_map]\n"); for(j = 0; j < i->channel_map.channels; j++) printf("[%d] '%s'\n", j, pa_channel_position_to_pretty_string(i->channel_map.map[j])); pa_channel_map_snprint(m, 64, &i->channel_map); printf("<snprint> '%s'\n", m); printf("<to_name> '%s'\n", pa_channel_map_to_name(&i->channel_map)); printf("<to_pretty_name> '%s'\n", pa_channel_map_to_pretty_name(&i->channel_map)); pa_threaded_mainloop_signal(pulse->mainloop, 0); } int main(void) { pa_operation *op; pulse = pulse_connect(0); if(!pulse) return 1; // pa_threaded_mainloop_lock(pulse->mainloop); op = pa_context_get_server_info(pulse->ctx, _callback, NULL); while(pa_operation_get_state(op) == PA_OPERATION_RUNNING) pa_threaded_mainloop_wait(pulse->mainloop); pa_operation_unref(op); pa_threaded_mainloop_unlock(pulse->mainloop); // pulse_free(pulse); return 0; }
実行結果
user_name: ****(環境による) host_name: ****(環境による) server_version: 17.0 server_name: pulseaudio default_sink_name: alsa_output.pci-0000_00_1f.3.analog-stereo default_source_name: alsa_output.pci-0000_00_1f.3.analog-stereo.monitor cookie: 0x64d2ba68 [sample_spec] format: (3) 's16le' rate: 44100 channels: 2 <snprint> 's16le 2ch 44100Hz' [channel_map] [0] 'Front Left' [1] 'Front Right' <snprint> 'front-left,front-right' <to_name> 'stereo' <to_pretty_name> 'Stereo'
default_sink_name は、デフォルトのオーディオ出力先を意味します。
default_source_name は、デフォルトとのオーディオ入力元です。
サンプルスペックとチャンネルマップは、値を元に、文字列を取得する関数があるので、それらを使って表示しています。
チャンネルマップは、各チャンネルが、どの位置にあるかという情報です。
ステレオなら、「(前方) 左」と「(前方) 右」の、2つのチャンネルがあります。
サンプルスペックの詳細はこちら。
チャンネルマップの詳細はこちら。