Re: auto upmix in .asoundrc

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

 



Takashi Iwai wrote:
Could you post a patch so that I can apply it to GIT tree?

Sure. Please find attached. In addition to the changes described, I've changed an error message and extended the chlist.

But there are two points to pay attention to:

1) What do you think about 3 and 7 channel sources? Should they be addressed more specific?

2) In upmix_2_to_71 I had to decide how to copy front to side. I first tried to use the delayed copy. It mangled the sound quality - not sure why. So I used the simple copy. I think the best solution would be to use about half the delay of the rear speakers. So maybe there should be something like half_delayed_copy which uses mix->delay_ms / 2. ;-)

Oh - and my patch is against deb-src version 1.0.21. If there's much changed in current git, I can do another one for you, but I wouldn't expect that.
--- pcm_upmix.c	2009-08-31 15:09:41.000000000 +0200
+++ pcm_upmix.c.new	2009-12-03 15:26:34.000000000 +0100
@@ -128,6 +128,20 @@
 	}
 }
 
+static void upmix_1_to_71(snd_pcm_upmix_t *mix ATTRIBUTE_UNUSED,
+			  const snd_pcm_channel_area_t *dst_areas,
+			  snd_pcm_uframes_t dst_offset,
+			  const snd_pcm_channel_area_t *src_areas,
+			  snd_pcm_uframes_t src_offset,
+			  snd_pcm_uframes_t size)
+{
+	int i;
+	for (i = 0; i < 8; i++)
+		snd_pcm_area_copy(dst_areas + i, dst_offset,
+				  src_areas, src_offset,
+				  size, SND_PCM_FORMAT_S16);
+}
+
 static void upmix_1_to_51(snd_pcm_upmix_t *mix ATTRIBUTE_UNUSED,
 			  const snd_pcm_channel_area_t *dst_areas,
 			  snd_pcm_uframes_t dst_offset,
@@ -156,6 +170,24 @@
 				  size, SND_PCM_FORMAT_S16);
 }
 
+static void upmix_2_to_71(snd_pcm_upmix_t *mix,
+			  const snd_pcm_channel_area_t *dst_areas,
+			  snd_pcm_uframes_t dst_offset,
+			  const snd_pcm_channel_area_t *src_areas,
+			  snd_pcm_uframes_t src_offset,
+			  snd_pcm_uframes_t size)
+{
+	snd_pcm_areas_copy(dst_areas, dst_offset, src_areas, src_offset,
+			   2, size, SND_PCM_FORMAT_S16);
+	delayed_copy(mix, dst_areas + 2, dst_offset, src_areas, src_offset,
+		     size);
+	average_copy(dst_areas + 4, dst_offset, src_areas, src_offset,
+		     2, size);
+	snd_pcm_areas_copy(dst_areas + 6, dst_offset, src_areas, src_offset,
+			   2, size, SND_PCM_FORMAT_S16);
+	
+}
+
 static void upmix_2_to_51(snd_pcm_upmix_t *mix,
 			  const snd_pcm_channel_area_t *dst_areas,
 			  snd_pcm_uframes_t dst_offset,
@@ -260,13 +292,26 @@
 			   6, size, SND_PCM_FORMAT_S16);
 }
 
