alsa-lib: re-add alsa-plugin-conf-multilib.patch

This patch was originally added in 2014 to support running apps with
32bit sound on 64bit architecture.

The patch itself add a "libs" field to syntax recognized in /etc/asound.conf:
ab8ef63ff49dd6276f765cce10d88b3e5b86b837

The pulseaudio module then used the "libs" to declare locations for both native
and 32bit plugins:
0c8ad65560fa1df07ea7b7937e02b44b1ce2b498

In a recent alsa-lib upgrade (1.2.5.1 -> 1.2.6.1), the patch was removed
without understanding its purpose, leaving alsa-lib unable to parse the
etc/asound.conf that the pulseaudio module generated:
aeea1bb53b28fc7bbe4583bd21f5bda8b05d5041

As a result, ALSA utils are failing on x86_64 architecture if pulseaudio
is enabled. E.g.

$ alsactl monitor default
alsa-lib control.c:1464:(snd_ctl_open_conf) Unknown field libs
Cannot open ctl default

$ alsamixer
ALSA lib control.c:1464:(snd_ctl_open_conf) Unknown field libs
cannot open mixer: Invalid argument

$ speaker-test -t wav -c 2

speaker-test 1.2.6

Playback device is default
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
ALSA lib pcm.c:2576:(snd_pcm_open_conf) Unknown field libs
Playback open error: -22,Invalid argument

Put the patch back in place to fix what was broken.

+236
+232
pkgs/os-specific/linux/alsa-project/alsa-lib/alsa-plugin-conf-multilib.patch
··· 1 + diff --git a/src/control/control.c b/src/control/control.c 2 + index 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) { 117 + diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c 118 + index 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) {
+4
pkgs/os-specific/linux/alsa-project/alsa-lib/default.nix
··· 14 14 hash = "sha256-rVgpk9Us21+xWaC+q2CmrFfqsMwb34XcTbbWGX8CMz8="; 15 15 }; 16 16 17 + patches = [ 18 + ./alsa-plugin-conf-multilib.patch 19 + ]; 20 + 17 21 enableParallelBuilding = true; 18 22 19 23 postInstall = ''