I don't know all about mmap, but why does one need to poll.
I would have thought that a callback with info on how many samples it wants
would be a better way.
Cheers
James


> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]]On Behalf Of Paul Davis
> Sent: 28 November 2001 13:47
> To: Jaroslav Kysela
> Cc: [EMAIL PROTECTED]
> Subject: Re: [Alsa-devel] more on that return from poll(2) issue
>
>
> >non-continous transfers. The right loop, based on the period_size
> >transfers, should be like this:
> >
> >     poll();
> >     if ((pfd->revents & POLLIN) {
> >             while (1) {
> >                     if (snd_pcm_avail_update(pcm) < period_size)
> >                             break;
> >                     count = period_size;
> >                     // transfer whole period (can be composed from more
> >                     // non-continuous parts)
>
> right, i understand that on some hardware, this is true. but there is
> no reason i know of for the trident h/w (perhaps for any hardware) to
> have a whole period composed of 2 non-continuous parts of size 1 and
> (period_size-1) frames. i can't believe that its an honest reflection
> of the state of the hardware.
>
> the one complication that i can see that might cause this is the
> extent to which capture+playback hw pointers are in sync. what might
> be happening is that there really is a continuous period_size's worth
> of frames available on one stream, but in the other stream, the
> pointer doesn't quite reflect this, so we end up with the silly
> situation of having (period_size-1) + 1 frames. you'll note that in the
> code below, i poll only one descriptor.
>
> do you think this is possible/likely? if it is, do you think that its
> the job of the low level driver(s) to handle this? otherwise, its hard
> for me to see how an application (or library) can handle this
> efficiently in any full-duplex situations.
>
> i say this because even if we poll on both stream descriptors, if one
> of them is out-of-step by 1 (or lets just say some very small number
> of frames), we have to go back into poll immediately, which will
> return immediately, and we end up busy waiting, which is not good at all.
> i don't see any other way to handle that situation. do you?
>
> i'm going to add some debugging to check on the "pointers-not-in-sync
> theory", and i'll let you know what i find. since very few programs do
> full duplex operation, this may be a rather hidden problem.
>
> >                     while (avail > 0) {
> >                             frames = count;
> >                             snd_pcm_mmap_begin(pcm, areas,
> &offset, &frames
> >);
> >                             ....
> >                             snd_pcm_mmap_commit(pcm, offset, frames);
> >                             count -= frames;
> >                     }
> >             }
> >     }
>
> is there any difference between that and the actual loop (a few
> non-essentials removed to make it clearer):
>
>       if (poll (&driver->pfd, 1, 1000) < 0) {
>               .... error ...
>       }
>
>       if (driver->pfd.revents & POLLERR) {
>               .... error ....
>       }
>
>       if (driver->pfd.revents == 0) {
>               ... timeout ....
>       }
>
>       if ((capture_avail = snd_pcm_avail_update
> (driver->capture_handle)) < 0) {
>             ... detect xruns ...
>       }
>
>       if ((playback_avail = snd_pcm_avail_update
> (driver->playback_handle)) < 0) {
>              ... detect xruns ...
>       }
>
>       ... handle xruns ...
>
>       avail = capture_avail < playback_avail ?
>                  capture_avail : playback_avail;
>
>       while (avail) {
>
>               /* driver->frames_per_cycle === period_size */
>
>               capture_avail = (avail > driver->frames_per_cycle) ?
>                                 driver->frames_per_cycle : avail;
>               playback_avail = (avail > driver->frames_per_cycle) ?
>                                 driver->frames_per_cycle : avail;
>
>               /* THIS CALLS snd_pcm_mmap_begin() FOR BOTH STREAMS */
>
>               if (alsa_driver_get_channel_addresses
>                        (driver,
>                        (snd_pcm_uframes_t *) &capture_avail,
>                      (snd_pcm_uframes_t *) &playback_avail,
>                        &capture_offset, &playback_offset) < 0) {
>                       return -1;
>               }
>
>               contiguous = capture_avail < playback_avail ?
>                                 capture_avail : playback_avail;
>
>               .... do interesting stuff with `contiguous' frames ...
>
>               snd_pcm_mmap_commit (driver->capture_handle,
>                                    capture_offset, contiguous);
>               snd_pcm_mmap_commit (driver->playback_handle,
>                                    playback_offset, contiguous);
>
>               avail -= contiguous;
>       }
>
>
>
>
>
> _______________________________________________
> Alsa-devel mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/alsa-devel


_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to