[alsa-devel] Vanilla Blocked I/O probs
Hi, I am calling
rc = snd_pcm_readi (handle, buffer, MAX_LEN)
but rc is always 4 short of MAX_LEN (1020 instead of 1024). I thought that it would just block until MAX_LEN frames were available. This is really doing my head in, and any help would be appreciated.
Cheers
At Tue, 03 Apr 2007 13:41:26 +0100, Gordon Miller wrote:
Hi, I am calling
rc = snd_pcm_readi (handle, buffer, MAX_LEN)
but rc is always 4 short of MAX_LEN (1020 instead of 1024). I thought that it would just block until MAX_LEN frames were available. This is really doing my head in, and any help would be appreciated.
It's no bug. The blocking read behavior doesn't guarantee you to get the given size. It's defined so in POSIX.
Practially you should get the request size if it's actually aligned to the period size, though...
Takashi
Thanks Takashi
I went for this :
/*******************************************************/ void record_block (void *buffer) { int rc, needed = MAX_LEN; void *buf_ptr = buffer;
do { rc = snd_pcm_readi (handle, buf_ptr, needed); needed -= rc; buf_ptr += rc * (stereo_channel ? BPSSTEREO : BPSMONO); } while (needed);
} /* end record_block */ /****************************************************/
I have a global variable "stereo_channel" as you see that is 0 (mono), 1 (stereo left only) or 2 (stereo right only). If it is non-zero I multiply by BPSSTEREO (4) else BPSMONO (2). So "needed" counts down to 0, and buf_ptr moves along.
It's not pretty, but it works !
Gordon
At Tue, 03 Apr 2007 15:19:01 +0100, Gordon Miller wrote:
Thanks Takashi
I went for this :
/*******************************************************/ void record_block (void *buffer) { int rc, needed = MAX_LEN; void *buf_ptr = buffer;
do { rc = snd_pcm_readi (handle, buf_ptr, needed); needed -= rc; buf_ptr += rc * (stereo_channel ? BPSSTEREO : BPSMONO); } while (needed);
} /* end record_block */ /****************************************************/
I have a global variable "stereo_channel" as you see that is 0 (mono), 1 (stereo left only) or 2 (stereo right only). If it is non-zero I multiply by BPSSTEREO (4) else BPSMONO (2). So "needed" counts down to 0, and buf_ptr moves along.
It's not pretty, but it works !
Repeating read is indeed a correct implementation. (It should be so even for normal file reads.)
But I'd suggest to check the return value of snd_pcm_readi() whether it's zero or negative.
Takashi
Hi Gordon,
Gordon Miller schrieb:
I went for this :
/*******************************************************/ void record_block (void *buffer) { int rc, needed = MAX_LEN; void *buf_ptr = buffer;
do { rc = snd_pcm_readi (handle, buf_ptr, needed); needed -= rc; buf_ptr += rc * (stereo_channel ? BPSSTEREO : BPSMONO); } while (needed);
} /* end record_block */ /****************************************************/
You could also use: if (rc > 0) { needed -= rc; buf_ptr += snd_pcm_frames_to_bytes( handle, rc ); }
Gregor
participants (3)
-
Gordon Miller
-
Gregor Jasny
-
Takashi Iwai