From 769439a0fff3db34ff0e3ce91636017afcdb652b Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 11 Feb 2004 19:09:03 +0000 Subject: [PATCH] - finished poll/select related functions for ALSA->OSS pcm emulation - fixed some trivial bugs - mpg123 works again using libaoss --- alsa/alsa-oss.c | 11 ++- alsa/mixer.c | 2 +- alsa/pcm.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 200 insertions(+), 5 deletions(-) diff --git a/alsa/alsa-oss.c b/alsa/alsa-oss.c index af67477..cd20968 100644 --- a/alsa/alsa-oss.c +++ b/alsa/alsa-oss.c @@ -73,7 +73,6 @@ static ops_t ops[FD_CLASSES]; typedef struct { int count; fd_class_t class; - void *private; void *mmap_area; } fd_t; @@ -195,6 +194,12 @@ int open(const char *file, int oflag, ...) !strncmp(file, "/dev/audio", 10)) { fd = lib_oss_pcm_open(file, oflag); if (fd >= 0) { + fds[fd] = calloc(sizeof(fd_t), 1); + if (fds[fd] == NULL) { + ops[FD_OSS_DSP].close(fd); + errno = ENOMEM; + return -1; + } fds[fd]->class = FD_OSS_DSP; poll_fds_add += lib_oss_pcm_poll_fds(fd); } @@ -216,7 +221,7 @@ int close(int fd) } else { fd_t *xfd = fds[fd]; int err; - + fds[fd] = NULL; poll_fds_add -= lib_oss_pcm_poll_fds(fd); err = ops[xfd->class].close(fd); @@ -251,7 +256,7 @@ int ioctl(int fd, unsigned long request, ...) va_end(args); if (fd < 0 || fd >= open_max || fds[fd] == NULL) return _ioctl(fd, request, arg); - else + else return ops[fds[fd]->class].ioctl(fd, request, arg); } diff --git a/alsa/mixer.c b/alsa/mixer.c index 2248739..c0e86cc 100644 --- a/alsa/mixer.c +++ b/alsa/mixer.c @@ -245,7 +245,7 @@ static int oss_mixer_open(int card, int device, int oflag, mode_t mode ATTRIBUTE result = snd_mixer_load(mixer->mix); if (result < 0) goto _error1; - mixer->fileno = result; + mixer->fileno = fd; insert_fd(mixer); return fd; _error1: diff --git a/alsa/pcm.c b/alsa/pcm.c index 571e324..1abec35 100644 --- a/alsa/pcm.c +++ b/alsa/pcm.c @@ -549,7 +549,7 @@ static int oss_dsp_open(int card, int device, int oflag, mode_t mode) result = oss_dsp_params(dsp); if (result < 0) goto _error; - xfd->fileno = result; + xfd->fileno = fd; insert_fd(xfd); return fd; @@ -1264,6 +1264,196 @@ int lib_oss_pcm_munmap(void *addr, size_t len) return 0; } +int lib_oss_pcm_select_prepare(int fd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) +{ + oss_dsp_t *dsp = look_for_dsp(fd); + int k; + + if (dsp == NULL) { + errno = EBADFD; + return -1; + } + for (k = 0; k < 2; ++k) { + snd_pcm_t *pcm = dsp->streams[k].pcm; + int err, count; + if (!pcm) + continue; + count = snd_pcm_poll_descriptors_count(pcm); + if (count < 0) { + errno = -count; + return -1; + } + { + struct pollfd ufds[count]; + int j; + err = snd_pcm_poll_descriptors(pcm, ufds, count); + if (err < 0) { + errno = -err; + return -1; + } + for (j = 0; j < count; j++) { + int fd = ufds[j].fd; + unsigned short events = ufds[j].events; + FD_CLR(fd, readfds); + FD_CLR(fd, writefds); + FD_CLR(fd, exceptfds); + if (events & POLLIN) + FD_SET(fd, readfds); + if (events & POLLOUT) + FD_SET(fd, writefds); + if (events & (POLLERR|POLLNVAL)) + FD_SET(fd, exceptfds); + } + } + } + return 0; +} + +int lib_oss_pcm_select_result(int fd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) +{ + oss_dsp_t *dsp = look_for_dsp(fd); + int k, result = 0; + + if (dsp == NULL) { + errno = EBADFD; + return -1; + } + for (k = 0; k < 2; ++k) { + snd_pcm_t *pcm = dsp->streams[k].pcm; + int err, count; + if (!pcm) + continue; + count = snd_pcm_poll_descriptors_count(pcm); + if (count < 0) { + errno = -count; + return -1; + } + { + struct pollfd ufds[count]; + int j; + unsigned short revents; + err = snd_pcm_poll_descriptors(pcm, ufds, count); + if (err < 0) { + errno = -err; + return -1; + } + for (j = 0; j < count; j++) { + int fd = ufds[j].fd; + revents = 0; + if (FD_ISSET(fd, readfds)) + revents |= POLLIN; + if (FD_ISSET(fd, writefds)) + revents |= POLLOUT; + if (FD_ISSET(fd, exceptfds)) + revents |= POLLERR; + ufds[j].revents = revents; + } + err = snd_pcm_poll_descriptors_revents(pcm, ufds, count, &revents); + if (err < 0) { + errno = -err; + return -1; + } + if (revents & (POLLNVAL|POLLERR)) + result |= OSS_WAIT_EVENT_ERROR; + if (revents & POLLIN) + result |= OSS_WAIT_EVENT_READ; + if (revents & POLLIN) + result |= OSS_WAIT_EVENT_WRITE; + } + } + return result; +} + +extern int lib_oss_pcm_poll_fds(int fd) +{ + oss_dsp_t *dsp = look_for_dsp(fd); + int k, result = 0; + + if (dsp == NULL) { + errno = EBADFD; + return -1; + } + for (k = 0; k < 2; ++k) { + snd_pcm_t *pcm = dsp->streams[k].pcm; + int err; + if (!pcm) + continue; + err = snd_pcm_poll_descriptors_count(pcm); + if (err < 0) { + errno = -err; + return -1; + } + result += err; + } + return result; +} + +int lib_oss_pcm_poll_prepare(int fd, struct pollfd *ufds) +{ + oss_dsp_t *dsp = look_for_dsp(fd); + int k; + + if (dsp == NULL) { + errno = EBADFD; + return -1; + } + for (k = 0; k < 2; ++k) { + snd_pcm_t *pcm = dsp->streams[k].pcm; + int err, count; + if (!pcm) + continue; + count = snd_pcm_poll_descriptors_count(pcm); + if (count < 0) { + errno = -count; + return -1; + } + err = snd_pcm_poll_descriptors(pcm, ufds, count); + if (err < 0) { + errno = -err; + return -1; + } + ufds += count; + } + return 0; +} + +int lib_oss_pcm_poll_result(int fd, struct pollfd *ufds) +{ + oss_dsp_t *dsp = look_for_dsp(fd); + int k, result = 0; + + if (dsp == NULL) { + errno = EBADFD; + return -1; + } + for (k = 0; k < 2; ++k) { + snd_pcm_t *pcm = dsp->streams[k].pcm; + int err, count; + unsigned short revents; + if (!pcm) + continue; + count = snd_pcm_poll_descriptors_count(pcm); + if (count < 0) { + errno = -count; + return -1; + } + err = snd_pcm_poll_descriptors_revents(pcm, ufds, count, &revents); + if (err < 0) { + errno = -err; + return -1; + } + if (revents & (POLLNVAL|POLLERR)) + result |= OSS_WAIT_EVENT_ERROR; + if (revents & POLLIN) + result |= OSS_WAIT_EVENT_READ; + if (revents & POLLIN) + result |= OSS_WAIT_EVENT_WRITE; + ufds += count; + } + return result; +} + + static void error_handler(const char *file ATTRIBUTE_UNUSED, int line ATTRIBUTE_UNUSED, const char *func ATTRIBUTE_UNUSED, -- 2.47.1