Patches for libasound to support upcoming Audacious 2.2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I've been working on the ALSA output for the upcoming 2.2 release of
Audacious media player and have run into some problems in
snd_device_name_hint, which is now used to show the user a list of
possible output devices.  I've written patches which correct those
problems.

The biggest problem is that in several places, functions called by
snd_device_name_hint call snd_config_delete on sections of the config
returned by snd_config_search.  Once these sections are deleted, future
calls to snd_pcm_open fail miserably.

        ALSA lib conf.c:4600:(snd_config_expand) Unknown parameters CARD=ICH6,DEV=0
        ALSA lib pcm.c:2211:(snd_pcm_open_noupdate) Unknown PCM front:CARD=ICH6,DEV=0
        alsa-gapless: snd_pcm_open failed: Invalid argument.

        ALSA lib pcm.c:2211:(snd_pcm_open_noupdate) Unknown PCM pulse
        alsa-gapless: snd_pcm_open failed: No such file or directory.

A smaller but still annoying problem shows up only once the offending
snd_config_delete calls are taken out: software devices, such as "pulse"
and "null" are listed twice or three times depending on how many
hardware devices I have plugged in.

A third problem is that "ctl" seems to be arbitrarily left out of the
list of device types that snd_device_name_hint will search for.  I've
added it to the list in this patch, and it seems to work fine.

Finally, a performance issue: snd_device_name_hint indirectly calls
snd_dlopen frequently with the parameter name == NULL, meaning to open
libasound.so itself.  In this case, snd_dlopen calls dladdr every call
to find out the path to libasound.so.  Caching this path within
snd_dlopen so that dladdr is called only once speeds up the execution
time of snd_device_name_hint (a somewhat slow call) by 40%.

I am attaching three patches that fix these problems:
 - src/conf.c
 - src/dlmisc.c
 - src/control/namehint.c

Peace,
John Lindgren
--- conf.0.c	2009-09-09 08:34:54.000000000 -0400
+++ conf.c	2009-10-24 11:35:28.000000000 -0400
@@ -1132,7 +1132,6 @@
 				free(id);
 				continue;
 			}
-			snd_config_delete(n);
 		}
 		if (mode == MERGE) {
 			SNDERR("%s does not exists", id);
@@ -1156,7 +1155,6 @@
 				skip = 1;
 				n = NULL;
 			} else if (mode == OVERRIDE) {
-				snd_config_delete(n);
 				n = NULL;
 			}
 		} else {
--- dlmisc.0.c	2009-09-09 08:34:54.000000000 -0400
+++ dlmisc.c	2009-10-24 11:57:46.000000000 -0400
@@ -54,9 +54,13 @@
 #else
 #ifdef HAVE_LIBDL
 	if (name == NULL) {
-		Dl_info dlinfo;
-		if (dladdr(snd_dlopen, &dlinfo) > 0)
-			name = dlinfo.dli_fname;
+		static const char * self = NULL;
+		if (self == NULL) {
+			static Dl_info dlinfo;
+			if (dladdr(snd_dlopen, &dlinfo) > 0)
+				self = dlinfo.dli_fname;
+		}
+		name = self;
 	}
 #endif
 #endif
--- namehint.0.c	2009-09-09 08:34:54.000000000 -0400
+++ namehint.c	2009-10-25 21:38:54.000000000 -0400
@@ -328,7 +328,6 @@
 	if (snd_config_search(cfg1, "slave", &cfg) >= 0 &&
 	    snd_config_search(cfg, base, &cfg1) >= 0)
 	    	goto __hint;
-	snd_config_delete(res);
 	res = NULL;
 	if (strchr(buf, ':') != NULL)
 		goto __ok;
@@ -379,8 +378,6 @@
 	      	err = hint_list_add(list, buf, buf1);
 	}
       __skip_add:
-      	if (res)
-	      	snd_config_delete(res);
 	if (buf1)
 		free(buf1);
       	free(buf);
@@ -450,13 +447,10 @@
 		if (err == -EXDEV)
 			continue;
 		if (err < 0) {
+			list->card = card;
 			list->device = -1;
 			err = try_config(list, list->siface, str);
 		}
-		if (err < 0) {
-			list->card = -1;
-			err = try_config(list, list->siface, str);
-		}
 		if (err == -ENOMEM)
 			goto __error;
 	}
@@ -466,6 +460,29 @@
 	return err;
 }

+static int add_software_devices(struct hint_list *list)
+{
+	int err;
+	snd_config_t *conf, *n;
+	snd_config_iterator_t i, next;
+	const char *str;
+
+	err = snd_config_search(snd_config, list->siface, &conf);
+	if (err < 0)
+		return err;
+	snd_config_for_each(i, next, conf) {
+		n = snd_config_iterator_entry(i);
+		if (snd_config_get_id(n, &str) < 0)
+			continue;
+		list->card = -1;
+		list->device = -1;
+		err = try_config(list, list->siface, str);
+		if (err == -ENOMEM)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
 static int get_card_name(struct hint_list *list, int card)
 {
 	char scard[16], *s;
@@ -532,6 +549,8 @@
 		list.iface = SND_CTL_ELEM_IFACE_SEQUENCER;
 	else if (strcmp(iface, "hwdep") == 0)
 		list.iface = SND_CTL_ELEM_IFACE_HWDEP;
+	else if (strcmp(iface, "ctl") == 0)
+		list.iface = SND_CTL_ELEM_IFACE_MIXER;
 	else
 		return -EINVAL;
 	list.show_all = 0;
@@ -543,6 +562,7 @@
 		if (err >= 0)
 			err = add_card(&list, card);
 	} else {
+		add_software_devices(&list);
 		err = snd_card_next(&card);
 		if (err < 0)
 			goto __error;
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux