Subject: [bug#31239] Make alsa find its plugins

From: Julien Lepiller <[email-masked]>
Date: Sun, 22 Apr 2018 19:13:45 +0200

Hi, this patch adds an environment variable, ALSA_PLUGIN_DIR to allow
it to find its plugins. This is especially useful in GuixSD where
pulseaudio is used by most applications. When running an application
that only knows about alsa, no sound can be output because the card is
taken by pulse. One solution is to use the pulseaudio plugin from
alsa-plugins:pulseaudio and setting ~/.asoundrc:

# Default to PulseAudio
pcm.!default {
    type pulse
    hint {
        show on
        description "Default ALSA Output (currently PulseAudio Sound
Server)" }
}
ctl.!default {
    type pulse
}

But this results in an error because alsa will look for plugins in its
own output directory in the store. With this patch, alsa is able to
find its plugins in ALSA_PLUGIN_DIR after exporting it (export
ALSA_PLUGIN_DIR=$HOME/.guix-profile/lib/alsa-lib).
>From 83602af1382c6cfed7824e7931fc54bf66d688e0 Mon Sep 17 00:00:00 2001
From: Julien Lepiller <[email-masked]>
Date: Sun, 22 Apr 2018 19:05:30 +0200
Subject: [PATCH] gnu: Make alsa find its plugins by setting ALSA_PLUGIN_DIR.

* gnu/packages/patches/alsa-lib-add-environment-variable.patch: New
file.
* gnu/packages/linux.scm (alsa-lib)[source]: Use it.
[native-search-paths]: Add ALSA_PLUGIN_DIR.
* gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                                  |   1 +
 gnu/packages/linux.scm                        |   9 +-
 .../alsa-lib-add-environment-variable.patch   | 506 ++++++++++++++++++
 3 files changed, 515 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/alsa-lib-add-environment-variable.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 056a46cb7..efbf36ac3 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -557,6 +557,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/aegis-test-fixup-1.patch            	\
   %D%/packages/patches/aegis-test-fixup-2.patch            	\
   %D%/packages/patches/agg-am_c_prototype.patch			\
+  %D%/packages/patches/alas-lib-add-environment-variable.patch	\
   %D%/packages/patches/ansible-wrap-program-hack.patch		\
   %D%/packages/patches/antiword-CVE-2014-8123.patch			\
   %D%/packages/patches/antlr3-3_1-fix-java8-compilation.patch	\
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index 1d9585e7f..75a8db04e 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -1002,8 +1002,15 @@ intercept and print the system calls executed by the program.")
                    version ".tar.bz2"))
              (sha256
               (base32
-               "1rhacnlj0grvfagjx5qzsnbhw7m7lyccghqs4jsv0dnsqv9qmxpl"))))
+               "1rhacnlj0grvfagjx5qzsnbhw7m7lyccghqs4jsv0dnsqv9qmxpl"))
+             (patches (search-patches "alsa-lib-add-environment-variable.patch"))))
     (build-system gnu-build-system)
