コード例 #1
0
ファイル: sndio.c プロジェクト: DragonFlyBSD/DPorts
/* Retrieves the just recorded buffer, if there is one. */
static int
sndio_rec_read(void *buf)
{
	struct pollfd pfd;
	nfds_t nfds;
	int ret, nbytes, offset = 0;

	/* make sure counters have been updated */
	nfds = sio_pollfd(hdl, &pfd, POLLIN);
	poll(&pfd, nfds, 0);
	sio_revents(hdl, &pfd);
	if (!(sio_revents(hdl, &pfd) & POLLIN))
		return 0;

	nbytes = sndio_rec_bufsize;
	while (nbytes) {
		ret = sio_read(hdl, buf + offset, nbytes);
		if (sio_eof(hdl))
			return 0;
		offset += ret;
		nbytes -= ret;
	}

	return 1;
}
コード例 #2
0
static int
sio_psleep(struct sio_hdl *hdl, int event)
{
    struct pollfd pfd[SIO_MAXNFDS];
    int revents;
    int nfds;

    nfds = sio_nfds(hdl);
    if (nfds > SIO_MAXNFDS) {
        DPRINTF("sio_psleep: %d: too many descriptors\n", nfds);
        hdl->eof = 1;
        return 0;
    }
    for (;;) {
        nfds = sio_pollfd(hdl, pfd, event);
        while (poll(pfd, nfds, -1) < 0) {
            if (errno == EINTR)
                continue;
            DPERROR("sio_psleep: poll");
            hdl->eof = 1;
            return 0;
        }
        revents = sio_revents(hdl, pfd);
        if (revents & POLLHUP) {
            DPRINTF("sio_psleep: hang-up\n");
            return 0;
        }
        if (revents & event)
            break;
    }
    return 1;
}
コード例 #3
0
ファイル: ao_sndio.c プロジェクト: chyiz/mpv
/*
 * make libsndio call movecb()
 */
