- Backport recent upstream fixes: topology API fix, UCM fixes/improvements, config fixes, chmap support in route plugin, timestamp type fix for dmix: 0006-topology-add-back-asrc-to-widget_map-in-dapm.c.patch 0007-ucm-clarify-the-index-syntax-for-the-device-names.patch 0008-ucm-fix-uc_mgr_scan_master_configs.patch 0009-namehint-remember-the-direction-from-the-upper-level.patch 0010-conf-fix-namehint-for-pcm.front-and-pcm.iec958.patch 0011-pcm-add-chmap-option-to-route-plugin.patch 0012-usecase-allow-indexes-also-for-modifier-names.patch 0013-ucm-fix-the-device-remove-operation.patch 0014-ucm-fix-copy-n-paste-typo-RemoveDevice-list.patch 0015-pcm-dmix-fix-sw_params-handling-of-timestamp-types-i.patch 0016-conf-USB-Audio-Fix-S-PDIF-output-of-ASUS-Xonar-AE.patch OBS-URL: https://build.opensuse.org/request/show/796086 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=271
217 lines
6.2 KiB
Diff
217 lines
6.2 KiB
Diff
From 3b46b03f099da2f39c205a25b3cc62ec688fe6b3 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Holmberg <jonashg@axis.com>
|
|
Date: Tue, 31 Mar 2020 17:09:25 +0200
|
|
Subject: [PATCH 11/16] pcm: add chmap option to route plugin
|
|
|
|
Add a config definition "chmap" to override the channel maps in the same
|
|
way as in the hw and null plugins.
|
|
|
|
Signed-off-by: Jonas Holmberg <jonashg@axis.com>
|
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
|
---
|
|
src/pcm/pcm_route.c | 57 +++++++++++++++++++++++++++++++++++++++++++----------
|
|
1 file changed, 47 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
|
|
index bbcc6118b593..d3e5f3ff1f15 100644
|
|
--- a/src/pcm/pcm_route.c
|
|
+++ b/src/pcm/pcm_route.c
|
|
@@ -104,6 +104,7 @@ typedef struct {
|
|
int schannels;
|
|
snd_pcm_route_params_t params;
|
|
snd_pcm_chmap_t *chmap;
|
|
+ snd_pcm_chmap_query_t **chmap_override;
|
|
} snd_pcm_route_t;
|
|
|
|
#endif /* DOC_HIDDEN */
|
|
@@ -441,6 +442,7 @@ static int snd_pcm_route_close(snd_pcm_t *pcm)
|
|
free(params->dsts);
|
|
}
|
|
free(route->chmap);
|
|
+ snd_pcm_free_chmaps(route->chmap_override);
|
|
return snd_pcm_generic_close(pcm);
|
|
}
|
|
|
|
@@ -634,6 +636,9 @@ static snd_pcm_chmap_t *snd_pcm_route_get_chmap(snd_pcm_t *pcm)
|
|
snd_pcm_chmap_t *map, *slave_map;
|
|
unsigned int src, dst, nsrcs;
|
|
|
|
+ if (route->chmap_override)
|
|
+ return _snd_pcm_choose_fixed_chmap(pcm, route->chmap_override);
|
|
+
|
|
slave_map = snd_pcm_generic_get_chmap(pcm);
|
|
if (!slave_map)
|
|
return NULL;
|
|
@@ -660,8 +665,14 @@ static snd_pcm_chmap_t *snd_pcm_route_get_chmap(snd_pcm_t *pcm)
|
|
|
|
static snd_pcm_chmap_query_t **snd_pcm_route_query_chmaps(snd_pcm_t *pcm)
|
|
{
|
|
+ snd_pcm_route_t *route = pcm->private_data;
|
|
snd_pcm_chmap_query_t **maps;
|
|
- snd_pcm_chmap_t *map = snd_pcm_route_get_chmap(pcm);
|
|
+ snd_pcm_chmap_t *map;
|
|
+
|
|
+ if (route->chmap_override)
|
|
+ return _snd_pcm_copy_chmap_query(route->chmap_override);
|
|
+
|
|
+ map = snd_pcm_route_get_chmap(pcm);
|
|
if (!map)
|
|
return NULL;
|
|
maps = _snd_pcm_make_single_query_chmaps(map);
|
|
@@ -818,10 +829,10 @@ err:
|
|
return -EINVAL;
|
|
}
|
|
|
|
-static int find_matching_chmap(snd_pcm_t *spcm, snd_pcm_chmap_t *tt_chmap,
|
|
+static int find_matching_chmap(snd_pcm_chmap_query_t **chmaps,
|
|
+ snd_pcm_chmap_t *tt_chmap,
|
|
snd_pcm_chmap_t **found_chmap, int *schannels)
|
|
{
|
|
- snd_pcm_chmap_query_t** chmaps = snd_pcm_query_chmaps(spcm);
|
|
int i;
|
|
|
|
*found_chmap = NULL;
|
|
@@ -854,7 +865,6 @@ static int find_matching_chmap(snd_pcm_t *spcm, snd_pcm_chmap_t *tt_chmap,
|
|
int size = sizeof(snd_pcm_chmap_t) + c->channels * sizeof(unsigned int);
|
|
*found_chmap = malloc(size);
|
|
if (!*found_chmap) {
|
|
- snd_pcm_free_chmaps(chmaps);
|
|
return -ENOMEM;
|
|
}
|
|
memcpy(*found_chmap, c, size);
|
|
@@ -863,8 +873,6 @@ static int find_matching_chmap(snd_pcm_t *spcm, snd_pcm_chmap_t *tt_chmap,
|
|
}
|
|
}
|
|
|
|
- snd_pcm_free_chmaps(chmaps);
|
|
-
|
|
if (*found_chmap == NULL) {
|
|
SNDERR("Found no matching channel map");
|
|
return -EINVAL;
|
|
@@ -1252,6 +1260,7 @@ pcm.name {
|
|
SCHANNEL REAL # route value (0.0 - 1.0)
|
|
}
|
|
}
|
|
+ [chmap MAP] # Override channel maps; MAP is a string array
|
|
}
|
|
\endcode
|
|
|
|
@@ -1292,6 +1301,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
|
|
snd_pcm_route_ttable_entry_t *ttable = NULL;
|
|
unsigned int csize, ssize;
|
|
unsigned int cused, sused;
|
|
+ snd_pcm_chmap_query_t **chmaps = NULL;
|
|
snd_config_for_each(i, next, conf) {
|
|
snd_config_t *n = snd_config_iterator_entry(i);
|
|
const char *id;
|
|
@@ -1306,31 +1316,45 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
|
|
if (strcmp(id, "ttable") == 0) {
|
|
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
|
|
SNDERR("Invalid type for %s", id);
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
return -EINVAL;
|
|
}
|
|
tt = n;
|
|
continue;
|
|
}
|
|
+ if (strcmp(id, "chmap") == 0) {
|
|
+ chmaps = _snd_pcm_parse_config_chmaps(n);
|
|
+ if (!chmaps) {
|
|
+ SNDERR("Invalid channel map for %s", id);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
SNDERR("Unknown field %s", id);
|
|
return -EINVAL;
|
|
}
|
|
if (!slave) {
|
|
SNDERR("slave is not defined");
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
return -EINVAL;
|
|
}
|
|
if (!tt) {
|
|
SNDERR("ttable is not defined");
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
return -EINVAL;
|
|
}
|
|
err = snd_pcm_slave_conf(root, slave, &sconf, 2,
|
|
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
|
|
SND_PCM_HW_PARAM_CHANNELS, 0, &schannels);
|
|
- if (err < 0)
|
|
+ if (err < 0) {
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
return err;
|
|
+ }
|
|
if (sformat != SND_PCM_FORMAT_UNKNOWN &&
|
|
snd_pcm_format_linear(sformat) != 1) {
|
|
snd_config_delete(sconf);
|
|
SNDERR("slave format is not linear");
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -1345,13 +1369,19 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
|
|
if (err < 0) {
|
|
free(tt_chmap);
|
|
free(ttable);
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
return err;
|
|
}
|
|
|
|
if (tt_chmap) {
|
|
- err = find_matching_chmap(spcm, tt_chmap, &chmap, &schannels);
|
|
+ if (!chmaps)
|
|
+ chmaps = snd_pcm_query_chmaps(spcm);
|
|
+ if (chmaps)
|
|
+ err = find_matching_chmap(chmaps, tt_chmap, &chmap,
|
|
+ &schannels);
|
|
free(tt_chmap);
|
|
- if (err < 0) {
|
|
+ if (chmaps && err < 0) {
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
snd_pcm_close(spcm);
|
|
return err;
|
|
}
|
|
@@ -1360,12 +1390,14 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
|
|
err = _snd_pcm_route_determine_ttable(tt, &csize, &ssize, chmap);
|
|
if (err < 0) {
|
|
free(chmap);
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
snd_pcm_close(spcm);
|
|
return err;
|
|
}
|
|
ttable = malloc(csize * ssize * sizeof(snd_pcm_route_ttable_entry_t));
|
|
if (ttable == NULL) {
|
|
free(chmap);
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
snd_pcm_close(spcm);
|
|
return -ENOMEM;
|
|
}
|
|
@@ -1374,6 +1406,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
|
|
if (err < 0) {
|
|
free(chmap);
|
|
free(ttable);
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
snd_pcm_close(spcm);
|
|
return err;
|
|
}
|
|
@@ -1385,9 +1418,13 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
|
|
free(ttable);
|
|
if (err < 0) {
|
|
free(chmap);
|
|
+ snd_pcm_free_chmaps(chmaps);
|
|
snd_pcm_close(spcm);
|
|
} else {
|
|
- ((snd_pcm_route_t*) (*pcmp)->private_data)->chmap = chmap;
|
|
+ snd_pcm_route_t *route = (*pcmp)->private_data;
|
|
+
|
|
+ route->chmap = chmap;
|
|
+ route->chmap_override = chmaps;
|
|
}
|
|
|
|
return err;
|
|
--
|
|
2.16.4
|
|
|