チャンネルマップ
PCM から、有効なチャンネルマップの情報を取得することができます。
チャンネルマップ関連の関数は、チャンネルマップ をご覧ください。
開いた PCM から取得する方法と、カード・デバイス・サブデバイス・ストリーム方向を指定して、取得する方法があります。
snd_pcm_chmap_query_t 構造体のポインタの配列、または NULL が返ります。
返ったポインタは、snd_pcm_free_chmaps() で解放します。
(snd_pcm_chmap_query_t *) の値が NULL で、データの終端になります。
snd_pcm_chmap_query_t の type は、チャンネル位置を交換できるかどうかのタイプです。
snd_pcm_chmap_t が、各チャンネルマップの情報です。
pos の配列は、チャンネル数分あります。
実際は、enum snd_pcm_chmap_position の値が格納されています。
ステレオ 2ch なら、FL と FR になります。
チャンネルマップ関連の関数は、チャンネルマップ をご覧ください。
チャンネルマップの情報取得
//開いた PCM から snd_pcm_chmap_query_t **snd_pcm_query_chmaps(snd_pcm_t *pcm); //カード番号などを指定 snd_pcm_chmap_query_t **snd_pcm_query_chmaps_from_hw(int card, int dev, int subdev, snd_pcm_stream_t stream); //解放 void snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps);
開いた PCM から取得する方法と、カード・デバイス・サブデバイス・ストリーム方向を指定して、取得する方法があります。
snd_pcm_chmap_query_t 構造体のポインタの配列、または NULL が返ります。
返ったポインタは、snd_pcm_free_chmaps() で解放します。
(snd_pcm_chmap_query_t *) の値が NULL で、データの終端になります。
snd_pcm_chmap_query_t
typedef struct snd_pcm_chmap_query { enum snd_pcm_chmap_type type; snd_pcm_chmap_t map; } snd_pcm_chmap_query_t; //各チャンネルマップ typedef struct snd_pcm_chmap { unsigned int channels; //チャンネル数 unsigned int pos[0]; //チャンネル位置 } snd_pcm_chmap_t;
snd_pcm_chmap_query_t の type は、チャンネル位置を交換できるかどうかのタイプです。
SND_CHMAP_TYPE_NONE | 未指定 |
---|---|
SND_CHMAP_TYPE_FIXED | 固定 |
SND_CHMAP_TYPE_VAR | 自由に交換可能 |
SND_CHMAP_TYPE_PAIRED | ペアで交換可能 |
snd_pcm_chmap_t が、各チャンネルマップの情報です。
pos の配列は、チャンネル数分あります。
実際は、enum snd_pcm_chmap_position の値が格納されています。
enum snd_pcm_chmap_position { SND_CHMAP_UNKNOWN = 0, //未定義 SND_CHMAP_NA, //無音 SND_CHMAP_MONO, SND_CHMAP_FL, //Front left SND_CHMAP_FR, SND_CHMAP_RL, //Rear left SND_CHMAP_RR, ...
ステレオ 2ch なら、FL と FR になります。
プログラム
指定した PCM で有効な、チャンネルマップの一覧を出力します。
$ cc -o 12-chmap 12-chmap.c -lasound
int main(int argc,char **argv) { snd_pcm_t *pcm; snd_pcm_chmap_query_t **ppmap,**ptr,*chmap; unsigned int i; if(snd_pcm_open(&pcm, (argc >= 2)? argv[1]: "default", SND_PCM_STREAM_PLAYBACK, 0)) { printf("open error\n"); return 1; } //チャンネルマップ ppmap = snd_pcm_query_chmaps(pcm); if(!ppmap) goto END; for(ptr = ppmap; *ptr; ptr++) { chmap = *ptr; printf("type: %s\n", snd_pcm_chmap_type_name(chmap->type)); printf("channels: %u\n", chmap->map.channels); for(i = 0; i < chmap->map.channels; i++) { printf("[%u] '%s' '%s'\n", i, snd_pcm_chmap_name(chmap->map.pos[i]), snd_pcm_chmap_long_name(chmap->map.pos[i])); } printf("------\n"); } snd_pcm_free_chmaps(ppmap); // END: snd_pcm_close(pcm); return 0; }
実行結果
type: FIXED channels: 2 [0] 'FL' 'Front Left' [1] 'FR' 'Front Right' ------
アナログ出力の場合、チャンネル位置は固定で、2ch (左、右) となっています。
HDMI
$ ./12-chmap hdmi type: VAR channels: 2 [0] 'FL' 'Front Left' [1] 'FR' 'Front Right' ------
HDMI の場合は、タイプが VAR なので、チャンネル位置が自由に交換可能になっています。
つまり、左右のチャンネル位置を入れ替えることができます。
snd_pcm_set_chmap() を使うと、現在のチャンネルマップを変更することができます。