-static const upmixer_t do_upmix[6][2] = {
-	{ upmix_1_to_40, upmix_1_to_51 },
-	{ upmix_2_to_40, upmix_2_to_51 },
-	{ upmix_3_to_40, upmix_3_to_51 },
-	{ upmix_4_to_40, upmix_4_to_51 },
-	{ upmix_4_to_40, upmix_5_to_51 },
-	{ upmix_4_to_40, upmix_6_to_51 },
+static void upmix_8_to_71(snd_pcm_upmix_t *mix ATTRIBUTE_UNUSED,
+			  const snd_pcm_channel_area_t *dst_areas,
+			  snd_pcm_uframes_t dst_offset,
+			  const snd_pcm_channel_area_t *src_areas,
+			  snd_pcm_uframes_t src_offset,
+			  snd_pcm_uframes_t size)
+{
+	snd_pcm_areas_copy(dst_areas, dst_offset, src_areas, src_offset,
+			   8, size, SND_PCM_FORMAT_S16);
+}
+
+static const upmixer_t do_upmix[8][3] = {
+	{ upmix_1_to_40, upmix_1_to_51, upmix_1_to_71 },
+	{ upmix_2_to_40, upmix_2_to_51, upmix_2_to_71 },
+	{ upmix_3_to_40, upmix_3_to_51, upmix_3_to_51 },
+	{ upmix_4_to_40, upmix_4_to_51, upmix_4_to_51 },
+	{ upmix_4_to_40, upmix_5_to_51, upmix_5_to_51 },
+	{ upmix_4_to_40, upmix_6_to_51, upmix_6_to_51 },
+	{ upmix_4_to_40, upmix_6_to_51, upmix_6_to_51 },
+	{ upmix_4_to_40, upmix_6_to_51, upmix_8_to_71 },
 };
 
 static snd_pcm_sframes_t
@@ -288,9 +333,18 @@
 	snd_pcm_upmix_t *mix = (snd_pcm_upmix_t *)ext;
 	int ctype, stype;
 
-	stype = (ext->slave_channels == 6) ? 1 : 0;
+	switch (ext->slave_channels) {
+		case	6:
+			stype = 1;
+			break;
+		case 8:
+			stype = 2;
+			break;
+		default:
+			stype = 0;
+	}
 	ctype = ext->channels - 1;
-	if (ctype < 0 || ctype > 5) {
+	if (ctype < 0 || ctype > 7) {
 		SNDERR("Invalid channel numbers for upmix: %d", ctype + 1);
 		return -EINVAL;
 	}
@@ -328,7 +382,7 @@
 	snd_config_iterator_t i, next;
 	snd_pcm_upmix_t *mix;
 	snd_config_t *sconf = NULL;
-	static const unsigned int chlist[2] = {4, 6};
+	static const unsigned int chlist[3] = {4, 6, 8};
 	unsigned int channels = 0;
 	int delay = 10;
 	int err;
@@ -362,8 +416,8 @@
 				return err;
 			}
 			channels = val;
-			if (channels != 4 && channels != 6 && channels != 0) {
-				SNDERR("channels must be 4, 6 or 0");
+			if (channels != 4 && channels != 6 && channels != 0 && channels != 8) {
+				SNDERR("channels must be 4, 6, 8 or 0");
 				return -EINVAL;
 			}
 			continue;
@@ -399,7 +453,7 @@
 
 	snd_pcm_extplug_set_param_minmax(&mix->ext,
 					 SND_PCM_EXTPLUG_HW_CHANNELS,
-					 1, 6);
+					 1, 8);
 	if (channels)
 		snd_pcm_extplug_set_slave_param_minmax(&mix->ext,
 						       SND_PCM_EXTPLUG_HW_CHANNELS,
@@ -407,7 +461,7 @@
 	else
 		snd_pcm_extplug_set_slave_param_list(&mix->ext,
 						     SND_PCM_EXTPLUG_HW_CHANNELS,
-						     2, chlist);
+						     3, chlist);
 	snd_pcm_extplug_set_param(&mix->ext, SND_PCM_EXTPLUG_HW_FORMAT,
 				  SND_PCM_FORMAT_S16);
 	snd_pcm_extplug_set_slave_param(&mix->ext, SND_PCM_EXTPLUG_HW_FORMAT,
------------------------------------------------------------------------------
Join us December 9, 2009 for the Red Hat Virtual Experience,
a free event focused on virtualization and cloud computing. 
Attend in-depth sessions from your desk. Your couch. Anywhere.
http://p.sf.net/sfu/redhat-sfdev2dev
_______________________________________________
Alsa-user mailing list
Alsa-user@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-user

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux