[alsa-devel] snd_pcm_writei() return value

Cristian Morales Vega cmorve69 at yahoo.es
Thu May 21 19:26:04 CEST 2009


Hi,

I have an stupid doubt... The snd_pcm_writei() documentation says:
"If the blocking behaviour is selected, then routine waits until all
requested bytes are played or put to the playback ring buffer. The
count of bytes can be less only if a signal or underrun occurred."
and at the same time it says "-EPIPE   an underrun occurred" is a
possible return value.
Then snd_pcm_recover() documentation says:
"This functions handles -EINTR (interrupted system call), -EPIPE
(overrun or underrun) and -ESTRPIPE (stream is suspended) error codes
trying to prepare given stream for next I/O."

So if I want to write the full content of a buffer, would this be valid?:

while(buffer.length > 0) {
  snd_pcm_sframes_t written = snd_pcm_writei(device.handle,
buffer.data, buffer.length);
  if(written < 0)
    snd_pcm_recover(device.handle, written, 1);
  else
    buffer.length = 0;
}


"The count of bytes can be less only if a signal ... occurred." makes
me think that if a signal interrups snd_pcm_writei() it will return a
value between 0 and buffer.length, but "This functions handles -EINTR
(interrupted system call)" makes me think that it will always return
-EINTR.

"The count of bytes can be less only if a ... underrun occurred.",
even if technically correct, also seems to be against the "-EPIPE   an
underrun occurred" return value.


So, in the previous code, "if(written < 0)" should be changed by
"if(written < buffer.length)"? Anyway, how snd_pcm_recover() handles
an -EINTR? If only half the data has been written it can't modify
buffer.data to point to the last sample written+1. Perhaps I need a
full:

uint32_t *buffer_ptr = buffer.data;

while(buffer.length > 0) {
  snd_pcm_sframes_t written = snd_pcm_writei(device.handle,
buffer_ptr, buffer.length);
  if(written < 0) {
    snd_pcm_recover(device.handle, written, 1);
  } else if(written <= buffer.length) {
    buffer.length -= written;
    buffer_ptr += written;
  }
}

? And still, in this case an interrupt would be handled by
snd_pcm_recover() (written < 0) or by the "else" code?


Thanks.


More information about the Alsa-devel mailing list