1diff --git a/src/control/control.c b/src/control/control.c
2index d66ed75..42cecad 100644
3--- a/src/control/control.c
4+++ b/src/control/control.c
5@@ -838,6 +838,10 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
6 #ifndef PIC
7 extern void *snd_control_open_symbols(void);
8 #endif
9+
10+ snd_config_t *libs = NULL;
11+ const char *libs_lib = NULL;
12+
13 if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
14 if (name)
15 SNDERR("Invalid type for CTL %s definition", name);
16@@ -879,6 +883,19 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
17 SNDERR("Invalid type for %s", id);
18 goto _err;
19 }
20+
21+ continue;
22+ }
23+ // Handle an array of extra libs.
24+ if (strcmp(id, "libs") == 0) {
25+ if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
26+ SNDERR("Invalid type for libs definition in CTL %s definition",
27+ str);
28+ goto _err;
29+ }
30+
31+ libs = n;
32+
33 continue;
34 }
35 if (strcmp(id, "open") == 0) {
36@@ -903,7 +920,62 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
37 open_name = buf;
38 sprintf(buf, "_snd_ctl_%s_open", str);
39 }
40- if (!lib) {
41+
42+#ifndef PIC
43+ snd_control_open_symbols();
44+#endif
45+
46+ // Normal alsa behaviour when there is no libs array.
47+ if (!libs) {
48+ if (lib) {
49+ open_func = snd_dlobj_cache_get(lib, open_name,
50+ SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
51+ }
52+ }
53+ // Handle libs array.
54+ // Suppresses error messages if any function is loaded successfully.
55+ else {
56+ if (lib) {
57+ open_func = snd_dlobj_cache_get(lib, open_name,
58+ SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
59+ }
60+
61+ if (!open_func) {
62+ snd_config_for_each(i, next, libs) {
63+ snd_config_t *n = snd_config_iterator_entry(i);
64+
65+ err = snd_config_get_string(n, &libs_lib);
66+ if (err < 0) {
67+ SNDERR("Invalid entry in CTL %s libs definition", str);
68+ goto _err;
69+ }
70+
71+ if (!open_func) {
72+ open_func = snd_dlobj_cache_get(libs_lib, open_name,
73+ SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
74+ }
75+ }
76+ }
77+
78+ // Print error messages.
79+ if (!open_func) {
80+ if (lib) {
81+ SNDERR("Either %s cannot be opened or %s was not defined inside",
82+ lib, open_name);
83+ }
84+
85+ snd_config_for_each(i, next, libs) {
86+ snd_config_t *n = snd_config_iterator_entry(i);
87+
88+ snd_config_get_string(n, &libs_lib);
89+ SNDERR("Either %s cannot be opened or %s was not defined inside",
90+ libs_lib, open_name);
91+ }
92+ }
93+ }
94+
95+ // Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
96+ if (!lib && (!libs || !libs_lib)) {
97 const char *const *build_in = build_in_ctls;
98 while (*build_in) {
99 if (!strcmp(*build_in, str))
100@@ -919,12 +991,11 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
101 lib = buf1;
102 sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
103 }
104- }
105-#ifndef PIC
106- snd_control_open_symbols();
107-#endif
108- open_func = snd_dlobj_cache_get(lib, open_name,
109+
110+ open_func = snd_dlobj_cache_get(lib, open_name,
111 SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
112+ }
113+
114 if (open_func) {
115 err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
116 if (err >= 0) {
117diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
118index 2e24338..7f489f4 100644
119--- a/src/pcm/pcm.c
120+++ b/src/pcm/pcm.c
121@@ -2116,6 +2116,10 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
122 #ifndef PIC
123 extern void *snd_pcm_open_symbols(void);
124 #endif
125+
126+ snd_config_t *libs = NULL;
127+ const char *libs_lib = NULL;
128+
129 if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
130 char *val;
131 id = NULL;
132@@ -2160,6 +2164,19 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
133 SNDERR("Invalid type for %s", id);
134 goto _err;
135 }
136+
137+ continue;
138+ }
139+ // Handle an array of extra libs.
140+ if (strcmp(id, "libs") == 0) {
141+ if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
142+ SNDERR("Invalid type for libs definition in PCM %s definition",
143+ str);
144+ goto _err;
145+ }
146+
147+ libs = n;
148+
149 continue;
150 }
151 if (strcmp(id, "open") == 0) {
152@@ -2184,7 +2201,62 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
153 open_name = buf;
154 sprintf(buf, "_snd_pcm_%s_open", str);
155 }
156- if (!lib) {
157+
158+#ifndef PIC
159+ snd_pcm_open_symbols(); /* this call is for static linking only */
160+#endif
161+
162+ // Normal alsa behaviour when there is no libs array.
163+ if (!libs) {
164+ if (lib) {
165+ open_func = snd_dlobj_cache_get(lib, open_name,
166+ SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
167+ }
168+ }
169+ // Handle libs array.
170+ // Suppresses error messages if any function is loaded successfully.
171+ else {
172+ if (lib) {
173+ open_func = snd_dlobj_cache_get(lib, open_name,
174+ SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
175+ }
176+
177+ if (!open_func) {
178+ snd_config_for_each(i, next, libs) {
179+ snd_config_t *n = snd_config_iterator_entry(i);
180+
181+ err = snd_config_get_string(n, &libs_lib);
182+ if (err < 0) {
183+ SNDERR("Invalid entry in PCM %s libs definition", str);
184+ goto _err;
185+ }
186+
187+ if (!open_func) {
188+ open_func = snd_dlobj_cache_get(libs_lib, open_name,
189+ SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
190+ }
191+ }
192+ }
193+
194+ // Print error messages.
195+ if (!open_func) {
196+ if (lib) {
197+ SNDERR("Either %s cannot be opened or %s was not defined inside",
198+ lib, open_name);
199+ }
200+
201+ snd_config_for_each(i, next, libs) {
202+ snd_config_t *n = snd_config_iterator_entry(i);
203+
204+ snd_config_get_string(n, &libs_lib);
205+ SNDERR("Either %s cannot be opened or %s was not defined inside",
206+ libs_lib, open_name);
207+ }
208+ }
209+ }
210+
211+ // Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
212+ if (!lib && (!libs || !libs_lib)) {
213 const char *const *build_in = build_in_pcms;
214 while (*build_in) {
215 if (!strcmp(*build_in, str))
216@@ -2200,12 +2272,11 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
217 lib = buf1;
218 sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
219 }
220- }
221-#ifndef PIC
222- snd_pcm_open_symbols(); /* this call is for static linking only */
223-#endif
224- open_func = snd_dlobj_cache_get(lib, open_name,
225+
226+ open_func = snd_dlobj_cache_get(lib, open_name,
227 SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
228+ }
229+
230 if (open_func) {
231 err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
232 if (err >= 0) {