[alsa-devel] multi pcm and mmap problem
Takashi Iwai
tiwai at suse.de
Fri Nov 23 15:35:35 CET 2007
At Fri, 23 Nov 2007 14:41:43 +0100,
I wrote:
>
> Try the patch below. This should fix the problem. Now the multi
> plugin just shadows the slave buffers via mmap.
There was a minor bug in the last patch. The revised version is
below.
Takashi
diff -r 3539f279ec38 src/pcm/pcm_multi.c
--- a/src/pcm/pcm_multi.c Wed Nov 21 12:19:43 2007 +0100
+++ b/src/pcm/pcm_multi.c Fri Nov 23 15:34:16 2007 +0100
@@ -690,13 +690,44 @@ static snd_pcm_sframes_t snd_pcm_multi_m
return size;
}
-static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+static int snd_pcm_multi_munmap(snd_pcm_t *pcm)
{
+ free(pcm->mmap_channels);
+ free(pcm->running_areas);
+ pcm->mmap_channels = NULL;
+ pcm->running_areas = NULL;
return 0;
}
-static int snd_pcm_multi_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+static int snd_pcm_multi_mmap(snd_pcm_t *pcm)
{
+ snd_pcm_multi_t *multi = pcm->private_data;
+ unsigned int c;
+
+ pcm->mmap_channels = calloc(pcm->channels,
+ sizeof(pcm->mmap_channels[0]));
+ pcm->running_areas = calloc(pcm->channels,
+ sizeof(pcm->running_areas[0]));
+ if (!pcm->mmap_channels || !pcm->running_areas) {
+ snd_pcm_multi_munmap(pcm);
+ return -ENOMEM;
+ }
+
+ /* Copy the slave mmapped buffer data */
+ for (c = 0; c < pcm->channels; c++) {
+ snd_pcm_multi_channel_t *chan = &multi->channels[c];
+ snd_pcm_t *slave;
+ if (chan->slave_idx < 0) {
+ snd_pcm_multi_munmap(pcm);
+ return -ENXIO;
+ }
+ slave = multi->slaves[chan->slave_idx].pcm;
+ pcm->mmap_channels[c] =
+ slave->mmap_channels[chan->slave_channel];
+ pcm->mmap_channels[c].channel = c;
+ pcm->running_areas[c] =
+ slave->running_areas[chan->slave_channel];
+ }
return 0;
}
@@ -850,6 +881,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp,
return err;
}
pcm->mmap_rw = 1;
+ pcm->mmap_shadow = 1; /* has own mmap method */
pcm->ops = &snd_pcm_multi_ops;
pcm->fast_ops = &snd_pcm_multi_fast_ops;
pcm->private_data = multi;
More information about the Alsa-devel
mailing list