summary refs log tree commit diff
path: root/pkgs/os-specific/linux/alsa-project/alsa-lib
diff options
context:
space:
mode:
authorivanbrennan <ivan.brennan@gmail.com>2022-01-29 12:51:54 -0500
committerivanbrennan <ivan.brennan@gmail.com>2022-01-31 20:12:59 -0500
commit3b139b96c54e56f9ac7b3b49fc650867391bb665 (patch)
treedcfb2e40e15163383f39f02482ee46916f4d8aaf /pkgs/os-specific/linux/alsa-project/alsa-lib
parent016e9e5a7f9d6f0f0e4284aeaa982850ed6c921a (diff)
downloadnixpkgs-3b139b96c54e56f9ac7b3b49fc650867391bb665.tar
nixpkgs-3b139b96c54e56f9ac7b3b49fc650867391bb665.tar.gz
nixpkgs-3b139b96c54e56f9ac7b3b49fc650867391bb665.tar.bz2
nixpkgs-3b139b96c54e56f9ac7b3b49fc650867391bb665.tar.lz
nixpkgs-3b139b96c54e56f9ac7b3b49fc650867391bb665.tar.xz
nixpkgs-3b139b96c54e56f9ac7b3b49fc650867391bb665.tar.zst
nixpkgs-3b139b96c54e56f9ac7b3b49fc650867391bb665.zip
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.
Diffstat (limited to 'pkgs/os-specific/linux/alsa-project/alsa-lib')
-rw-r--r--pkgs/os-specific/linux/alsa-project/alsa-lib/alsa-plugin-conf-multilib.patch232
-rw-r--r--pkgs/os-specific/linux/alsa-project/alsa-lib/default.nix4
2 files changed, 236 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/alsa-project/alsa-lib/alsa-plugin-conf-multilib.patch b/pkgs/os-specific/linux/alsa-project/alsa-lib/alsa-plugin-conf-multilib.patch
new file mode 100644
index 00000000000..b17df9a492e
--- /dev/null
+++ b/pkgs/os-specific/linux/alsa-project/alsa-lib/alsa-plugin-conf-multilib.patch
@@ -0,0 +1,232 @@
+diff --git a/src/control/control.c b/src/control/control.c
+index d66ed75..42cecad 100644
+--- a/src/control/control.c
++++ b/src/control/control.c
+@@ -838,6 +838,10 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ #ifndef PIC
+ 	extern void *snd_control_open_symbols(void);
+ #endif
++
++	snd_config_t *libs = NULL;
++	const char *libs_lib = NULL;
++
+ 	if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
+ 		if (name)
+ 			SNDERR("Invalid type for CTL %s definition", name);
+@@ -879,6 +883,19 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ 					SNDERR("Invalid type for %s", id);
+ 					goto _err;
+ 				}
++
++				continue;
++			}
++			// Handle an array of extra libs.
++			if (strcmp(id, "libs") == 0) {
++				if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
++					SNDERR("Invalid type for libs definition in CTL %s definition",
++						str);
++					goto _err;
++				}
++
++				libs = n;
++
+ 				continue;
+ 			}
+ 			if (strcmp(id, "open") == 0) {
+@@ -903,7 +920,62 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ 		open_name = buf;
+ 		sprintf(buf, "_snd_ctl_%s_open", str);
+ 	}
+-	if (!lib) {
++
++#ifndef PIC
++	snd_control_open_symbols();
++#endif
++
++	// Normal alsa behaviour when there is no libs array.
++	if (!libs) {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
++		}
++	}
++	// Handle libs array.
++	// Suppresses error messages if any function is loaded successfully.
++	else {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
++		}
++
++		if (!open_func) {
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				err = snd_config_get_string(n, &libs_lib);
++				if (err < 0) {
++					SNDERR("Invalid entry in CTL %s libs definition", str);
++					goto _err;
++				}
++
++				if (!open_func) {
++					open_func = snd_dlobj_cache_get(libs_lib, open_name,
++						SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
++				}
++			}
++		}
++
++		// Print error messages.
++		if (!open_func) {
++			if (lib) {
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					lib, open_name);
++			}
++
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				snd_config_get_string(n, &libs_lib);
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					libs_lib, open_name);
++			}
++		}
++	}
++
++	// Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
++	if (!lib && (!libs || !libs_lib)) {
+ 		const char *const *build_in = build_in_ctls;
+ 		while (*build_in) {
+ 			if (!strcmp(*build_in, str))
+@@ -919,12 +991,11 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ 			lib = buf1;
+ 			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
+ 		}
+-	}
+-#ifndef PIC
+-	snd_control_open_symbols();
+-#endif
+-	open_func = snd_dlobj_cache_get(lib, open_name,
++
++		open_func = snd_dlobj_cache_get(lib, open_name,
+ 			SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
++	}
++
+ 	if (open_func) {
+ 		err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
+ 		if (err >= 0) {
+diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
+index 2e24338..7f489f4 100644
+--- a/src/pcm/pcm.c
++++ b/src/pcm/pcm.c
+@@ -2116,6 +2116,10 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ #ifndef PIC
+ 	extern void *snd_pcm_open_symbols(void);
+ #endif
++
++	snd_config_t *libs = NULL;
++	const char *libs_lib = NULL;
++
+ 	if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
+ 		char *val;
+ 		id = NULL;
+@@ -2160,6 +2164,19 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ 					SNDERR("Invalid type for %s", id);
+ 					goto _err;
+ 				}
++
++				continue;
++			}
++			// Handle an array of extra libs.
++			if (strcmp(id, "libs") == 0) {
++				if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
++					SNDERR("Invalid type for libs definition in PCM %s definition",
++						str);
++					goto _err;
++				}
++
++				libs = n;
++
+ 				continue;
+ 			}
+ 			if (strcmp(id, "open") == 0) {
+@@ -2184,7 +2201,62 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ 		open_name = buf;
+ 		sprintf(buf, "_snd_pcm_%s_open", str);
+ 	}
+-	if (!lib) {
++
++#ifndef PIC
++	snd_pcm_open_symbols();	/* this call is for static linking only */
++#endif
++
++	// Normal alsa behaviour when there is no libs array.
++	if (!libs) {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
++		}
++	}
++	// Handle libs array.
++	// Suppresses error messages if any function is loaded successfully.
++	else {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
++		}
++
++		if (!open_func) {
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				err = snd_config_get_string(n, &libs_lib);
++				if (err < 0) {
++					SNDERR("Invalid entry in PCM %s libs definition", str);
++					goto _err;
++				}
++
++				if (!open_func) {
++					open_func = snd_dlobj_cache_get(libs_lib, open_name,
++						SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
++				}
++			}
++		}
++
++		// Print error messages.
++		if (!open_func) {
++			if (lib) {
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					lib, open_name);
++			}
++
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				snd_config_get_string(n, &libs_lib);
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					libs_lib, open_name);
++			}
++		}
++	}
++
++	// Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
++	if (!lib && (!libs || !libs_lib)) {
+ 		const char *const *build_in = build_in_pcms;
+ 		while (*build_in) {
+ 			if (!strcmp(*build_in, str))
+@@ -2200,12 +2272,11 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ 			lib = buf1;
+ 			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
+ 		}
+-	}
+-#ifndef PIC
+-	snd_pcm_open_symbols();	/* this call is for static linking only */
+-#endif
+-	open_func = snd_dlobj_cache_get(lib, open_name,
++
++		open_func = snd_dlobj_cache_get(lib, open_name,
+ 			SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
++	}
++
+ 	if (open_func) {
+ 		err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
+ 		if (err >= 0) {
diff --git a/pkgs/os-specific/linux/alsa-project/alsa-lib/default.nix b/pkgs/os-specific/linux/alsa-project/alsa-lib/default.nix
index 445d171d31f..f2cc2b48a7e 100644
--- a/pkgs/os-specific/linux/alsa-project/alsa-lib/default.nix
+++ b/pkgs/os-specific/linux/alsa-project/alsa-lib/default.nix
@@ -14,6 +14,10 @@ stdenv.mkDerivation rec {
     hash = "sha256-rVgpk9Us21+xWaC+q2CmrFfqsMwb34XcTbbWGX8CMz8=";
   };
 
+  patches = [
+    ./alsa-plugin-conf-multilib.patch
+  ];
+
   enableParallelBuilding = true;
 
   postInstall = ''