From 9c1a0ce72d71e4728d45dcd3986dd0ef0201dd67 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 4 Sep 2012 17:26:43 +0200 Subject: [PATCH 09/30] PCM: Introduce snd_pcm_chmap_t and snd_pcm_chmap_query_t Instead of passing ambiguous integer array, define snd_pcm_chmap_t and snd_pcm_chmap_query_t so that user can understand more easily which element is for what. Signed-off-by: Takashi Iwai --- include/pcm.h | 21 +++++++++++++++++---- include/pcm_extplug.h | 6 +++--- include/pcm_ioplug.h | 6 +++--- src/pcm/pcm.c | 10 +++++----- src/pcm/pcm_direct.c | 6 +++--- src/pcm/pcm_direct.h | 6 +++--- src/pcm/pcm_extplug.c | 6 +++--- src/pcm/pcm_generic.c | 6 +++--- src/pcm/pcm_generic.h | 6 +++--- src/pcm/pcm_hw.c | 31 ++++++++++++++++--------------- src/pcm/pcm_ioplug.c | 6 +++--- src/pcm/pcm_local.h | 6 +++--- src/pcm/pcm_multi.c | 25 ++++++++++++++----------- src/pcm/pcm_route.c | 10 +++++----- test/chmap.c | 35 ++++++++++++++++++----------------- 15 files changed, 102 insertions(+), 84 deletions(-) --- a/include/pcm.h +++ b/include/pcm.h @@ -512,10 +512,23 @@ enum snd_pcm_chmap_position { #define SND_CHMAP_PHASE_INVERSE (0x01 << 16) /* the channel is phase inverted */ #define SND_CHMAP_DRIVER_SPEC (0x02 << 16) /* non-standard channel value */ -int **snd_pcm_query_chmaps(snd_pcm_t *pcm); -void snd_pcm_free_chmaps(int **maps); -int *snd_pcm_get_chmap(snd_pcm_t *pcm); -int snd_pcm_set_chmap(snd_pcm_t *pcm, const int *map); +/** the channel map header */ +typedef struct snd_pcm_chmap { + unsigned int channels; + unsigned int pos[0]; +} snd_pcm_chmap_t; + +/** the header of array items returned from snd_pcm_query_chmaps() */ +typedef struct snd_pcm_chmap_query { + enum snd_pcm_chmap_type type; + snd_pcm_chmap_t map; +} snd_pcm_chmap_query_t; + + +snd_pcm_chmap_query_t **snd_pcm_query_chmaps(snd_pcm_t *pcm); +void snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps); +snd_pcm_chmap_t *snd_pcm_get_chmap(snd_pcm_t *pcm); +int snd_pcm_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); //int snd_pcm_mixer_element(snd_pcm_t *pcm, snd_mixer_t *mixer, snd_mixer_elem_t **elem); --- a/include/pcm_extplug.h +++ b/include/pcm_extplug.h @@ -154,15 +154,15 @@ struct snd_pcm_extplug_callback { /** * query the channel maps; optional; since v1.0.2 */ - int **(*query_chmaps)(snd_pcm_extplug_t *ext); + snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_extplug_t *ext); /** * get the channel map; optional; since v1.0.2 */ - int *(*get_chmap)(snd_pcm_extplug_t *ext); + snd_pcm_chmap_t *(*get_chmap)(snd_pcm_extplug_t *ext); /** * set the channel map; optional; since v1.0.2 */ - int (*set_chmap)(snd_pcm_extplug_t *ext, const int *map); + int (*set_chmap)(snd_pcm_extplug_t *ext, const snd_pcm_chmap_t *map); }; --- a/include/pcm_ioplug.h +++ b/include/pcm_ioplug.h @@ -192,15 +192,15 @@ struct snd_pcm_ioplug_callback { /** * query the channel maps; optional; since v1.0.2 */ - int **(*query_chmaps)(snd_pcm_ioplug_t *io); + snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_ioplug_t *io); /** * get the channel map; optional; since v1.0.2 */ - int *(*get_chmap)(snd_pcm_ioplug_t *io); + snd_pcm_chmap_t *(*get_chmap)(snd_pcm_ioplug_t *io); /** * set the channel map; optional; since v1.0.2 */ - int (*set_chmap)(snd_pcm_ioplug_t *io, const int *map); + int (*set_chmap)(snd_pcm_ioplug_t *io, const snd_pcm_chmap_t *map); }; --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -7310,7 +7310,7 @@ OBSOLETE1(snd_pcm_sw_params_get_silence_ * integer array, beginning with the channel map type, followed by the * number of channels, and the position of each channel. */ -int **snd_pcm_query_chmaps(snd_pcm_t *pcm) +snd_pcm_chmap_query_t **snd_pcm_query_chmaps(snd_pcm_t *pcm) { if (!pcm->ops->query_chmaps) return NULL; @@ -7321,9 +7321,9 @@ int **snd_pcm_query_chmaps(snd_pcm_t *pc * \!brief Release the channel map array allocated via #snd_pcm_query_chmaps * \param maps the array pointer to release */ -void snd_pcm_free_chmaps(int **maps) +void snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps) { - int **p; + snd_pcm_chmap_query_t **p = maps; if (!maps) return; for (p = maps; *p; p++) @@ -7336,7 +7336,7 @@ void snd_pcm_free_chmaps(int **maps) * \param pcm PCM instance * \return the current channel map, or NULL if error */ -int *snd_pcm_get_chmap(snd_pcm_t *pcm) +snd_pcm_chmap_t *snd_pcm_get_chmap(snd_pcm_t *pcm) { if (!pcm->ops->get_chmap) return NULL; @@ -7349,7 +7349,7 @@ int *snd_pcm_get_chmap(snd_pcm_t *pcm) * \param map the channel map to write * \return zero if succeeded, or a negative error code */ -int snd_pcm_set_chmap(snd_pcm_t *pcm, const int *map) +int snd_pcm_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map) { if (!pcm->ops->set_chmap) return -ENXIO; --- a/src/pcm/pcm_direct.c +++ b/src/pcm/pcm_direct.c @@ -789,19 +789,19 @@ int snd_pcm_direct_munmap(snd_pcm_t *pcm return 0; } -int **snd_pcm_direct_query_chmaps(snd_pcm_t *pcm) +snd_pcm_chmap_query_t **snd_pcm_direct_query_chmaps(snd_pcm_t *pcm) { snd_pcm_direct_t *dmix = pcm->private_data; return snd_pcm_query_chmaps(dmix->spcm); } -int *snd_pcm_direct_get_chmap(snd_pcm_t *pcm) +snd_pcm_chmap_t *snd_pcm_direct_get_chmap(snd_pcm_t *pcm) { snd_pcm_direct_t *dmix = pcm->private_data; return snd_pcm_get_chmap(dmix->spcm); } -int snd_pcm_direct_set_chmap(snd_pcm_t *pcm, const int *map) +int snd_pcm_direct_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map) { snd_pcm_direct_t *dmix = pcm->private_data; return snd_pcm_set_chmap(dmix->spcm, map); --- a/src/pcm/pcm_direct.h +++ b/src/pcm/pcm_direct.h @@ -296,9 +296,9 @@ void snd_pcm_direct_clear_timer_queue(sn int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix); int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name); -int **snd_pcm_direct_query_chmaps(snd_pcm_t *pcm); -int *snd_pcm_direct_get_chmap(snd_pcm_t *pcm); -int snd_pcm_direct_set_chmap(snd_pcm_t *pcm, const int *map); +snd_pcm_chmap_query_t **snd_pcm_direct_query_chmaps(snd_pcm_t *pcm); +snd_pcm_chmap_t *snd_pcm_direct_get_chmap(snd_pcm_t *pcm); +int snd_pcm_direct_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid); struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm); --- a/src/pcm/pcm_extplug.c +++ b/src/pcm/pcm_extplug.c @@ -425,7 +425,7 @@ static int snd_pcm_extplug_close(snd_pcm return 0; } -static int **snd_pcm_extplug_query_chmaps(snd_pcm_t *pcm) +static snd_pcm_chmap_query_t **snd_pcm_extplug_query_chmaps(snd_pcm_t *pcm) { extplug_priv_t *ext = pcm->private_data; @@ -435,7 +435,7 @@ static int **snd_pcm_extplug_query_chmap return snd_pcm_generic_query_chmaps(pcm); } -static int *snd_pcm_extplug_get_chmap(snd_pcm_t *pcm) +static snd_pcm_chmap_t *snd_pcm_extplug_get_chmap(snd_pcm_t *pcm) { extplug_priv_t *ext = pcm->private_data; @@ -445,7 +445,7 @@ static int *snd_pcm_extplug_get_chmap(sn return snd_pcm_generic_get_chmap(pcm); } -static int snd_pcm_extplug_set_chmap(snd_pcm_t *pcm, const int *map) +static int snd_pcm_extplug_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map) { extplug_priv_t *ext = pcm->private_data; --- a/src/pcm/pcm_generic.c +++ b/src/pcm/pcm_generic.c @@ -323,19 +323,19 @@ int snd_pcm_generic_munmap(snd_pcm_t *pc return 0; } -int **snd_pcm_generic_query_chmaps(snd_pcm_t *pcm) +snd_pcm_chmap_query_t **snd_pcm_generic_query_chmaps(snd_pcm_t *pcm) { snd_pcm_generic_t *generic = pcm->private_data; return snd_pcm_query_chmaps(generic->slave); } -int *snd_pcm_generic_get_chmap(snd_pcm_t *pcm) +snd_pcm_chmap_t *snd_pcm_generic_get_chmap(snd_pcm_t *pcm) { snd_pcm_generic_t *generic = pcm->private_data; return snd_pcm_get_chmap(generic->slave); } -int snd_pcm_generic_set_chmap(snd_pcm_t *pcm, const int *map) +int snd_pcm_generic_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map) { snd_pcm_generic_t *generic = pcm->private_data; return snd_pcm_set_chmap(generic->slave, map); --- a/src/pcm/pcm_generic.h +++ b/src/pcm/pcm_generic.h @@ -155,8 +155,8 @@ int snd_pcm_generic_real_htimestamp(snd_ snd_htimestamp_t *tstamp); int snd_pcm_generic_mmap(snd_pcm_t *pcm); int snd_pcm_generic_munmap(snd_pcm_t *pcm); -int **snd_pcm_generic_query_chmaps(snd_pcm_t *pcm); -int *snd_pcm_generic_get_chmap(snd_pcm_t *pcm); -int snd_pcm_generic_set_chmap(snd_pcm_t *pcm, const int *map); +snd_pcm_chmap_query_t **snd_pcm_generic_query_chmaps(snd_pcm_t *pcm); +snd_pcm_chmap_t *snd_pcm_generic_get_chmap(snd_pcm_t *pcm); +int snd_pcm_generic_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -1045,13 +1045,13 @@ static void chmap_caps_set_error(snd_pcm hw->chmap_caps |= (1 << (type + 8)); } -static int **snd_pcm_hw_query_chmaps(snd_pcm_t *pcm) +static snd_pcm_chmap_query_t **snd_pcm_hw_query_chmaps(snd_pcm_t *pcm) { snd_pcm_hw_t *hw = pcm->private_data; snd_ctl_t *ctl; snd_ctl_elem_id_t *id; unsigned int tlv[256], *start; - int **map; + snd_pcm_chmap_query_t **map; int i, ret, nums; if (!chmap_caps(hw, CHMAP_CTL_QUERY)) @@ -1108,9 +1108,9 @@ static int **snd_pcm_hw_query_chmaps(snd snd_pcm_free_chmaps(map); return NULL; } - map[i][0] = start[0] - 0x100; - map[i][1] = start[1] / 4; - memcpy(map[i] + 2, start + 2, start[1]); + map[i]->type = start[0] - 0x100; + map[i]->map.channels = start[1] / 4; + memcpy(map[i]->map.pos, start + 2, start[1]); start += start[1] / 4 + 2; } chmap_caps_set_ok(hw, CHMAP_CTL_QUERY); @@ -1121,10 +1121,10 @@ static int **snd_pcm_hw_query_chmaps(snd return NULL; } -static int *snd_pcm_hw_get_chmap(snd_pcm_t *pcm) +static snd_pcm_chmap_t *snd_pcm_hw_get_chmap(snd_pcm_t *pcm) { snd_pcm_hw_t *hw = pcm->private_data; - int *map; + snd_pcm_chmap_t *map; snd_ctl_t *ctl; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *val; @@ -1150,7 +1150,7 @@ static int *snd_pcm_hw_get_chmap(snd_pcm map = malloc(pcm->channels + 1); if (!map) return NULL; - *map = pcm->channels; + map->channels = pcm->channels; ret = snd_ctl_hw_open(&ctl, NULL, hw->card, 0); if (ret < 0) { free(map); @@ -1171,24 +1171,25 @@ static int *snd_pcm_hw_get_chmap(snd_pcm return NULL; } for (i = 0; i < pcm->channels; i++) - map[i + 1] = snd_ctl_elem_value_get_integer(val, i); + map->pos[i] = snd_ctl_elem_value_get_integer(val, i); chmap_caps_set_ok(hw, CHMAP_CTL_GET); return map; } -static int snd_pcm_hw_set_chmap(snd_pcm_t *pcm, const int *map) +static int snd_pcm_hw_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map) { snd_pcm_hw_t *hw = pcm->private_data; snd_ctl_t *ctl; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *val; - int i, ret; + unsigned int i; + int ret; if (!chmap_caps(hw, CHMAP_CTL_SET)) return -ENXIO; - if (*map < 0 || *map > 128) { - SYSMSG("Invalid number of channels %d\n", *map); + if (map->channels > 128) { + SYSMSG("Invalid number of channels %d\n", map->channels); return -EINVAL; } if (FAST_PCM_STATE(hw) != SNDRV_PCM_STATE_PREPARED) { @@ -1206,8 +1207,8 @@ static int snd_pcm_hw_set_chmap(snd_pcm_ snd_ctl_elem_value_alloca(&val); fill_chmap_ctl_id(pcm, id); snd_ctl_elem_value_set_id(val, id); - for (i = 0; i < *map; i++) - snd_ctl_elem_value_set_integer(val, i, map[i + 1]); + for (i = 0; i < map->channels; i++) + snd_ctl_elem_value_set_integer(val, i, map->pos[i]); ret = snd_ctl_elem_write(ctl, val); snd_ctl_close(ctl); if (ret >= 0) --- a/src/pcm/pcm_ioplug.c +++ b/src/pcm/pcm_ioplug.c @@ -710,7 +710,7 @@ static int snd_pcm_ioplug_munmap(snd_pcm return 0; } -static int **snd_pcm_ioplug_query_chmaps(snd_pcm_t *pcm) +static snd_pcm_chmap_query_t **snd_pcm_ioplug_query_chmaps(snd_pcm_t *pcm) { ioplug_priv_t *io = pcm->private_data; @@ -720,7 +720,7 @@ static int **snd_pcm_ioplug_query_chmaps return NULL; } -static int *snd_pcm_ioplug_get_chmap(snd_pcm_t *pcm) +static snd_pcm_chmap_t *snd_pcm_ioplug_get_chmap(snd_pcm_t *pcm) { ioplug_priv_t *io = pcm->private_data; @@ -730,7 +730,7 @@ static int *snd_pcm_ioplug_get_chmap(snd return NULL; } -static int snd_pcm_ioplug_set_chmap(snd_pcm_t *pcm, const int *map) +static int snd_pcm_ioplug_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map) { ioplug_priv_t *io = pcm->private_data; --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -143,9 +143,9 @@ typedef struct { void (*dump)(snd_pcm_t *pcm, snd_output_t *out); int (*mmap)(snd_pcm_t *pcm); int (*munmap)(snd_pcm_t *pcm); - int **(*query_chmaps)(snd_pcm_t *pcm); - int *(*get_chmap)(snd_pcm_t *pcm); - int (*set_chmap)(snd_pcm_t *pcm, const int *map); + snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_t *pcm); + snd_pcm_chmap_t *(*get_chmap)(snd_pcm_t *pcm); + int (*set_chmap)(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); } snd_pcm_ops_t; typedef struct { --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -739,10 +739,10 @@ static int snd_pcm_multi_mmap(snd_pcm_t return 0; } -static int *snd_pcm_multi_get_chmap(snd_pcm_t *pcm) +static snd_pcm_chmap_t *snd_pcm_multi_get_chmap(snd_pcm_t *pcm) { snd_pcm_multi_t *multi = pcm->private_data; - int *map; + snd_pcm_chmap_t *map; unsigned int i, idx; map = malloc(pcm->channels + 4); @@ -750,34 +750,37 @@ static int *snd_pcm_multi_get_chmap(snd_ return NULL; idx = 0; for (i = 0; i < multi->slaves_count; ++i) { - int c, *slave_map; + unsigned int c; + snd_pcm_chmap_t *slave_map; slave_map = snd_pcm_get_chmap(multi->slaves[i].pcm); if (!slave_map) { free(map); return NULL; } - for (c = 0; c < *slave_map; c++) { + for (c = 0; c < slave_map->channels; c++) { if (idx >= pcm->channels) break; - map[idx++] = slave_map[c + 1]; + map->pos[idx++] = slave_map->pos[c]; } free(slave_map); } return map; } -static int snd_pcm_multi_set_chmap(snd_pcm_t *pcm, const int *map) +static int snd_pcm_multi_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map) { snd_pcm_multi_t *multi = pcm->private_data; + const unsigned int *pos; unsigned int i, idx, chs; int err; - chs = *map; + chs = map->channels; if (chs != pcm->channels) return -EINVAL; - map++; + pos = map->pos; + idx = 0; for (i = 0; i < multi->slaves_count; ++i) { - int *slave_map; + snd_pcm_chmap_t *slave_map; unsigned int slave_chs; slave_chs = multi->slaves[i].channels_count; if (idx + slave_chs > chs) @@ -785,8 +788,8 @@ static int snd_pcm_multi_set_chmap(snd_p slave_map = malloc(slave_chs * 4 + 4); if (!slave_map) return -ENOMEM; - *slave_map = slave_chs; - memcpy(slave_map, map + idx, slave_chs * 4); + slave_map->channels = slave_chs; + memcpy(slave_map->pos, pos + idx, slave_chs * 4); err = snd_pcm_set_chmap(multi->slaves[i].pcm, slave_map); free(slave_map); if (err < 0) --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -703,10 +703,10 @@ snd_pcm_route_read_areas(snd_pcm_t *pcm, return size; } -static int *snd_pcm_route_get_chmap(snd_pcm_t *pcm) +static snd_pcm_chmap_t *snd_pcm_route_get_chmap(snd_pcm_t *pcm) { snd_pcm_route_t *route = pcm->private_data; - int *map, *slave_map; + snd_pcm_chmap_t *map, *slave_map; unsigned int src, dst; slave_map = snd_pcm_generic_get_chmap(pcm); @@ -717,13 +717,13 @@ static int *snd_pcm_route_get_chmap(snd_ free(slave_map); return NULL; } - *map = route->schannels; + map->channels = route->schannels; for (dst = 0; dst < route->params.ndsts; dst++) { snd_pcm_route_ttable_dst_t *d = &route->params.dsts[dst]; for (src = 0; src < d->nsrcs; src++) { int c = d->srcs[src].channel; - if (c < route->schannels && !map[c + 1]) - map[c + 1] = slave_map[dst + 1]; + if (c < route->schannels && !map->pos[c]) + map->pos[c] = slave_map->pos[dst]; } } free(slave_map); --- a/test/chmap.c +++ b/test/chmap.c @@ -31,13 +31,14 @@ static const char * const chname[] = { #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -static void print_channels(int channels, int *map) +static void print_channels(const snd_pcm_chmap_t *map) { - int i; + unsigned int i; + printf(" "); - for (i = 0; i < channels; i++) { - unsigned int c = *map++; - unsigned int pos = c & SND_CHMAP_POSITION_MASK; + for (i = 0; i < map->channels; i++) { + unsigned int c = map->pos[i]; + unsigned int p = c & SND_CHMAP_POSITION_MASK; if (c & SND_CHMAP_DRIVER_SPEC) printf(" %d", p); else if (p >= ARRAY_SIZE(chname)) @@ -80,16 +81,16 @@ static const char *chmap_type(int type) static int query_chmaps(snd_pcm_t *pcm) { - int **maps = snd_pcm_query_chmaps(pcm); - int **p, *v; + snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps(pcm); + snd_pcm_chmap_query_t **p, *v; if (!maps) { printf("Cannot query maps\n"); return 1; } for (p = maps; (v = *p) != NULL; p++) { - printf("Type = %s, Channels = %d\n", chmap_type(v[0]), v[1]); - print_channels(v[1], v + 2); + printf("Type = %s, Channels = %d\n", chmap_type(v->type), v->map.channels); + print_channels(&v->map); } snd_pcm_free_chmaps(maps); return 0; @@ -132,7 +133,7 @@ static int setup_pcm(snd_pcm_t *pcm, int static int get_chmap(snd_pcm_t *pcm, int format, int channels, int rate) { - int *map; + snd_pcm_chmap_t *map; if (setup_pcm(pcm, format, channels, rate)) return 1; @@ -141,8 +142,8 @@ static int get_chmap(snd_pcm_t *pcm, int printf("Cannot get chmap\n"); return 1; } - printf("Channels = %d\n", *map); - print_channels(*map, map + 1); + printf("Channels = %d\n", map->channels); + print_channels(map); free(map); return 0; } @@ -151,7 +152,7 @@ static int set_chmap(snd_pcm_t *pcm, int int nargs, char **arg) { int i; - int *map; + snd_pcm_chmap_t *map; if (channels && channels != nargs) { printf("Inconsistent channels %d vs %d\n", channels, nargs); @@ -171,9 +172,9 @@ static int set_chmap(snd_pcm_t *pcm, int printf("cannot malloc\n"); return 1; } - *map = channels; + map->channels = channels; for (i = 0; i < channels; i++) - map[i + 1] = to_channel(arg[i]); + map->pos[i] = to_channel(arg[i]); if (snd_pcm_set_chmap(pcm, map) < 0) { printf("Cannot set chmap\n"); return 1; @@ -185,8 +186,8 @@ static int set_chmap(snd_pcm_t *pcm, int printf("Cannot get chmap\n"); return 1; } - printf("Get channels = %d\n", *map); - print_channels(*map, map + 1); + printf("Get channels = %d\n", map->channels); + print_channels(map); free(map); return 0; }