[alsa-devel] Capture not working in MMAP mode with '-v'
Eero Nurkkala
ext-eero.nurkkala at nokia.com
Mon Nov 9 11:32:46 CET 2009
On Mon, 2009-11-09 at 11:26 +0100, ext Mark Brown wrote:
> On Mon, Nov 09, 2009 at 10:12:31AM +0200, Eero Nurkkala wrote:
>
> > As far as I know, nobody fixed it. Yeah, aplay = arecord, and it occurs
> > only with arecord to be more specific, and is present on all platforms
> > out there:
>
> Has anyone reported whatever the problem is?
> _______________________________________________
Does the below make any sense?
Call to:
err = snd_pcm_mmap_begin(handle, &areas, &offset, &chunk_size);
Will make the chuck_size to zero.
It's perfectly fine to be zero:
/**
* \brief Application request to access a portion of direct (mmap) area
* \param pcm PCM handle
* \param areas Returned mmap channel areas
* \param offset Returned mmap area offset in area steps (== frames)
* \param frames mmap area portion size in frames (wanted on entry, contiguous
available on exit)
* \return 0 on success otherwise a negative error code
*
* It is necessary to call the snd_pcm_avail_update() function directly before
* this call. Otherwise, this function can return a wrong count of available
frames.
*
* The function should be called before a sample-direct area can be accessed.
* The resulting size parameter is always less or equal to the input count of
frames
* and can be zero, if no frames can be processed (the ring buffer is full).
*
* See the snd_pcm_mmap_commit() function to finish the frame processing in
* the direct areas.
*/
int snd_pcm_mmap_begin(snd_pcm_t *pcm,
const snd_pcm_channel_area_t **areas,
snd_pcm_uframes_t *offset,
snd_pcm_uframes_t *frames)
{
--> aplay doesn't call "snd_pcm_avail_update()" as this function suggest. I try
is also, but the problem is chuck_size, when zero:
at aplay:
static ssize_t pcm_read(u_char *data, size_t rcount)
returns rcount always, never reading any through readi_func!!!!
This pcm_read is called at aplay:
/* capture */
fdcount = 0;
while (rest > 0) {
size_t c = (rest <= (off64_t)chunk_bytes) ?
(size_t)rest : chunk_bytes;
size_t f = c * 8 / bits_per_frame;
if (pcm_read(audiobuf, f) != f)
break;
if (write(fd, audiobuf, c) != c) {
perror(name);
exit(EXIT_FAILURE);
}
count -= c;
rest -= c;
fdcount += c;
printf("here!\n");
}
--> like you see this thing is always fine:
if (pcm_read(audiobuf, f) != f)
break;
if (write(fd, audiobuf, c) != c) {
perror(name);
exit(EXIT_FAILURE);
}
so it keeps on writing in the file, not reading any from ALSA. (try with
strace)
-->> Aplay is buggy, period.
So the patch:
--- a/alsa-utils-1.0.21/aplay/aplay.c
+++ b/alsa-utils-1.0.21/aplay/aplay-fix.c
@@ -1104,7 +1104,8 @@ static void set_params(void)
if (mmap_flag && verbose) {
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t offset;
- int i;
+ int i, chunk_prev = chunk_size;
+ snd_pcm_avail_update(handle);
err = snd_pcm_mmap_begin(handle, &areas, &offset, &chunk_size);
if (err < 0) {
error("snd_pcm_mmap_begin problem: %s", snd_strerror(err));
@@ -1112,6 +1113,11 @@ static void set_params(void)
}
for (i = 0; i < hwparams.channels; i++)
fprintf(stderr, "mmap_area[%i] = %p,%u,%u (%u)\n", i, areas[i].addr, areas[i].first, areas[i].step, snd_pcm_format_physical_width(hwparams.format));
+
+ /* Chunk size better be non-zero */
+ if (!chunk_size)
+ chunk_size = chunk_prev;
+
/* not required, but for sure */
snd_pcm_mmap_commit(handle, offset, 0);
}
More information about the Alsa-devel
mailing list