Package: libasound2
Version: 1.0.8-3
Severity: wishlist
Tags: patch

This bug make impossible to work with single channel of multichannel frame.
So I do not find another clear way to filter high frequences out of my 
subwoofer.

Patch contain more verbose description of the problem and solution 
(doc/README.LADSPA).

Patch fixes all three problems I found.
Patch need attention want to use - may be split, it changes debian/changelog, 
add more verbose debug.
Patch checked: apt-get source libasound2 (from stable); copy; apply; 
dpkg-buildpackage -rfakeroot; dpkg -i ../*asound*deb; check xmms&mplayer works
Patch also fixes 1 minor bug in sources (debugging, line commented).

-- System Information:
Debian Release: 3.1
Architecture: i386 (i686)
Kernel: Linux 2.6.8.1
Locale: LANG=ru_RU.KOI8-R, LC_CTYPE=ru_RU.KOI8-R

Versions of packages libasound2 depends on:
ii  libc6                       2.3.2.ds1-22 GNU C Library: Shared libraries an

-- no debconf information
diff -urN alsa-lib-1.0.8/debian/changelog alsa-lib-1.0.8.fix1/debian/changelog
--- alsa-lib-1.0.8/debian/changelog	2005-10-28 00:03:38.000000000 +0400
+++ alsa-lib-1.0.8.fix1/debian/changelog	2005-10-27 20:16:58.000000000 +0400
@@ -1,3 +1,11 @@
+alsa-lib (1.0.8-3.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix LADSPA plugin handling
+  * Fix locale decimal point handling dependence
+
+ -- Gennadiy Kupava <[EMAIL PROTECTED]>  Thu, 27 Oct 2005 20:14:32 +0400
+
 alsa-lib (1.0.8-3) unstable; urgency=medium
 
   * Thomas Hood:
diff -urN alsa-lib-1.0.8/doc/README.LADSPA alsa-lib-1.0.8.fix1/doc/README.LADSPA
--- alsa-lib-1.0.8/doc/README.LADSPA	1970-01-01 03:00:00.000000000 +0300
+++ alsa-lib-1.0.8.fix1/doc/README.LADSPA	2005-10-28 01:15:46.000000000 +0400
@@ -0,0 +1,165 @@
+LADSPA not best fix.
+
+Firstly, bug: policy NONE simple do not work anyway.
+
+Searching in internet for description how LADSPA works with alsa give me 
+next to nothing.
+
+So I decide describe how it works after this little fix. I am sure that 
+this must be done better. (I can do it better, but have no need. May be if 
+you ask and don`t afraid that I will ask you much more time about sound, 
+filters, etc).
+
+OK. Things is simple. Imagine you frame of N sound channels. Every channel
+have input and output. Every channel must have at least one plugin(instance of plugin). 
+input and output of plugin must end in same channel. Plugins executed
+in order of conffile. Policy NONE mean that only one instance of plugin is created for only one channel.
+Policy DUBLICATE(default) mean that instances of that plugin will be created 
+for every channel. For dublicate policy input and output channel in conffile 
+must be 0.
+
+Example of working conffile. It is wrong and have extra unused stuff, but works:
+it can be used placing ice2_20to21 in 'audiodevice' of config of alsa output extention of xmms to play standard stereo file (2.0) to 2.1 (stereo+sub) with filtering for subwoofer.
+
+pcm.ice1724_0 {
+	type hw
+	card 1
+	device 0
+	subdevice 0
+}
+
+pcm.ice1724_1 {
+	type hw
+	card 1
+	device 2
+	subdevice 1
+}
+
+pcm.ice1724_2 {
+	type hw
+	card 1
+	device 2
+	subdevice 2
+}
+
+
+pcm.ice_cv {
+	type multi;
+	slaves.a.pcm ice1724_0;
+	slaves.a.channels 2;
+	slaves.b.pcm ice1724_1;
+	slaves.b.channels 2;
+	slaves.c.pcm ice1724_2;
+	slaves.c.channels 2;
+	bindings.0.slave a;
+	bindings.0.channel 0;
+	bindings.1.slave a;
+	bindings.1.channel 1;
+	bindings.2.slave b;
+	bindings.2.channel 0;
+	bindings.3.slave b;
+	bindings.3.channel 1;
+	bindings.4.slave c;
+	bindings.4.channel 0;
+	bindings.5.slave c;
+	bindings.5.channel 1;
+}
+
+
+pcm.ice_plug {
+	type plug
+	slave.pcm ice_cv
+	slave.format S32_LE
+	slave.channels 6
+}
+
+pcm.ice_route {
+	type route;
+	slave.pcm ice_plug;
+	slave.channels 6;
+	ttable.0.0 1;
+	ttable.1.1 1;
+	ttable.0.2 1;
+	ttable.1.3 1;
+	ttable.0.4 1;
+	ttable.1.5 1;
+}
+
+pcm.ice_route2 {
+	type route;
+	slave.pcm ice_plug;
+	slave.channels 6;
+	#channels 4;
+	ttable.0.0 1;
+	ttable.1.1 1;
+	ttable.2.2 1;
+	ttable.3.3 1;
+	ttable.0.4 1;
+	ttable.1.5 1;
+}
+
+pcm.ice2_51to21 {
+	type plug
+	slave.pcm ice_cv
+	slave.format S32_LE
+	#slave.rate 48000
+	slave.channels 6
+	ttable {
+		0.0	0.3333;
+		1.1	0.3333;
+		2.0	0.3333;
+		3.1	0.3333;
+		4.0	0.3333;  #c->fl
+		4.1	0.3333;  #c->fr
+		5.2	0.2;
+		0.2	0.2;
+		1.2	0.2;
+		2.2	0.2;
+		3.2	0.2;
+	}
+}
+
+
+pcm.ice2_20to21 {
+	type plug
+	slave.pcm ice2_21cutoffsub
+	#slave.pcm	ice_cv
+	#slave.pcm	ladspa
+	#slave.format S32_LE
+	#slave.rate 48000
+	slave.channels 6
+	ttable {
+		0.0	1
+		1.1	1
+		0.2	0.5
+		1.2	0.5
+	}
+}
+
+pcm.ice2_21cutoffsub {
+	type ladspa
+	slave.pcm	ice_plug
+	path 	"/usr/lib/ladspa"
+	plugins {
+		0 {
+			label lp4pole_fcrcia_oa
+			policy none
+			input.bindings.2 "Input";
+			output.bindings.2 "Output";
+			input {
+			 controls	[ 300 0 ]
+			}
+		}
+		1 {
+ 		  label delay_0.01s
+		  input.bindings.0 "Input";
+		  output.bindings.0 "Output";
+                  input {
+			controls [ 0 1 ]
+		  }
+		}
+	}
+}
+
+
+Gennady Kupava, [EMAIL PROTECTED] dot spbnit dot ru.
\ ÷ ËÏÎÃÅ ÆÁÊÌÁ ÎÅÔ ÎÏ×ÏÊ ÓÔÒÏËÉ
diff -urN alsa-lib-1.0.8/doc/README.locale alsa-lib-1.0.8.fix1/doc/README.locale
--- alsa-lib-1.0.8/doc/README.locale	1970-01-01 03:00:00.000000000 +0300
+++ alsa-lib-1.0.8.fix1/doc/README.locale	2005-10-28 00:53:24.000000000 +0400
@@ -0,0 +1,14 @@
+Locale fix introduce a bit confusing behaviour.
+
+Problem is real numbers delimiter. Somethere, for example in Russia it is ',' 
+not '.'. So .asoundrc with numbers like 0.33 look wrong for config parser.
+Fixed by checking locale delimiter and replacing '.' from conffile to locale 
+delimiter of current locale before conversion of string.
+
+More intresting problem with LADSPA plugin names. For example name of plugin
+'delay0.01s' is 'delay0.01s' in en_US locale and 'delay0,01s' in ru_RU.KOI8-R 
+locale. You may check listplugins from ladspa-sdk. Fixed search for both
+variant of label, i. e. normal and replaced last '.' with locale-defined 
+delimiter then searching for plugins. 
+
+Gennady Kupava, [EMAIL PROTECTED] dot spbnit dot ru.
\ ÷ ËÏÎÃÅ ÆÁÊÌÁ ÎÅÔ ÎÏ×ÏÊ ÓÔÒÏËÉ
diff -urN alsa-lib-1.0.8/include/version.h alsa-lib-1.0.8.fix1/include/version.h
--- alsa-lib-1.0.8/include/version.h	2005-01-13 13:07:32.000000000 +0300
+++ alsa-lib-1.0.8.fix1/include/version.h	2005-10-27 23:46:08.000000000 +0400
@@ -5,7 +5,7 @@
 #define SND_LIB_MAJOR		1 /**< major number of library version */
 #define SND_LIB_MINOR		0 /**< minor number of library version */
 #define SND_LIB_SUBMINOR	8 /**< subminor number of library version */
