dmix: add S24_3LE support

Add to the dmix plugin support for the S24_3LE sample format which is
used by 24-bit USB devices.

The optimized assembler version uses only 23 bits for sample data so
that the lowest bit can be used for synchronization because there is no
24-bit cmpxchg instruction.
This commit is contained in:
Clemens Ladisch 2005-12-19 07:39:03 +00:00
parent 46f81f994b
commit 45f63a8735
8 changed files with 404 additions and 7 deletions

View file

@ -188,7 +188,8 @@ static void mix_areas(snd_pcm_direct_t *dmix,
sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
dmix->u.dmix.mix_areas1(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
}
} else {
} else if (dmix->shmptr->s.format == SND_PCM_FORMAT_S32_LE ||
dmix->shmptr->s.format == SND_PCM_FORMAT_S32_BE) {
signed int *src;
volatile signed int *dst;
if (dmix->interleaved) {
@ -216,6 +217,32 @@ static void mix_areas(snd_pcm_direct_t *dmix,
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 */
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_areas3(size * channels,
((char *)dst_areas[0].addr) + 3 * dst_ofs * channels,
((char *)src_areas[0].addr) + 3 * src_ofs * channels,
dmix->u.dmix.sum_buffer + (dst_ofs * channels),
3, 3, 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_areas3(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
}
}
}