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@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-user

Reply via email to