-#define SND_LIB_EXTRAVER	1000000 /**< extra version number, used mainly for betas */
+#define SND_LIB_EXTRAVER	1000001 /**< extra version number, used mainly for betas */
 /** library version */
 #define SND_LIB_VERSION		((SND_LIB_MAJOR<<16)|\
 				 (SND_LIB_MINOR<<8)|\
diff -urN alsa-lib-1.0.8/src/conf.c alsa-lib-1.0.8.fix1/src/conf.c
--- alsa-lib-1.0.8/src/conf.c	2004-10-05 19:33:04.000000000 +0400
+++ alsa-lib-1.0.8.fix1/src/conf.c	2005-10-27 23:32:57.000000000 +0400
@@ -420,6 +420,7 @@
 #include <limits.h>
 #include <sys/stat.h>
 #include <pthread.h>
+#include <locale.h>
 #include "local.h"
 
 #ifndef DOC_HIDDEN
@@ -497,10 +498,19 @@
 {
 	char *end;
 	double v;
+	struct lconv* lc;
+	char dp;
+	char *str2;
 	if (!*str)
 		return -EINVAL;
+	str2=malloc (strlen (str)+1);
+	strcpy (str2,str);
 	errno = 0;
-	v = strtod(str, &end);
+	lc=localeconv ();
+	if (strchr (str2,'.'))
+	  *strchr (str2,'.')=*lc->decimal_point;
+	v = strtod(str2, &end);
+	free (str2);
 	if (errno)
 		return -errno;
 	if (*end)
diff -urN alsa-lib-1.0.8/src/pcm/pcm_ladspa.c alsa-lib-1.0.8.fix1/src/pcm/pcm_ladspa.c
--- alsa-lib-1.0.8/src/pcm/pcm_ladspa.c	2004-05-04 19:54:01.000000000 +0400
+++ alsa-lib-1.0.8.fix1/src/pcm/pcm_ladspa.c	2005-10-28 01:27:58.000000000 +0400
@@ -29,6 +29,7 @@
 #include <dirent.h>
 #include <dlfcn.h>
 #include <wordexp.h>
+#include <locale.h>
 #include "pcm_local.h"
 #include "pcm_plugin.h"
 
@@ -432,19 +433,71 @@
 			assert(err >= 0);
 		}
 		if (plugin->policy == SND_PCM_LADSPA_POLICY_NONE) {
+			int bindf;
 			instance = list_entry(plugin->instances.next, snd_pcm_ladspa_instance_t, list);
-			for (idx = 0; idx < pcm->channels; idx++) {
-				err = snd_pcm_ladspa_connect_plugin(plugin, &plugin->input, instance, idx);
-				if (err < 0) {
-					SNDERR("Unable to connect input port of plugin '%s' channel %u depth %u", plugin->desc->Name, idx, depth);
-					return err;
-				}
-				err = snd_pcm_ladspa_connect_plugin(plugin, &plugin->output, instance, idx);
-				if (err < 0) {
-					SNDERR("Unable to connect output port of plugin '%s' channel %u depth %u", plugin->desc->Name, idx, depth);
-					return err;
-				}
-			}
+			bindf = 0;
+			instance->channel = NO_ASSIGN;
+			for (idx = 0; idx < plugin->input.port_bindings_size; idx++)
+			  if (plugin->input.port_bindings[idx] != NO_ASSIGN)
+			    if (!bindf)
+			      {
+				bindf = 1;
+				instance->in_port = plugin->input.port_bindings[idx];
+				if (instance->channel == NO_ASSIGN)
+				  instance->channel = idx;
+				else if (instance->channel != idx)
+				  {
+				    SNDERR
+				      ("Input and output channel differ port specified for plugin '%s' channel %u depth %u",
+				       plugin->desc->Name, idx, depth);
+				    return -EINVAL;
+				  };
+			      }
+			    else
+			      {
+				SNDERR
+				  ("More that one input port specified for plugin '%s' channel %u depth %u",
+				   plugin->desc->Name, idx, depth);
+				return -EINVAL;
+			      };
+			if (!bindf)
+			  {
+			    SNDERR
+			      ("No input port specified for plugin '%s' channel %u depth %u",
+			       plugin->desc->Name, idx, depth);
+			    return -EINVAL;
+			  };
+			bindf = 0;
+			for (idx = 0; idx < plugin->output.port_bindings_size; idx++)
+			  if (plugin->output.port_bindings[idx] != NO_ASSIGN)
+			    if (!bindf)
+			      {
+				bindf = 1;
+				instance->out_port = plugin->output.port_bindings[idx];
+				if (instance->channel == NO_ASSIGN)
+				  instance->channel = idx;
+				else if (instance->channel != idx)
+				  {
+				    SNDERR
+				      ("Input and output channel differ port specified for plugin '%s' channel %u depth %u",
+				       plugin->desc->Name, idx, depth);
+				    return -EINVAL;
+				  };
+			      }
+			    else
+			      {
+				SNDERR
+				  ("More that one output port specified for plugin '%s' channel %u depth %u",
+				   plugin->desc->Name, idx, depth);
+				return -EINVAL;
+			      };
+			if (!bindf)
+			  {
+			    SNDERR
+			      ("No output port specified for plugin '%s' channel %u depth %u",
+			       plugin->desc->Name, idx, depth);
+			    return -EINVAL;
+			  };
 		}
 		depth++;
 	}
