* ring buffer operation
*/
-static int check_interleave(snd_pcm_dmix_t *dmix)
+static int check_interleave(snd_pcm_dmix_t *dmix, snd_pcm_t *pcm)
{
unsigned int chn, channels;
int interleaved = 1;
const snd_pcm_channel_area_t *dst_areas;
+ const snd_pcm_channel_area_t *src_areas;
channels = dmix->shmptr->s.channels;
dst_areas = snd_pcm_mmap_areas(dmix->spcm);
+ src_areas = snd_pcm_mmap_areas(pcm);
for (chn = 1; chn < channels; chn++) {
if (dst_areas[chn-1].addr != dst_areas[chn].addr) {
interleaved = 0;
break;
}
+ if (src_areas[chn-1].addr != src_areas[chn].addr) {
+ interleaved = 0;
+ break;
+ }
}
for (chn = 0; chn < channels; chn++) {
if (dst_areas[chn].first != sizeof(signed short) * chn * 8 ||
interleaved = 0;
break;
}
+ if (src_areas[chn].first != sizeof(signed short) * chn * 8 ||
+ src_areas[chn].step != channels * sizeof(signed short) * 8) {
+ interleaved = 0;
+ break;
+ }
}
return dmix->interleaved = interleaved;
}
while (size-- > 0) {
sample = *src;
+ old_sample = *sum;
if (*dst == 0)
- sample -= *sum;
+ sample -= old_sample;
*sum += sample;
do {
old_sample = *sum;
sample = old_sample;
*dst = sample;
} while (*sum != old_sample);
- ((char *)src) += dst_step;
- ((char *)dst) += src_step;
- ((char *)sum) += sum_step;
+ ((char *)src) += src_step;
+ ((char *)dst) += dst_step;
+ ((char *)sum) += sum_step;
}
}
channels = dmix->shmptr->s.channels;
if (dmix->interleaved) {
/*
- * process the all areas in one loop
+ * process all areas in one loop
* it optimizes the memory accesses for this case
*/
dmix->mix_areas1(size * channels,
{
snd_pcm_dmix_t *dmix = pcm->private_data;
+ check_interleave(dmix, pcm);
// assert(pcm->boundary == dmix->shmptr->s.boundary); /* for sure */
dmix->state = SND_PCM_STATE_PREPARED;
dmix->appl_ptr = 0;
goto _err;
}
- check_interleave(dmix);
mix_select_callbacks(dmix);
pcm->poll_fd = dmix->poll_fd;