static void update(struct ao *ao)
{
    struct priv *p = ao->priv;
    int n = sio_pollfd(p->hdl, p->pfd, POLLOUT);
    while (poll(p->pfd, n, 0) < 0 && errno == EINTR) {}
    sio_revents(p->hdl, p->pfd);
}
コード例 #4
0
void
SNDDMA_Submit(void)
{
    struct pollfd pfd;
    size_t count, todo, avail;
    int n;

    n = sio_pollfd(hdl, &pfd, POLLOUT);
    while (poll(&pfd, n, 0) < 0 && errno == EINTR)
        ;
    if (!(sio_revents(hdl, &pfd) & POLLOUT))
        return;
    avail = dma_buffer_size;
    while (avail > 0) {
        todo = dma_buffer_size - dma_ptr;
        if (todo > avail)
            todo = avail;
        count = sio_write(hdl, dma_buffer + dma_ptr, todo);
        if (count == 0)
            break;
        dma_ptr += count;
        if (dma_ptr >= dma_buffer_size)
            dma_ptr -= dma_buffer_size;
        avail -= count;
    }
}
コード例 #5
0
ファイル: sndio.c プロジェクト: DragonFlyBSD/DPorts
/* write as many blocks as is currently possible */
static void
sndio_update(int threaded)
{
	struct pollfd pfd;
	nfds_t nfds;
	int i, nblocks, nbytes;

	/* make sure counters have been updated */
	nfds = sio_pollfd(hdl, &pfd, POLLOUT);
	poll(&pfd, nfds, 0);
	if (!(sio_revents(hdl, &pfd) & POLLOUT))
		return;

	nblocks = (sndio_play_appbufsz - (sndio_playpos - sndio_realpos)) /
	    sndio_play_round;

	/* we got POLLOUT, so we can write something.  if we don't
	 * write anything, we could underrun.
	 */
	if (nblocks < 1)
		nblocks = 1;

	for (i = 0; i < nblocks; i++) {
		sio_write(hdl, sndio_play_bufdata, sndio_play_bufsize);
		sndio_playpos += sndio_play_round;
		if (sio_eof(hdl)) {
			/* print error message? */
			return;
		}
		_mix_some_samples((uintptr_t) sndio_play_bufdata, 0, sndio_signed);
	}
}
コード例 #6
0
ファイル: sndio-input.c プロジェクト: Bluerise/bitrig-ports
static void *
read_thread(void *dp)
{
	sndio_in_driver *d = dp;
	struct pollfd pfd;
	int size, ret, off, nfds;

	if (!sio_start(d->hdl)) {
		error_error("could not start sndio");
		goto done;
	}

	while (d->read_trun) {
		nfds = sio_pollfd(d->hdl, &pfd, POLLIN);
		poll(&pfd, nfds, -1);
		if (sio_revents(d->hdl, &pfd) & POLLIN) {
			size = d->par.rchan * d->par.bps * d->bufsize;
			off = 0;
			while (size > 0) {
				ret = sio_read(d->hdl, d->sndbuf + off, size);
				off += ret;
				size -= ret;
			}
			sample_editor_sampled(d->sndbuf, d->bufsize,
			    d->par.rate, d->mf);
		}
	}
done:
	pthread_exit(NULL);
	return NULL;
}
コード例 #7
0
ファイル: siofile.c プロジェクト: t6/sndio
int
dev_sio_revents(void *arg, struct pollfd *pfd)
{
	struct dev *d = arg;
	int events;

	events = sio_revents(d->sio.hdl, pfd);
#ifdef DEBUG
	d->sio.events = events;
#endif
	return events;
}
コード例 #8
0
int
sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos)
{
	if (s == NULL)
		return SA_ERROR_NO_INIT;

	sio_pollfd(s->handle, &s->pfd, 0);
	poll(&s->pfd, 1, 0);
	sio_revents(s->handle, &s->pfd);
	*pos = s->position;

	return SA_SUCCESS;
}
コード例 #9
0
ファイル: ao_sndio.c プロジェクト: AbhiDGamer/mpv
/*
 * how many bytes can be played without blocking
 */
static int get_space(struct ao *ao)
{
    struct priv *p = ao->priv;
    int n;

    /*
     * call poll() and sio_revents(), so the
     * delay counter is updated
     */
    n = sio_pollfd(p->hdl, p->pfd, POLLOUT);
    while (poll(p->pfd, n, 0) < 0 && errno == EINTR)
        ; /* nothing */
    sio_revents(p->hdl, p->pfd);

    return (p->par.bufsz * p->par.pchan * p->par.bps - p->delay) / ao->sstride;
}
コード例 #10
0
ファイル: swfdec_playback_sndio.c プロジェクト: aharri/ports
static int
swfdec_playback_stream_avail_update (Stream *stream)
{
  struct pollfd pfd;
  int n, revents, used, avail;

  n = sio_pollfd (stream->hdl, &pfd, POLLOUT);
  while (poll (&pfd, n, 0) < 0 && errno == EINTR)
    ;
  revents = sio_revents (stream->hdl, &pfd);

  used = (stream->f_played < 0) ?
    stream->f_written : stream->f_written - stream->f_played;
  avail = stream->par.bufsz - used;

  return avail;
}
コード例 #11
0
ファイル: pa_sndio.c プロジェクト: svn2github/PortAudio
static signed long BlockingGetStreamWriteAvailable(PaStream *stream)
{
    PaSndioStream *s = (PaSndioStream *)stream;
    int n, events;

    n = sio_pollfd(s->hdl, s->pfds, POLLOUT);
    while (poll(s->pfds, n, 0) < 0) {
        if (errno == EINTR)
            continue;
        perror("poll");
        abort();
    }
    events = sio_revents(s->hdl, s->pfds);
    if (!(events & POLLOUT))
        return 0;

    return s->par.bufsz - (s->bytesWritten - s->framesProcessed);
}
コード例 #12
0
ファイル: pa_sndio.c プロジェクト: Bluerise/bitrig-ports
static signed long
BlockingGetStreamWriteAvailable(PaStream *stream)
{
	PaSndioStream *s = (PaSndioStream *)stream;
	struct pollfd pfd;
	int n, events;

	n = sio_pollfd(s->hdl, &pfd, POLLOUT);
	while (poll(&pfd, n, 0) < 0) {
		if (errno == EINTR)
			continue;
		perror("poll");
		abort();
	}
	events = sio_revents(s->hdl, &pfd);
	if (!(events & POLLOUT))
		return 0;

	return s->par.bufsz - (s->wpos - s->realpos);
}
コード例 #13
0
ファイル: siofile.c プロジェクト: UNGLinux/Obase
int
siofile_revents(struct file *file, struct pollfd *pfd)
{
	return sio_revents(((struct siofile *)file)->hdl, pfd);
}
コード例 #14
0
ファイル: cubeb_sndio.c プロジェクト: luke-chang/gecko-1
static void *
sndio_mainloop(void *arg)
{
#define MAXFDS 8
  struct pollfd pfds[MAXFDS];
  cubeb_stream *s = arg;
  int n, eof = 0, prime, nfds, events, revents, state = CUBEB_STATE_STARTED;
  size_t pstart = 0, pend = 0, rstart = 0, rend = 0;
  long nfr;

  DPR("sndio_mainloop()\n");
  s->state_cb(s, s->arg, CUBEB_STATE_STARTED);
  pthread_mutex_lock(&s->mtx);
  if (!sio_start(s->hdl)) {
    pthread_mutex_unlock(&s->mtx);
    return NULL;
  }
  DPR("sndio_mainloop(), started\n");

  if (s->mode & SIO_PLAY) {
    pstart = pend = s->nfr * s->pbpf;
    prime = s->nblks;
    if (s->mode & SIO_REC) {
      memset(s->rbuf, 0, s->nfr * s->rbpf);
      rstart = rend = s->nfr * s->rbpf;
    }
  } else {
    prime = 0;
    rstart = 0;
    rend = s->nfr * s->rbpf;
  }

  for (;;) {
    if (!s->active) {
      DPR("sndio_mainloop() stopped\n");
      state = CUBEB_STATE_STOPPED;
      break;
    }

    /* do we have a complete block? */
    if ((!(s->mode & SIO_PLAY) || pstart == pend) &&
	(!(s->mode & SIO_REC) || rstart == rend)) {

      if (eof) {
        DPR("sndio_mainloop() drained\n");
        state = CUBEB_STATE_DRAINED;
        break;
      }

      if ((s->mode & SIO_REC) && s->conv)
        s16_to_float(s->rbuf, s->nfr * s->rchan);

      /* invoke call-back, it returns less that s->nfr if done */
      pthread_mutex_unlock(&s->mtx);
      nfr = s->data_cb(s, s->arg, s->rbuf, s->pbuf, s->nfr);
      pthread_mutex_lock(&s->mtx);
      if (nfr < 0) {
        DPR("sndio_mainloop() cb err\n");
        state = CUBEB_STATE_ERROR;
        break;
      }
      s->swpos += nfr;

      /* was this last call-back invocation (aka end-of-stream) ? */
      if (nfr < s->nfr) {

        if (!(s->mode & SIO_PLAY) || nfr == 0) {
          state = CUBEB_STATE_DRAINED;
          break;
	}

        /* need to write (aka drain) the partial play block we got */
        pend = nfr * s->pbpf;
        eof = 1;
      }

      if (prime > 0)
        prime--;

      if ((s->mode & SIO_PLAY) && s->conv)
          float_to_s16(s->pbuf, nfr * s->pchan);

      if (s->mode & SIO_REC)
        rstart = 0;
      if (s->mode & SIO_PLAY)
        pstart = 0;
    }

    events = 0;
    if ((s->mode & SIO_REC) && rstart < rend && prime == 0)
      events |= POLLIN;
    if ((s->mode & SIO_PLAY) && pstart < pend)
      events |= POLLOUT;
    nfds = sio_pollfd(s->hdl, pfds, events);

    if (nfds > 0) {
      pthread_mutex_unlock(&s->mtx);
      n = poll(pfds, nfds, -1);
      pthread_mutex_lock(&s->mtx);
      if (n < 0)
        continue;
    }

    revents = sio_revents(s->hdl, pfds);

    if (revents & POLLHUP) {
      state = CUBEB_STATE_ERROR;
      break;
    }

    if (revents & POLLOUT) {
      n = sio_write(s->hdl, s->pbuf + pstart, pend - pstart);
      if (n == 0 && sio_eof(s->hdl)) {
        DPR("sndio_mainloop() werr\n");
        state = CUBEB_STATE_ERROR;
        break;
      }
      pstart += n;
    }

    if (revents & POLLIN) {
      n = sio_read(s->hdl, s->rbuf + rstart, rend - rstart);
      if (n == 0 && sio_eof(s->hdl)) {
        DPR("sndio_mainloop() rerr\n");
        state = CUBEB_STATE_ERROR;
        break;
      }
      rstart += n;
    }

    /* skip rec block, if not recording (yet) */
    if (prime > 0 && (s->mode & SIO_REC))
      rstart = rend;
  }
  sio_stop(s->hdl);
  s->hwpos = s->swpos;
  pthread_mutex_unlock(&s->mtx);
  s->state_cb(s, s->arg, state);
  return NULL;
}
コード例 #15
0
ファイル: vol.c プロジェクト: SylvestreG/bitrig
int
main(int argc, char **argv) {
	int ch;
	int tty;
	struct sio_hdl *hdl;
	struct termios tio;
	struct pollfd pfd[2];
	char cmd;
	ssize_t n, len;
	
	/*
	 * defaults parameters
	 */
	sio_initpar(&par);
	par.sig = 1;
	par.bits = 16;
	par.pchan = 2;
	par.rate = 44100;

	if (isatty(STDIN_FILENO)) {
		fprintf(stderr, "stdin can't be a tty\n");
		exit(1);
	}
	tty = open("/dev/tty", O_RDWR);
	if (tty < 0) {
		perror("/dev/tty");
		exit(1);
	}
	if (tcgetattr(tty, &tio) < 0) {
		perror("tcsetattr");
		exit(1);
	}
	tio.c_lflag &= ~ICANON;
	tio.c_lflag &= ~ECHO;
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 0;
	if (tcsetattr(tty, TCSAFLUSH, &tio) < 0) {
		perror("tcsetattr");
		exit(1);
	}

	while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) {
		switch(ch) {
		case 'r':
			if (sscanf(optarg, "%u", &par.rate) != 1) {
				fprintf(stderr, "%s: bad rate\n", optarg);
				exit(1);
			}
			break;
		case 'c':
			if (sscanf(optarg, "%u", &par.pchan) != 1) {
				fprintf(stderr, "%s: bad channels\n", optarg);
				exit(1);
			}
			break;
		case 'e':
			if (!sio_strtoenc(&par, optarg)) {
				fprintf(stderr, "%s: bad encoding\n", optarg);
				exit(1);
			}
			break;
		default:
			usage();
			exit(1);
			break;
		}
	}

	hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0);
	if (hdl == NULL) {
		fprintf(stderr, "sio_open() failed\n");
		exit(1);
	}
	if (!sio_setpar(hdl, &par)) {
		fprintf(stderr, "sio_setpar() failed\n");
		exit(1);
	}
	if (!sio_onvol(hdl, onvol, NULL))
		fprintf(stderr, "warning: no volume knob on this device\n");
	fprintf(stderr, "use ``+'' and ``-'' to adjust the volume\n");
	if (!sio_start(hdl)) {
		fprintf(stderr, "sio_start() failed\n");
		exit(1);
	}
	for (;;) {
		pfd[0].fd = tty;
		pfd[0].events = POLLIN;
		sio_pollfd(hdl, &pfd[1], POLLOUT);
		if (poll(pfd, 2, -1) < 0) {
			perror("poll");
			exit(1);
		}
		if (pfd[0].revents & POLLIN) {
			if (read(tty, &cmd, 1) < 0) {
				perror("read(tty)");
				exit(1);
			}
			switch (cmd) {
			case '+':
				if (vol < SIO_MAXVOL) {
					vol++;
					sio_setvol(hdl, vol);
				}
				break;
			case '-':
				if (vol > 0) {
					vol--;
					sio_setvol(hdl, vol);
				}
				break;
			}
		}
		if (sio_revents(hdl, &pfd[1]) & POLLOUT) {
			len = read(STDIN_FILENO, buf, BUFSZ);
			if (len < 0) {
				perror("stdin");
				exit(1);
			}
			if (len == 0)
				break;
			n = sio_write(hdl, buf, len);
			if (n == 0) {
				fprintf(stderr, "sio_write: failed\n");
				exit(1);
			}
		}
	}
	sio_close(hdl);
	return 0;
}
コード例 #16
0
ファイル: cubeb_sndio.c プロジェクト: MichaelKohler/gecko-dev
static void *
sndio_mainloop(void *arg)
{
#define MAXFDS 8
  struct pollfd pfds[MAXFDS];
  cubeb_stream *s = arg;
  int n, nfds, revents, state = CUBEB_STATE_STARTED;
  size_t start = 0, end = 0;
  long nfr;

  DPR("sndio_mainloop()\n");
  s->state_cb(s, s->arg, CUBEB_STATE_STARTED);
  pthread_mutex_lock(&s->mtx);
  if (!sio_start(s->hdl)) {
    pthread_mutex_unlock(&s->mtx);
    return NULL;
  }
  DPR("sndio_mainloop(), started\n");

  start = end = s->nfr;
  for (;;) {
    if (!s->active) {
      DPR("sndio_mainloop() stopped\n");
      state = CUBEB_STATE_STOPPED;
      break;
    }
    if (start == end) {
      if (end < s->nfr) {
        DPR("sndio_mainloop() drained\n");
        state = CUBEB_STATE_DRAINED;
        break;
      }
      pthread_mutex_unlock(&s->mtx);
      nfr = s->data_cb(s, s->arg, NULL, s->buf, s->nfr);
      pthread_mutex_lock(&s->mtx);
      if (nfr < 0) {
        DPR("sndio_mainloop() cb err\n");
        state = CUBEB_STATE_ERROR;
        break;
      }
      if (s->conv)
        float_to_s16(s->buf, nfr * s->pchan);
      start = 0;
      end = nfr * s->bpf;
    }
    if (end == 0)
      continue;
    nfds = sio_pollfd(s->hdl, pfds, POLLOUT);
    if (nfds > 0) {
      pthread_mutex_unlock(&s->mtx);
      n = poll(pfds, nfds, -1);
      pthread_mutex_lock(&s->mtx);
      if (n < 0)
        continue;
    }
    revents = sio_revents(s->hdl, pfds);
    if (revents & POLLHUP)
      break;
    if (revents & POLLOUT) {
      n = sio_write(s->hdl, s->buf + start, end - start);
      if (n == 0) {
        DPR("sndio_mainloop() werr\n");
        state = CUBEB_STATE_ERROR;
        break;
      }
      s->wrpos += n;
      start += n;
    }
  }
  sio_stop(s->hdl);
  s->rdpos = s->wrpos;
  pthread_mutex_unlock(&s->mtx);
  s->state_cb(s, s->arg, state);
  return NULL;
}