@@ -657,9 +710,10 @@
 		goto __control;
 	snd_output_printf(out, "Audio %s port bindings:", io->pdesc == LADSPA_PORT_INPUT ? "input" : "output");
 	for (idx = 0; idx < io->port_bindings_size; idx++) {
-		if (io->port_bindings[idx] != NO_ASSIGN) 
-			continue;
-		snd_output_printf(out, " %i -> %i", idx, io->port_bindings[idx]);
+	  if (io->port_bindings[idx] == NO_ASSIGN)	//bug one
+	    snd_output_printf (out, " %i -> NO_ASSIGN", idx);
+	  else
+	    snd_output_printf (out, " %i -> %i", idx, io->port_bindings[idx]);
 	}
 	snd_output_printf(out, "\n");
       __control:
@@ -673,27 +727,59 @@
 
 static void snd_pcm_ladspa_plugins_dump(struct list_head *list, snd_output_t *out)
 {
-	struct list_head *pos;
-	
-	list_for_each(pos, list) {
-		snd_pcm_ladspa_plugin_t *plugin = list_entry(pos, snd_pcm_ladspa_plugin_t, list);
-		snd_pcm_ladspa_dump_direction(&plugin->input, out);
-		snd_pcm_ladspa_dump_direction(&plugin->output, out);
-	}
+  struct list_head *pos, *pos2;
+
+  list_for_each (pos, list)
+  {
+    snd_pcm_ladspa_plugin_t *plugin =
+      list_entry (pos, snd_pcm_ladspa_plugin_t, list);
+    snd_output_printf (out, "Policy %i\n", plugin->policy);
+    snd_output_printf (out, "Filename %s\n", plugin->filename);
+    list_for_each (pos2, &plugin->instances)
+    {
+      snd_pcm_ladspa_instance_t *in = (snd_pcm_ladspa_instance_t *) pos2;
+      snd_output_printf (out,
+			 "-Instance: depth:%i, channel %i, inp %i, outp %i\n",
+			 in->depth, in->channel, in->in_port, in->out_port);
+    };
+    snd_pcm_ladspa_dump_direction (&plugin->input, out);
+    snd_pcm_ladspa_dump_direction (&plugin->output, out);
+  }
 }
 
 static void snd_pcm_ladspa_dump(snd_pcm_t *pcm, snd_output_t *out)
 {
-	snd_pcm_ladspa_t *ladspa = pcm->private_data;
-	snd_output_printf(out, "LADSPA PCM\n");
-	snd_pcm_ladspa_plugins_dump(&ladspa->pplugins, out);
-	snd_pcm_ladspa_plugins_dump(&ladspa->cplugins, out);
-	if (pcm->setup) {
-		snd_output_printf(out, "Its setup is:\n");
-		snd_pcm_dump_setup(pcm, out);
-	}
-	snd_output_printf(out, "Slave: ");
-	snd_pcm_dump(ladspa->plug.slave, out);
+  snd_pcm_ladspa_t *ladspa = pcm->private_data;
+  struct list_head *pos;
+  snd_output_printf (out, "LADSPA PCM\n");
+  snd_output_printf (out, "instances_channels %i\n",
+		     ladspa->instances_channels);
+  if (ladspa->finstances)
+    {
+      int idx;
+      for (idx = 0; idx < ladspa->instances_channels; idx++)
+	{
+	  if (!ladspa->finstances[idx])
+	    snd_output_printf (out, "-Instance %i: not assigned\n", idx);
+	  else
+	    {
+	      snd_pcm_ladspa_instance_t *in = ladspa->finstances[idx];
+	      snd_output_printf (out, "-Instance %i: depth:%i, channel %i\n",
+				 idx, in->depth, in->channel);
+	    };
+	};
+    };
+  snd_output_printf (out, "  >playback\n");
+  snd_pcm_ladspa_plugins_dump (&ladspa->pplugins, out);
+  snd_output_printf (out, "  >capture\n");
+  snd_pcm_ladspa_plugins_dump (&ladspa->cplugins, out);
+  if (pcm->setup)
+    {
+      snd_output_printf (out, "Its setup is:\n");
+      snd_pcm_dump_setup (pcm, out);
+    }
+  snd_output_printf (out, "Slave: ");
+  snd_pcm_dump (ladspa->plug.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_ladspa_ops = {
@@ -727,8 +813,18 @@
 			long idx;
 			const LADSPA_Descriptor *d;
 			for (idx = 0; (d = fcn(idx)) != NULL; idx++) {
-				if (strcmp(label, d->Label))
-					continue;
+				char *labellocale;
+				struct lconv *lc;
+				lc = localeconv ();
+				labellocale = malloc (strlen (label) + 1);
+				strcpy (labellocale, label);
+				if (strrchr (labellocale, '.'))
+				  *strrchr (labellocale, '.') = *lc->decimal_point;
+				if (strcmp (label, d->Label) && strcmp (labellocale, d->Label)) {
+				  free (labellocale);
+				  continue;
+				};
+				free (labellocale);
 				if (ladspa_id > 0 && d->UniqueID != ladspa_id)
 					continue;
 				plugin->filename = strdup(filename);

Reply via email to