mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-02-25 01:40:10 -05:00
dmix: simplify mix_areas()
The code for the three supported sample widths is almost the same, so it makes sense to merge the three cases.
This commit is contained in:
parent
79db4a6bfa
commit
a3fe1f7800
2 changed files with 52 additions and 86 deletions
|
|
@ -24,6 +24,11 @@
|
||||||
#define DIRECT_IPC_SEMS 1
|
#define DIRECT_IPC_SEMS 1
|
||||||
#define DIRECT_IPC_SEM_CLIENT 0
|
#define DIRECT_IPC_SEM_CLIENT 0
|
||||||
|
|
||||||
|
typedef void (mix_areas_t)(unsigned int size,
|
||||||
|
volatile void *dst, void *src,
|
||||||
|
volatile signed int *sum, size_t dst_step,
|
||||||
|
size_t src_step, size_t sum_step);
|
||||||
|
|
||||||
typedef void (mix_areas_16_t)(unsigned int size,
|
typedef void (mix_areas_16_t)(unsigned int size,
|
||||||
volatile signed short *dst, signed short *src,
|
volatile signed short *dst, signed short *src,
|
||||||
volatile signed int *sum, size_t dst_step,
|
volatile signed int *sum, size_t dst_step,
|
||||||
|
|
|
||||||
|
|
@ -156,95 +156,56 @@ static void mix_areas(snd_pcm_direct_t *dmix,
|
||||||
snd_pcm_uframes_t dst_ofs,
|
snd_pcm_uframes_t dst_ofs,
|
||||||
snd_pcm_uframes_t size)
|
snd_pcm_uframes_t size)
|
||||||
{
|
{
|
||||||
volatile signed int *sum;
|
|
||||||
unsigned int src_step, dst_step;
|
unsigned int src_step, dst_step;
|
||||||
unsigned int chn, dchn, channels;
|
unsigned int chn, dchn, channels, sample_size;
|
||||||
|
mix_areas_t *do_mix_areas;
|
||||||
|
|
||||||
channels = dmix->channels;
|
channels = dmix->channels;
|
||||||
if (dmix->shmptr->s.format == SND_PCM_FORMAT_S16_LE ||
|
switch (dmix->shmptr->s.format) {
|
||||||
dmix->shmptr->s.format == SND_PCM_FORMAT_S16_BE) {
|
case SND_PCM_FORMAT_S16_LE:
|
||||||
signed short *src;
|
case SND_PCM_FORMAT_S16_BE:
|
||||||
volatile signed short *dst;
|
sample_size = 2;
|
||||||
if (dmix->interleaved) {
|
do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_16;
|
||||||
/*
|
break;
|
||||||
* process all areas in one loop
|
case SND_PCM_FORMAT_S32_LE:
|
||||||
* it optimizes the memory accesses for this case
|
case SND_PCM_FORMAT_S32_BE:
|
||||||
*/
|
sample_size = 4;
|
||||||
dmix->u.dmix.mix_areas_16(size * channels,
|
do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_32;
|
||||||
((signed short *)dst_areas[0].addr) + (dst_ofs * channels),
|
break;
|
||||||
((signed short *)src_areas[0].addr) + (src_ofs * channels),
|
case SND_PCM_FORMAT_S24_3LE:
|
||||||
dmix->u.dmix.sum_buffer + (dst_ofs * channels),
|
sample_size = 3;
|
||||||
sizeof(signed short),
|
do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_24;
|
||||||
sizeof(signed short),
|
break;
|
||||||
sizeof(signed int));
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (chn = 0; chn < channels; chn++) {
|
if (dmix->interleaved) {
|
||||||
dchn = dmix->bindings ? dmix->bindings[chn] : chn;
|
/*
|
||||||
if (dchn >= dmix->shmptr->s.channels)
|
* process all areas in one loop
|
||||||
continue;
|
* it optimizes the memory accesses for this case
|
||||||
src_step = src_areas[chn].step / 8;
|
*/
|
||||||
dst_step = dst_areas[dchn].step / 8;
|
do_mix_areas(size * channels,
|
||||||
src = (signed short *)(((char *)src_areas[chn].addr + src_areas[chn].first / 8) + (src_ofs * src_step));
|
(unsigned char *)dst_areas[0].addr + sample_size * dst_ofs * channels,
|
||||||
dst = (signed short *)(((char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + (dst_ofs * dst_step));
|
(unsigned char *)src_areas[0].addr + sample_size * src_ofs * channels,
|
||||||
sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
|
dmix->u.dmix.sum_buffer + dst_ofs * channels,
|
||||||
dmix->u.dmix.mix_areas_16(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
|
sample_size,
|
||||||
}
|
sample_size,
|
||||||
} else if (dmix->shmptr->s.format == SND_PCM_FORMAT_S32_LE ||
|
sizeof(signed int));
|
||||||
dmix->shmptr->s.format == SND_PCM_FORMAT_S32_BE) {
|
return;
|
||||||
signed int *src;
|
}
|
||||||
volatile signed int *dst;
|
for (chn = 0; chn < channels; chn++) {
|
||||||
if (dmix->interleaved) {
|
dchn = dmix->bindings ? dmix->bindings[chn] : chn;
|
||||||
/*
|
if (dchn >= dmix->shmptr->s.channels)
|
||||||
* process all areas in one loop
|
continue;
|
||||||
* it optimizes the memory accesses for this case
|
src_step = src_areas[chn].step / 8;
|
||||||
*/
|
dst_step = dst_areas[dchn].step / 8;
|
||||||
dmix->u.dmix.mix_areas_32(size * channels,
|
do_mix_areas(size,
|
||||||
((signed int *)dst_areas[0].addr) + (dst_ofs * channels),
|
((unsigned char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + dst_ofs * dst_step,
|
||||||
((signed int *)src_areas[0].addr) + (src_ofs * channels),
|
((unsigned char *)src_areas[chn].addr + src_areas[chn].first / 8) + src_ofs * src_step,
|
||||||
dmix->u.dmix.sum_buffer + (dst_ofs * channels),
|
dmix->u.dmix.sum_buffer + channels * dst_ofs + chn,
|
||||||
sizeof(signed int),
|
dst_step,
|
||||||
sizeof(signed int),
|
src_step,
|
||||||
sizeof(signed int));
|
channels * 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 = (signed int *)(((char *)src_areas[chn].addr + src_areas[chn].first / 8) + (src_ofs * src_step));
|
|
||||||
dst = (signed int *)(((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_32(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_areas_24(size * channels,
|
|
||||||
((unsigned char *)dst_areas[0].addr) + 3 * dst_ofs * channels,
|
|
||||||
((unsigned 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_areas_24(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue