[linux-audio-dev] efficient non-blocking writes to /dev/dsp

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: [linux-audio-dev] efficient non-blocking writes to /dev/dsp
From: Christopher Lee (clee_AT_gnwy100.wuh.wustl.edu)
Date: Mon Apr 02 2001 - 06:24:11 EEST


I'm just getting started with linux sound progamming and had a basic question:

I'm trying to debug the call that writes sound data in the linuxaudiodev
python module so that it uses non-blocking IO correctly to write to
/dev/dsp or /dev/audio.

I've written a fixed version using select() that works, but it seems that
it leads to 1 or 2 byte transfers being done on many of the write() calls. Is
there a standard paradigm for doing the transfer in a more efficient way?
The OSS programmers manual from 4Front mentions using optimal transfer
sizes, but it not clear to me how this helps w/ select().

Thanks in advance,

-chris
(using linux 2.4.2 w/ AM's low-latency patch with a SB Live!)

Here's what the current code looks like roughly (fd corresponds to /dev/dsp
opened in non-blocking, write-only mode):

int mydspwrite(int fd, char *cp, int size)
/*
    write size number of bytes to fd (/dev/dsp) from buffer pointed to
    by *cp
    return number of bytes written on success = size
    return -1 on error
*/
{
    int rv;
    int ocount=0; /* output-count: num bytes written */
    fd_set write_set_fds;
    struct timeval tv;
    int select_retval;
    
    /* use select to wait for audio device to be available */
    FD_ZERO(&write_set_fds);
    FD_SET(fd, &write_set_fds);
    tv.tv_sec = 1; /* timeout values */
    tv.tv_usec = 0;

    while (size > 0) {
      select_retval = select(fd+1, NULL, &write_set_fds, NULL, &tv);
      tv.tv_sec = 1; tv.tv_usec = 0; /* willing to wait this long next time*/
      if (select_retval) {
        if ((rv = write(fd, cp, size)) == -1) {
          if (errno != EAGAIN) {
             return -1;
          } else {
            errno = 0; /* EAGAIN: buffer is full, try again */
          }
        } else {
          /* successfully wrote rv bytes */
          ocount += rv;
          size -= rv;
          cp += rv;
        }
      } else {
        printf("timeout: Not able to write to linux audio device within %ld seconds\n", tv.tv_sec);
        return (-1);
      }
    }
    return ocount;
}


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Sat Apr 07 2001 - 16:00:08 EEST