mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
PCM: Use compounds for overriding / enhancing chmaps
Instead of a single channel map, multiple channel maps can be provided in a form of compound (array) to hw and null plugins. In null get_chmap, the channel map corresponding to the current channels is copied from the given channel maps. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
5ba11d69da
commit
ec7acfc408
7 changed files with 144 additions and 45 deletions
109
src/pcm/pcm.c
109
src/pcm/pcm.c
|
|
@ -7531,25 +7531,37 @@ snd_pcm_chmap_t *snd_pcm_chmap_parse_string(const char *str)
|
|||
return map;
|
||||
}
|
||||
|
||||
/* copy a single channel map with the fixed type to chmap_query pointer */
|
||||
static int _copy_to_fixed_query_map(snd_pcm_chmap_query_t **dst,
|
||||
const snd_pcm_chmap_t *src)
|
||||
{
|
||||
*dst = malloc((src->channels + 2) * sizeof(int));
|
||||
if (!*dst)
|
||||
return -ENOMEM;
|
||||
(*dst)->type = SND_CHMAP_TYPE_FIXED;
|
||||
memcpy(&(*dst)->map, src, (src->channels + 1) * sizeof(int));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
/* make a chmap_query array from a single channel map */
|
||||
snd_pcm_chmap_query_t **
|
||||
_snd_pcm_make_single_query_chmaps(snd_pcm_chmap_t *src)
|
||||
_snd_pcm_make_single_query_chmaps(const snd_pcm_chmap_t *src)
|
||||
{
|
||||
snd_pcm_chmap_query_t **maps;
|
||||
|
||||
maps = calloc(2, sizeof(*maps));
|
||||
if (!maps)
|
||||
return NULL;
|
||||
*maps = malloc((src->channels + 2) * sizeof(int));
|
||||
if (!*maps) {
|
||||
if (_copy_to_fixed_query_map(maps, src)) {
|
||||
free(maps);
|
||||
return NULL;
|
||||
}
|
||||
(*maps)->type = SND_CHMAP_TYPE_FIXED;
|
||||
memcpy(&(*maps)->map, src, (src->channels + 1) * sizeof(int));
|
||||
return maps;
|
||||
}
|
||||
|
||||
snd_pcm_chmap_t *_snd_pcm_copy_chmap(snd_pcm_chmap_t *src)
|
||||
/* make a copy of chmap */
|
||||
snd_pcm_chmap_t *_snd_pcm_copy_chmap(const snd_pcm_chmap_t *src)
|
||||
{
|
||||
snd_pcm_chmap_t *map;
|
||||
|
||||
|
|
@ -7560,6 +7572,91 @@ snd_pcm_chmap_t *_snd_pcm_copy_chmap(snd_pcm_chmap_t *src)
|
|||
return map;
|
||||
}
|
||||
|
||||
/* make a copy of channel maps */
|
||||
snd_pcm_chmap_query_t **
|
||||
_snd_pcm_copy_chmap_query(snd_pcm_chmap_query_t * const *src)
|
||||
{
|
||||
snd_pcm_chmap_query_t * const *p;
|
||||
snd_pcm_chmap_query_t **maps;
|
||||
int i, nums;
|
||||
|
||||
for (nums = 0, p = src; *p; p++)
|
||||
nums++;
|
||||
|
||||
maps = calloc(nums + 1, sizeof(*maps));
|
||||
if (!maps)
|
||||
return NULL;
|
||||
for (i = 0; i < nums; i++) {
|
||||
maps[i] = malloc((src[i]->map.channels + 2) * sizeof(int));
|
||||
if (!maps[i]) {
|
||||
snd_pcm_free_chmaps(maps);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(maps[i], src[i], (src[i]->map.channels + 2) * sizeof(int));
|
||||
}
|
||||
return maps;
|
||||
}
|
||||
|
||||
/* select the channel map with the current PCM channels and make a copy */
|
||||
snd_pcm_chmap_t *
|
||||
_snd_pcm_choose_fixed_chmap(snd_pcm_t *pcm, snd_pcm_chmap_query_t * const *maps)
|
||||
{
|
||||
snd_pcm_chmap_query_t * const *p;
|
||||
|
||||
for (p = maps; *p; p++) {
|
||||
if ((*p)->map.channels == pcm->channels)
|
||||
return _snd_pcm_copy_chmap(&(*p)->map);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make chmap_query array from the config tree;
|
||||
* conf must be a compound (array)
|
||||
*/
|
||||
snd_pcm_chmap_query_t **
|
||||
_snd_pcm_parse_config_chmaps(snd_config_t *conf)
|
||||
{
|
||||
snd_pcm_chmap_t *chmap;
|
||||
snd_pcm_chmap_query_t **maps;
|
||||
snd_config_iterator_t i, next;
|
||||
const char *str;
|
||||
int nums, err;
|
||||
|
||||
if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND)
|
||||
return NULL;
|
||||
|
||||
nums = 0;
|
||||
snd_config_for_each(i, next, conf) {
|
||||
nums++;
|
||||
}
|
||||
|
||||
maps = calloc(nums + 1, sizeof(*maps));
|
||||
if (!maps)
|
||||
return NULL;
|
||||
|
||||
nums = 0;
|
||||
snd_config_for_each(i, next, conf) {
|
||||
snd_config_t *n = snd_config_iterator_entry(i);
|
||||
err = snd_config_get_string(n, &str);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
chmap = snd_pcm_chmap_parse_string(str);
|
||||
if (!chmap)
|
||||
goto error;
|
||||
if (_copy_to_fixed_query_map(maps + nums, chmap)) {
|
||||
free(chmap);
|
||||
goto error;
|
||||
}
|
||||
nums++;
|
||||
}
|
||||
return maps;
|
||||
|
||||
error:
|
||||
snd_pcm_free_chmaps(maps);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* DOC_HIDDEN */
|
||||
|
||||
/*
|
||||
* basic helpers
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue