Re: Is it possible to get dmix working with an 8bits USB sound card?

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

 



David Bourgeois wrote:
> Or can I imagine patching dmix to add support for 8 bits

Please try this patch.


Index: alsa/alsa-lib/src/pcm/pcm_dmix.c
===================================================================
--- alsa.orig/alsa-lib/src/pcm/pcm_dmix.c	2007-07-07 11:07:05.000000000 +0200
+++ alsa/alsa-lib/src/pcm/pcm_dmix.c	2007-09-23 12:32:44.000000000 +0200
@@ -219,7 +219,7 @@ static void mix_areas(snd_pcm_direct_t *
 			sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
 			dmix->u.dmix.mix_areas2(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
 		}
-	} else { /* SND_PCM_FORMAT_S24_3LE */
+	} else if (dmix->shmptr->s.format == SND_PCM_FORMAT_S24_3LE) {
 		unsigned char *src;
 		volatile unsigned char *dst;
 		if (dmix->interleaved) {
@@ -245,6 +245,32 @@ static void mix_areas(snd_pcm_direct_t *
 			sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
 			dmix->u.dmix.mix_areas3(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
 		}
+	} else { /* SND_PCM_FORMAT_U8 */
+		unsigned char *src;
+		volatile unsigned char *dst;
+		if (dmix->interleaved) {
+			/*
+			 * process all areas in one loop
+			 * it optimizes the memory accesses for this case
+			 */
+			dmix->u.dmix.mix_areas_u8(size * channels,
+					((unsigned char *)dst_areas[0].addr) + dst_ofs * channels,
+					((unsigned char *)src_areas[0].addr) + src_ofs * channels,
+					dmix->u.dmix.sum_buffer + (dst_ofs * channels),
+					1, 1, sizeof(signed int));
+			return;
+		}
+		for (chn = 0; chn < channels; chn++) {
+			dchn = dmix->bindings ? dmix->bindings[chn] : chn;
+			if (dchn >= dmix->shmptr->s.channels)
+				continue;
+			src_step = src_areas[chn].step / 8;
+			dst_step = dst_areas[dchn].step / 8;
+			src = (unsigned char *)(((char *)src_areas[chn].addr + src_areas[chn].first / 8) + (src_ofs * src_step));
+			dst = (unsigned char *)(((char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + (dst_ofs * dst_step));
+			sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
+			dmix->u.dmix.mix_areas_u8(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
+		}
 	}
 }

Index: alsa/alsa-lib/src/pcm/pcm_direct.c
===================================================================
--- alsa.orig/alsa-lib/src/pcm/pcm_direct.c	2007-05-24 20:41:40.000000000 +0200
+++ alsa/alsa-lib/src/pcm/pcm_direct.c	2007-09-23 12:34:10.000000000 +0200
@@ -883,6 +883,7 @@ int snd_pcm_direct_initialize_slave(snd_
 			SND_PCM_FORMAT_S16,
 			SND_PCM_FORMAT_S16 ^ SND_PCM_FORMAT_S16_LE ^ SND_PCM_FORMAT_S16_BE,
 			SND_PCM_FORMAT_S24_3LE,
+			SND_PCM_FORMAT_U8,
 		};
 		snd_pcm_format_t format;
 		unsigned int i;
Index: alsa/alsa-lib/src/pcm/pcm_direct.h
===================================================================
--- alsa.orig/alsa-lib/src/pcm/pcm_direct.h	2007-04-07 09:19:48.000000000 +0200
+++ alsa/alsa-lib/src/pcm/pcm_direct.h	2007-09-23 12:26:17.000000000 +0200
@@ -39,6 +39,11 @@ typedef void (mix_areas3_t)(unsigned int
 			volatile signed int *sum, size_t dst_step,
 			size_t src_step, size_t sum_step);

+typedef void (mix_areas_u8_t)(unsigned int size,
+			      volatile unsigned char *dst, unsigned char *src,
+			      volatile signed int *sum, size_t dst_step,
+			      size_t src_step, size_t sum_step);
+
 struct slave_params {
 	snd_pcm_format_t format;
 	int rate;
@@ -151,6 +156,7 @@ struct snd_pcm_direct {
 			mix_areas1_t *mix_areas1;
 			mix_areas2_t *mix_areas2;
 			mix_areas3_t *mix_areas3;
+			mix_areas_u8_t *mix_areas_u8;
 		} dmix;
 		struct {
 		} dsnoop;
Index: alsa/alsa-lib/src/pcm/pcm_dmix_generic.c
===================================================================
--- alsa.orig/alsa-lib/src/pcm/pcm_dmix_generic.c	2007-07-07 11:07:05.000000000 +0200
+++ alsa/alsa-lib/src/pcm/pcm_dmix_generic.c	2007-09-23 12:40:52.000000000 +0200
@@ -277,6 +277,32 @@ static void generic_mix_areas3(unsigned
 	}
 }

+static void generic_mix_areas_u8(unsigned int size,
+				 volatile unsigned char *dst, unsigned char *src,
+				 volatile signed int *sum, size_t dst_step,
+				 size_t src_step, size_t sum_step)
+{
+	for (;;) {
+		register int sample = *src - 0x80;
+		if (!*dst) {
+			*sum = sample;
+		} else {
+			sample += *sum;
+			*sum = sample;
+			if (sample > 0x7f)
+				sample = 0x7f;
+			else if (sample < -0x80)
+				sample = -0x80;
+		}
+		*dst = sample + 0x80;
+		if (!--size)
+			return;
+		dst += dst_step;
+		src += src_step;
+		sum = (signed int *) ((char *)sum + sum_step);
+	}
+}
+

 static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
 {
@@ -288,6 +314,7 @@ static void generic_mix_select_callbacks
 		dmix->u.dmix.mix_areas2 = generic_mix_areas2_swap;
 	}
 	dmix->u.dmix.mix_areas3 = generic_mix_areas3;
+	dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8;
 }

 #endif

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
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