>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