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