+    (native-search-paths
+     (list (search-path-specification
+             (variable "ALSA_PLUGIN_DIR")
+             (file-type 'regular)
+             (separator #f)                         ;single entry
+             (files '("lib/alsa-lib")))))
     (home-page "https://www.alsa-project.org/")
     (synopsis "The Advanced Linux Sound Architecture libraries")
     (description
diff --git a/gnu/packages/patches/alsa-lib-add-environment-variable.patch b/gnu/packages/patches/alsa-lib-add-environment-variable.patch
new file mode 100644
index 000000000..d3e1b2859
--- /dev/null
+++ b/gnu/packages/patches/alsa-lib-add-environment-variable.patch
@@ -0,0 +1,506 @@
+From ef87a17bd2a55dd3247a6ee0a463f3589fc01f08 Mon Sep 17 00:00:00 2001
+From: Julien Lepiller <[email-masked]>
+Date: Sun, 22 Apr 2018 16:28:38 +0200
+Subject: [PATCH] Add support for a ALSA_PLUGIN_DIR environment variable.
+
+If it is not set, default to previous behavior.
+---
+ ...a-ALSA_PLUGIN_DIR-environment-variab.patch | 378 ++++++++++++++++++
+ src/control/control.c                         |   8 +-
+ src/dlmisc.c                                  |  13 +-
+ src/pcm/pcm.c                                 |   8 +-
+ src/pcm/pcm_rate.c                            |  13 +-
+ 5 files changed, 409 insertions(+), 11 deletions(-)
+ create mode 100644 0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
+
+diff --git a/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch b/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
+new file mode 100644
+index 0000000..7aa6891
+--- /dev/null
++++ b/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
+@@ -0,0 +1,378 @@
++From 54530c486c9cbf48cbb591d3428075cee9678314 Mon Sep 17 00:00:00 2001
++From: Julien Lepiller <[email-masked]>
++Date: Sun, 22 Apr 2018 16:28:38 +0200
++Subject: [PATCH] Add support for a ALSA_PLUGIN_DIR environment variable.
++
++If it is not set, default to previous behavior.
++---
++ ...a-ALSA_PLUGIN_DIR-environment-variab.patch | 249 ++++++++++++++++++
++ src/control/control.c                         |   8 +-
++ src/dlmisc.c                                  |  14 +-
++ src/pcm/pcm.c                                 |   8 +-
++ src/pcm/pcm_rate.c                            |  13 +-
++ 5 files changed, 281 insertions(+), 11 deletions(-)
++ create mode 100644 0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
++
++diff --git a/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch b/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
++new file mode 100644
++index 0000000..e98acc7
++--- /dev/null
+++++ b/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
++@@ -0,0 +1,249 @@
+++From f00f0a2e8b9b56114eb6d168d5a22d84a61ecf22 Mon Sep 17 00:00:00 2001
+++From: Julien Lepiller <[email-masked]>
+++Date: Sun, 22 Apr 2018 16:28:38 +0200
+++Subject: [PATCH] Add support for a ALSA_PLUGIN_DIR environment variable.
+++
+++If it is not set, default to previous behavior.
+++---
+++ ...a-ALSA_PLUGIN_DIR-environment-variab.patch | 120 ++++++++++++++++++
+++ src/control/control.c                         |   8 +-
+++ src/dlmisc.c                                  |  14 +-
+++ src/pcm/pcm.c                                 |   8 +-
+++ src/pcm/pcm_rate.c                            |  13 +-
+++ 5 files changed, 152 insertions(+), 11 deletions(-)
+++ create mode 100644 0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
+++
+++diff --git a/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch b/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
+++new file mode 100644
+++index 0000000..23ace65
+++--- /dev/null
++++++ b/0001-Add-support-for-a-ALSA_PLUGIN_DIR-environment-variab.patch
+++@@ -0,0 +1,120 @@
++++From 21e72ff81167f0ec4e4b9b56ac4af546de83557b Mon Sep 17 00:00:00 2001
++++From: Julien Lepiller <[email-masked]>
++++Date: Sun, 22 Apr 2018 16:28:38 +0200
++++Subject: [PATCH] Add support for a ALSA_PLUGIN_DIR environment variable.
++++
++++If it is not set, default to previous behavior.
++++---
++++ src/control/control.c |  8 ++++++--
++++ src/dlmisc.c          | 14 +++++++++++---
++++ src/pcm/pcm.c         |  8 ++++++--
++++ src/pcm/pcm_rate.c    | 12 ++++++++----
++++ 4 files changed, 31 insertions(+), 11 deletions(-)
++++
++++diff --git a/src/control/control.c b/src/control/control.c
++++index 268c5e9..b2c8f9f 100644
++++--- a/src/control/control.c
+++++++ b/src/control/control.c
++++@@ -1331,13 +1331,17 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
++++ 			build_in++;
++++ 		}
++++ 		if (*build_in == NULL) {
++++-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
+++++			char* plugdir = ALSA_PLUGIN_DIR;
+++++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++++            if(envplugdir != NULL)
+++++                plugdir = envplugdir;
+++++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
++++ 			if (buf1 == NULL) {
++++ 				err = -ENOMEM;
++++ 				goto _err;
++++ 			}
++++ 			lib = buf1;
++++-			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
+++++			sprintf(buf1, "%s/libasound_module_ctl_%s.so", plugdir, str);
++++ 		}
++++ 	}
++++ #ifndef PIC
++++diff --git a/src/dlmisc.c b/src/dlmisc.c
++++index b36c48f..baa4bf8 100644
++++--- a/src/dlmisc.c
+++++++ b/src/dlmisc.c
++++@@ -76,10 +76,18 @@ void *snd_dlopen(const char *name, int mode)
++++ 	char *filename;
++++ 
++++ 	if (name && name[0] != '/') {
+++++		char* plugdir = ALSA_PLUGIN_DIR;
+++++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++++        if(envplugdir != NULL)
+++++            plugdir = envplugdir;
+++++
++++ 		filename = malloc(sizeof(ALSA_PLUGIN_DIR) + 1 + strlen(name) + 1);
++++-		strcpy(filename, ALSA_PLUGIN_DIR);
++++-		strcat(filename, "/");
++++-		strcat(filename, name);
+++++		if (filename == NULL) {
+++++			err = -ENOMEM;
+++++			return NULL;
+++++		}
+++++
+++++		sprintf(filename, "%s/%s", plugdir, name);
++++ 		handle = dlopen(filename, mode);
++++ 		free(filename);
++++ 	}
++++diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
++++index fc7bd52..1a64490 100644
++++--- a/src/pcm/pcm.c
+++++++ b/src/pcm/pcm.c
++++@@ -2432,13 +2432,17 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
++++ 			build_in++;
++++ 		}
++++ 		if (*build_in == NULL) {
++++-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
+++++			char* plugdir = ALSA_PLUGIN_DIR;
+++++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++++            if(envplugdir != NULL)
+++++                plugdir = envplugdir;
+++++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
++++ 			if (buf1 == NULL) {
++++ 				err = -ENOMEM;
++++ 				goto _err;
++++ 			}
++++ 			lib = buf1;
++++-			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
+++++			sprintf(buf1, "%s/libasound_module_pcm_%s.so", plugdir, str);
++++ 		}
++++ 	}
++++ #ifndef PIC
++++diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
++++index f60b0ae..2c62842 100644
++++--- a/src/pcm/pcm_rate.c
+++++++ b/src/pcm/pcm_rate.c
++++@@ -1260,7 +1260,7 @@ static const char *const default_rate_plugins[] = {
++++ 
++++ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_config_t *converter_conf, int verbose)
++++ {
++++-	char open_name[64], open_conf_name[64], lib_name[128], *lib = NULL;
+++++	char open_name[64], open_conf_name[64], *lib = NULL;
++++ 	snd_pcm_rate_open_func_t open_func;
++++ 	snd_pcm_rate_open_conf_func_t open_conf_func;
++++ 	int err;
++++@@ -1268,9 +1268,13 @@ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_conf
++++ 	snprintf(open_name, sizeof(open_name), "_snd_pcm_rate_%s_open", type);
++++ 	snprintf(open_conf_name, sizeof(open_conf_name), "_snd_pcm_rate_%s_open_conf", type);
++++ 	if (!is_builtin_plugin(type)) {
++++-		snprintf(lib_name, sizeof(lib_name),
++++-				 "%s/libasound_module_rate_%s.so", ALSA_PLUGIN_DIR, type);
++++-		lib = lib_name;
+++++		char* plugdir = ALSA_PLUGIN_DIR;
+++++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++++        if(envplugdir != NULL)
+++++            plugdir = envplugdir;
+++++		buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
+++++		sprintf(buf1, "%s/libasound_module_rate_%s.so", plugdir, type);
+++++		lib = buf1;
++++ 	}
++++ 
++++ 	rate->rate_min = SND_PCM_PLUGIN_RATE_MIN;
++++-- 
++++2.17.0
++++
+++diff --git a/src/control/control.c b/src/control/control.c
+++index 268c5e9..b2c8f9f 100644
+++--- a/src/control/control.c
++++++ b/src/control/control.c
+++@@ -1331,13 +1331,17 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+++ 			build_in++;
+++ 		}
+++ 		if (*build_in == NULL) {
+++-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
++++			char* plugdir = ALSA_PLUGIN_DIR;
++++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++++            if(envplugdir != NULL)
++++                plugdir = envplugdir;
++++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
+++ 			if (buf1 == NULL) {
+++ 				err = -ENOMEM;
+++ 				goto _err;
+++ 			}
+++ 			lib = buf1;
+++-			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
++++			sprintf(buf1, "%s/libasound_module_ctl_%s.so", plugdir, str);
+++ 		}
+++ 	}
+++ #ifndef PIC
+++diff --git a/src/dlmisc.c b/src/dlmisc.c
+++index b36c48f..baa4bf8 100644
+++--- a/src/dlmisc.c
++++++ b/src/dlmisc.c
+++@@ -76,10 +76,18 @@ void *snd_dlopen(const char *name, int mode)
+++ 	char *filename;
+++ 
+++ 	if (name && name[0] != '/') {
++++		char* plugdir = ALSA_PLUGIN_DIR;
++++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++++        if(envplugdir != NULL)
++++            plugdir = envplugdir;
++++
+++ 		filename = malloc(sizeof(ALSA_PLUGIN_DIR) + 1 + strlen(name) + 1);
+++-		strcpy(filename, ALSA_PLUGIN_DIR);
+++-		strcat(filename, "/");
+++-		strcat(filename, name);
++++		if (filename == NULL) {
++++			err = -ENOMEM;
++++			return NULL;
++++		}
++++
++++		sprintf(filename, "%s/%s", plugdir, name);
+++ 		handle = dlopen(filename, mode);
+++ 		free(filename);
+++ 	}
+++diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
+++index fc7bd52..1a64490 100644
+++--- a/src/pcm/pcm.c
++++++ b/src/pcm/pcm.c
+++@@ -2432,13 +2432,17 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+++ 			build_in++;
+++ 		}
+++ 		if (*build_in == NULL) {
+++-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
++++			char* plugdir = ALSA_PLUGIN_DIR;
++++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++++            if(envplugdir != NULL)
++++                plugdir = envplugdir;
++++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
+++ 			if (buf1 == NULL) {
+++ 				err = -ENOMEM;
+++ 				goto _err;
+++ 			}
+++ 			lib = buf1;
+++-			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
++++			sprintf(buf1, "%s/libasound_module_pcm_%s.so", plugdir, str);
+++ 		}
+++ 	}
+++ #ifndef PIC
+++diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
+++index f60b0ae..72a1723 100644
+++--- a/src/pcm/pcm_rate.c
++++++ b/src/pcm/pcm_rate.c
+++@@ -1260,7 +1260,8 @@ static const char *const default_rate_plugins[] = {
+++ 
+++ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_config_t *converter_conf, int verbose)
+++ {
+++-	char open_name[64], open_conf_name[64], lib_name[128], *lib = NULL;
++++	char open_name[64], open_conf_name[64], *lib = NULL;
++++    char *buf1;
+++ 	snd_pcm_rate_open_func_t open_func;
+++ 	snd_pcm_rate_open_conf_func_t open_conf_func;
+++ 	int err;
+++@@ -1268,9 +1269,13 @@ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_conf
+++ 	snprintf(open_name, sizeof(open_name), "_snd_pcm_rate_%s_open", type);
+++ 	snprintf(open_conf_name, sizeof(open_conf_name), "_snd_pcm_rate_%s_open_conf", type);
+++ 	if (!is_builtin_plugin(type)) {
+++-		snprintf(lib_name, sizeof(lib_name),
+++-				 "%s/libasound_module_rate_%s.so", ALSA_PLUGIN_DIR, type);
+++-		lib = lib_name;
++++		char* plugdir = ALSA_PLUGIN_DIR;
++++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++++        if(envplugdir != NULL)
++++            plugdir = envplugdir;
++++		buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
++++		sprintf(buf1, "%s/libasound_module_rate_%s.so", plugdir, type);
++++		lib = buf1;
+++ 	}
+++ 
+++ 	rate->rate_min = SND_PCM_PLUGIN_RATE_MIN;
+++-- 
+++2.17.0
+++
++diff --git a/src/control/control.c b/src/control/control.c
++index 268c5e9..b2c8f9f 100644
++--- a/src/control/control.c
+++++ b/src/control/control.c
++@@ -1331,13 +1331,17 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
++ 			build_in++;
++ 		}
++ 		if (*build_in == NULL) {
++-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
+++			char* plugdir = ALSA_PLUGIN_DIR;
+++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++            if(envplugdir != NULL)
+++                plugdir = envplugdir;
+++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
++ 			if (buf1 == NULL) {
++ 				err = -ENOMEM;
++ 				goto _err;
++ 			}
++ 			lib = buf1;
++-			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
+++			sprintf(buf1, "%s/libasound_module_ctl_%s.so", plugdir, str);
++ 		}
++ 	}
++ #ifndef PIC
++diff --git a/src/dlmisc.c b/src/dlmisc.c
++index b36c48f..baa4bf8 100644
++--- a/src/dlmisc.c
+++++ b/src/dlmisc.c
++@@ -76,10 +76,18 @@ void *snd_dlopen(const char *name, int mode)
++ 	char *filename;
++ 
++ 	if (name && name[0] != '/') {
+++		char* plugdir = ALSA_PLUGIN_DIR;
+++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++        if(envplugdir != NULL)
+++            plugdir = envplugdir;
+++
++ 		filename = malloc(sizeof(ALSA_PLUGIN_DIR) + 1 + strlen(name) + 1);
++-		strcpy(filename, ALSA_PLUGIN_DIR);
++-		strcat(filename, "/");
++-		strcat(filename, name);
+++		if (filename == NULL) {
+++			err = -ENOMEM;
+++			return NULL;
+++		}
+++
+++		sprintf(filename, "%s/%s", plugdir, name);
++ 		handle = dlopen(filename, mode);
++ 		free(filename);
++ 	}
++diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
++index fc7bd52..1a64490 100644
++--- a/src/pcm/pcm.c
+++++ b/src/pcm/pcm.c
++@@ -2432,13 +2432,17 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
++ 			build_in++;
++ 		}
++ 		if (*build_in == NULL) {
++-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
+++			char* plugdir = ALSA_PLUGIN_DIR;
+++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++            if(envplugdir != NULL)
+++                plugdir = envplugdir;
+++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
++ 			if (buf1 == NULL) {
++ 				err = -ENOMEM;
++ 				goto _err;
++ 			}
++ 			lib = buf1;
++-			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
+++			sprintf(buf1, "%s/libasound_module_pcm_%s.so", plugdir, str);
++ 		}
++ 	}
++ #ifndef PIC
++diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
++index f60b0ae..4bc9006 100644
++--- a/src/pcm/pcm_rate.c
+++++ b/src/pcm/pcm_rate.c
++@@ -1260,7 +1260,8 @@ static const char *const default_rate_plugins[] = {
++ 
++ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_config_t *converter_conf, int verbose)
++ {
++-	char open_name[64], open_conf_name[64], lib_name[128], *lib = NULL;
+++	char open_name[64], open_conf_name[64], *lib = NULL;
+++    char *buf1;
++ 	snd_pcm_rate_open_func_t open_func;
++ 	snd_pcm_rate_open_conf_func_t open_conf_func;
++ 	int err;
++@@ -1268,9 +1269,13 @@ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_conf
++ 	snprintf(open_name, sizeof(open_name), "_snd_pcm_rate_%s_open", type);
++ 	snprintf(open_conf_name, sizeof(open_conf_name), "_snd_pcm_rate_%s_open_conf", type);
++ 	if (!is_builtin_plugin(type)) {
++-		snprintf(lib_name, sizeof(lib_name),
++-				 "%s/libasound_module_rate_%s.so", ALSA_PLUGIN_DIR, type);
++-		lib = lib_name;
+++		char* plugdir = ALSA_PLUGIN_DIR;
+++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
+++        if(envplugdir != NULL)
+++            plugdir = envplugdir;
+++		buf1 = malloc(strlen(type) + strlen(plugdir) + 32);
+++		sprintf(buf1, "%s/libasound_module_rate_%s.so", plugdir, type);
+++		lib = buf1;
++ 	}
++ 
++ 	rate->rate_min = SND_PCM_PLUGIN_RATE_MIN;
++-- 
++2.17.0
++
+diff --git a/src/control/control.c b/src/control/control.c
+index 268c5e9..b2c8f9f 100644
+--- a/src/control/control.c
++++ b/src/control/control.c
+@@ -1331,13 +1331,17 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ 			build_in++;
+ 		}
+ 		if (*build_in == NULL) {
+-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
++			char* plugdir = ALSA_PLUGIN_DIR;
++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++            if(envplugdir != NULL)
++                plugdir = envplugdir;
++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
+ 			if (buf1 == NULL) {
+ 				err = -ENOMEM;
+ 				goto _err;
+ 			}
+ 			lib = buf1;
+-			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
++			sprintf(buf1, "%s/libasound_module_ctl_%s.so", plugdir, str);
+ 		}
+ 	}
+ #ifndef PIC
+diff --git a/src/dlmisc.c b/src/dlmisc.c
+index b36c48f..f6af8fe 100644
+--- a/src/dlmisc.c
++++ b/src/dlmisc.c
+@@ -76,10 +76,17 @@ void *snd_dlopen(const char *name, int mode)
+ 	char *filename;
+ 
+ 	if (name && name[0] != '/') {
++		char* plugdir = ALSA_PLUGIN_DIR;
++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++        if(envplugdir != NULL)
++            plugdir = envplugdir;
++
+ 		filename = malloc(sizeof(ALSA_PLUGIN_DIR) + 1 + strlen(name) + 1);
+-		strcpy(filename, ALSA_PLUGIN_DIR);
+-		strcat(filename, "/");
+-		strcat(filename, name);
++		if (filename == NULL) {
++			return NULL;
++		}
++
++		sprintf(filename, "%s/%s", plugdir, name);
+ 		handle = dlopen(filename, mode);
+ 		free(filename);
+ 	}
+diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
+index fc7bd52..1a64490 100644
+--- a/src/pcm/pcm.c
++++ b/src/pcm/pcm.c
+@@ -2432,13 +2432,17 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ 			build_in++;
+ 		}
+ 		if (*build_in == NULL) {
+-			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
++			char* plugdir = ALSA_PLUGIN_DIR;
++            char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++            if(envplugdir != NULL)
++                plugdir = envplugdir;
++			buf1 = malloc(strlen(str) + strlen(plugdir) + 32);
+ 			if (buf1 == NULL) {
+ 				err = -ENOMEM;
+ 				goto _err;
+ 			}
+ 			lib = buf1;
+-			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
++			sprintf(buf1, "%s/libasound_module_pcm_%s.so", plugdir, str);
+ 		}
+ 	}
+ #ifndef PIC
+diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
+index f60b0ae..4bc9006 100644
+--- a/src/pcm/pcm_rate.c
++++ b/src/pcm/pcm_rate.c
+@@ -1260,7 +1260,8 @@ static const char *const default_rate_plugins[] = {
+ 
+ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_config_t *converter_conf, int verbose)
+ {
+-	char open_name[64], open_conf_name[64], lib_name[128], *lib = NULL;
++	char open_name[64], open_conf_name[64], *lib = NULL;
++    char *buf1;
+ 	snd_pcm_rate_open_func_t open_func;
+ 	snd_pcm_rate_open_conf_func_t open_conf_func;
+ 	int err;
+@@ -1268,9 +1269,13 @@ static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_conf
+ 	snprintf(open_name, sizeof(open_name), "_snd_pcm_rate_%s_open", type);
+ 	snprintf(open_conf_name, sizeof(open_conf_name), "_snd_pcm_rate_%s_open_conf", type);
+ 	if (!is_builtin_plugin(type)) {
+-		snprintf(lib_name, sizeof(lib_name),
+-				 "%s/libasound_module_rate_%s.so", ALSA_PLUGIN_DIR, type);
+-		lib = lib_name;
++		char* plugdir = ALSA_PLUGIN_DIR;
++        char* envplugdir = getenv("ALSA_PLUGIN_DIR");
++        if(envplugdir != NULL)
++            plugdir = envplugdir;
++		buf1 = malloc(strlen(type) + strlen(plugdir) + 32);
++		sprintf(buf1, "%s/libasound_module_rate_%s.so", plugdir, type);
++		lib = buf1;
+ 	}
+ 
+ 	rate->rate_min = SND_PCM_PLUGIN_RATE_MIN;
+-- 
+2.17.0
+
-- 
2.17.0