Added snd_*_poll_descriptors_revents functions.
This commit is contained in:
parent
23ab0b3509
commit
ddb7209e9a
15 changed files with 195 additions and 36 deletions
|
@ -201,6 +201,7 @@ int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
|
|||
snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler);
|
||||
int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl);
|
||||
int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space);
|
||||
int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe);
|
||||
int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info);
|
||||
int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t * list);
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct _snd_hwdep snd_hwdep_t;
|
|||
int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode);
|
||||
int snd_hwdep_close(snd_hwdep_t *hwdep);
|
||||
int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space);
|
||||
int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock);
|
||||
int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info);
|
||||
int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg);
|
||||
|
|
|
@ -90,6 +90,7 @@ int snd_mixer_attach(snd_mixer_t *mixer, const char *name);
|
|||
int snd_mixer_detach(snd_mixer_t *mixer, const char *name);
|
||||
int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer);
|
||||
int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space);
|
||||
int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_mixer_load(snd_mixer_t *mixer);
|
||||
void snd_mixer_free(snd_mixer_t *mixer);
|
||||
int snd_mixer_wait(snd_mixer_t *mixer, int timeout);
|
||||
|
|
|
@ -362,6 +362,7 @@ snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
|
|||
snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm);
|
||||
int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm);
|
||||
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
|
||||
int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
|
||||
int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
|
||||
snd_async_callback_t callback, void *private_data);
|
||||
|
@ -710,7 +711,7 @@ void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_su
|
|||
void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask);
|
||||
void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask);
|
||||
int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
|
||||
int snd_pcm_subformat_mask_empty(const snd_pcm_format_mask_t *mask);
|
||||
int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask);
|
||||
void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
|
||||
void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ int snd_rawmidi_open_lconf(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
|
|||
int snd_rawmidi_close(snd_rawmidi_t *rmidi);
|
||||
int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rmidi);
|
||||
int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rmidi, struct pollfd *pfds, unsigned int space);
|
||||
int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revent);
|
||||
int snd_rawmidi_nonblock(snd_rawmidi_t *rmidi, int nonblock);
|
||||
size_t snd_rawmidi_info_sizeof(void);
|
||||
/** \hideinitializer
|
||||
|
|
|
@ -90,6 +90,7 @@ snd_seq_type_t snd_seq_type(snd_seq_t *seq);
|
|||
int snd_seq_close(snd_seq_t *handle);
|
||||
int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events);
|
||||
int snd_seq_poll_descriptors(snd_seq_t *handle, struct pollfd *pfds, unsigned int space, short events);
|
||||
int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_seq_nonblock(snd_seq_t *handle, int nonblock);
|
||||
int snd_seq_client_id(snd_seq_t *handle);
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ int snd_timer_open_lconf(snd_timer_t **handle, const char *name, int mode, snd_c
|
|||
int snd_timer_close(snd_timer_t *handle);
|
||||
int snd_timer_poll_descriptors_count(snd_timer_t *handle);
|
||||
int snd_timer_poll_descriptors(snd_timer_t *handle, struct pollfd *pfds, unsigned int space);
|
||||
int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer);
|
||||
int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params);
|
||||
int snd_timer_status(snd_timer_t *handle, snd_timer_status_t *status);
|
||||
|
|
|
@ -160,15 +160,33 @@ int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl)
|
|||
*/
|
||||
int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space)
|
||||
{
|
||||
assert(ctl);
|
||||
assert(ctl && pfds);
|
||||
if (space > 0) {
|
||||
pfds->fd = ctl->poll_fd;
|
||||
pfds->events = POLLIN;
|
||||
pfds->events = POLLIN|POLLERR;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get returned events from poll descriptors
|
||||
* \param ctl CTL handle
|
||||
* \param pfds array of poll descriptors
|
||||
* \param nfds count of poll descriptors
|
||||
* \param revents returned events
|
||||
* \return zero if success, otherwise a negative error code
|
||||
*/
|
||||
int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
assert(ctl && pfds && revents);
|
||||
if (nfds == 1) {
|
||||
*revents = pfds->revents;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Ask to be informed about events (poll, #snd_ctl_async, #snd_ctl_read)
|
||||
* \param ctl CTL handle
|
||||
|
|
|
@ -260,13 +260,13 @@ int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned
|
|||
pfds->fd = hwdep->poll_fd;
|
||||
switch (hwdep->mode & O_ACCMODE) {
|
||||
case O_WRONLY:
|
||||
pfds->events = POLLOUT;
|
||||
pfds->events = POLLOUT|POLLERR;
|
||||
break;
|
||||
case O_RDONLY:
|
||||
pfds->events = POLLIN;
|
||||
pfds->events = POLLIN|POLLERR;
|
||||
break;
|
||||
case O_RDWR:
|
||||
pfds->events = POLLOUT|POLLIN;
|
||||
pfds->events = POLLOUT|POLLIN|POLLERR;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
|
@ -276,6 +276,24 @@ int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get returned events from poll descriptors
|
||||
* \param hwdep HwDep handle
|
||||
* \param pfds array of poll descriptors
|
||||
* \param nfds count of poll descriptors
|
||||
* \param revents returned events
|
||||
* \return zero if success, otherwise a negative error code
|
||||
*/
|
||||
int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
assert(hwdep && pfds && revents);
|
||||
if (nfds == 1) {
|
||||
*revents = pfds->revents;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief set nonblock mode
|
||||
* \param hwdep HwDep handle
|
||||
|
|
|
@ -599,6 +599,28 @@ int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned
|
|||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get returned events from poll descriptors
|
||||
* \param mixer Mixer handle
|
||||
* \param pfds array of poll descriptors
|
||||
* \param nfds count of poll descriptors
|
||||
* \param revents returned events
|
||||
* \return zero if success, otherwise a negative error code
|
||||
*/
|
||||
int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
unsigned int idx;
|
||||
unsigned short res;
|
||||
assert(mixer && pfds && revents);
|
||||
if (nfds == 0)
|
||||
return -EINVAL;
|
||||
res = 0;
|
||||
for (idx = 0; idx < nfds; idx++)
|
||||
res |= pfds->revents & (POLLIN|POLLERR);
|
||||
*revents = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Wait for a mixer to become ready (i.e. at least one event pending)
|
||||
* \param mixer Mixer handle
|
||||
|
|
|
@ -1003,14 +1003,33 @@ int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)
|
|||
*/
|
||||
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
|
||||
{
|
||||
assert(pcm);
|
||||
if (space >= 1) {
|
||||
assert(pcm && pfds);
|
||||
if (space >= 1 && pfds) {
|
||||
pfds->fd = pcm->poll_fd;
|
||||
pfds->events = pcm->stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
|
||||
}
|
||||
pfds->events = pcm->stream == SND_PCM_STREAM_PLAYBACK ? (POLLOUT|POLLERR) : (POLLIN|POLLERR);
|
||||
} else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get returned events from poll descriptors
|
||||
* \param pcm PCM handle
|
||||
* \param pfds array of poll descriptors
|
||||
* \param nfds count of poll descriptors
|
||||
* \param revents returned events
|
||||
* \return zero if success, otherwise a negative error code
|
||||
*/
|
||||
int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
assert(pcm && pfds && revents);
|
||||
if (nfds == 1) {
|
||||
*revents = pfds->revents;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
#define STATE(v) [SND_PCM_STATE_##v] = #v
|
||||
#define STREAM(v) [SND_PCM_STREAM_##v] = #v
|
||||
|
|
|
@ -313,12 +313,30 @@ int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rawmidi, struct pollfd *pfds, un
|
|||
assert(rawmidi);
|
||||
if (space >= 1) {
|
||||
pfds->fd = rawmidi->poll_fd;
|
||||
pfds->events = rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT ? POLLOUT : POLLIN;
|
||||
pfds->events = rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT ? (POLLOUT|POLLERR) : (POLLIN|POLLERR);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get returned events from poll descriptors
|
||||
* \param pcm rawmidi RawMidi handle
|
||||
* \param pfds array of poll descriptors
|
||||
* \param nfds count of poll descriptors
|
||||
* \param revents returned events
|
||||
* \return zero if success, otherwise a negative error code
|
||||
*/
|
||||
int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
assert(rawmidi && pfds && revents);
|
||||
if (nfds == 1) {
|
||||
*revents = pfds->revents;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief set nonblock mode
|
||||
* \param rawmidi RawMidi handle
|
||||
|
|
|
@ -305,11 +305,11 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
|
|||
assert(seq);
|
||||
if ((events & POLLIN) && space >= 1) {
|
||||
assert(seq->streams & SND_SEQ_OPEN_INPUT);
|
||||
revents |= POLLIN;
|
||||
revents |= POLLIN|POLLERR;
|
||||
}
|
||||
if ((events & POLLOUT) && space >= 1) {
|
||||
assert(seq->streams & SND_SEQ_OPEN_INPUT);
|
||||
revents |= POLLOUT;
|
||||
revents |= POLLOUT|POLLERR;
|
||||
}
|
||||
if (!revents)
|
||||
return 0;
|
||||
|
@ -318,6 +318,24 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get returned events from poll descriptors
|
||||
* \param seq sequencer handle
|
||||
* \param pfds array of poll descriptors
|
||||
* \param nfds count of poll descriptors
|
||||
* \param revents returned events
|
||||
* \return zero if success, otherwise a negative error code
|
||||
*/
|
||||
int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
assert(seq && pfds && revents);
|
||||
if (nfds == 1) {
|
||||
*revents = pfds->revents;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set nonblock mode
|
||||
* \param seq sequencer handle
|
||||
|
|
|
@ -261,13 +261,13 @@ int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned
|
|||
pfds->fd = timer->poll_fd;
|
||||
switch (timer->mode & O_ACCMODE) {
|
||||
case O_WRONLY:
|
||||
pfds->events = POLLOUT;
|
||||
pfds->events = POLLOUT|POLLERR;
|
||||
break;
|
||||
case O_RDONLY:
|
||||
pfds->events = POLLIN;
|
||||
pfds->events = POLLIN|POLLERR;
|
||||
break;
|
||||
case O_RDWR:
|
||||
pfds->events = POLLOUT|POLLIN;
|
||||
pfds->events = POLLOUT|POLLIN|POLLERR;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
|
@ -277,6 +277,24 @@ int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get returned events from poll descriptors
|
||||
* \param timer timer handle
|
||||
* \param pfds array of poll descriptors
|
||||
* \param nfds count of poll descriptors
|
||||
* \param revents returned events
|
||||
* \return zero if success, otherwise a negative error code
|
||||
*/
|
||||
int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
assert(timer && pfds && revents);
|
||||
if (nfds == 1) {
|
||||
*revents = pfds->revents;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief set nonblock mode
|
||||
* \param timer timer handle
|
||||
|
|
47
test/pcm.c
47
test/pcm.c
|
@ -226,23 +226,18 @@ static int write_loop(snd_pcm_t *handle,
|
|||
* Transfer method - write and wait for room in buffer using poll
|
||||
*/
|
||||
|
||||
static int wait_for_poll(struct pollfd *ufds, int count)
|
||||
static int wait_for_poll(snd_pcm_t *handle, struct pollfd *ufds, unsigned int count)
|
||||
{
|
||||
int i;
|
||||
unsigned int events;
|
||||
unsigned short revents;
|
||||
|
||||
while (1) {
|
||||
poll(ufds, count, -1);
|
||||
for (i = 0; i < count; i++) {
|
||||
events = ufds[i].revents;
|
||||
if (events & POLLERR) {
|
||||
printf("Poll - POLLERR detected\n");
|
||||
snd_pcm_poll_descriptors_revents(handle, ufds, count, &revents);
|
||||
if (revents & POLLERR)
|
||||
return -EIO;
|
||||
}
|
||||
if (events & POLLOUT)
|
||||
if (revents & POLLOUT)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int write_and_poll_loop(snd_pcm_t *handle,
|
||||
|
@ -252,7 +247,7 @@ static int write_and_poll_loop(snd_pcm_t *handle,
|
|||
struct pollfd *ufds;
|
||||
double phase = 0;
|
||||
signed short *ptr;
|
||||
int err, count, cptr;
|
||||
int err, count, cptr, init;
|
||||
|
||||
count = snd_pcm_poll_descriptors_count (handle);
|
||||
if (count <= 0) {
|
||||
|
@ -270,12 +265,25 @@ static int write_and_poll_loop(snd_pcm_t *handle,
|
|||
return err;
|
||||
}
|
||||
|
||||
init = 1;
|
||||
while (1) {
|
||||
err = wait_for_poll(ufds, count);
|
||||
if (!init) {
|
||||
err = wait_for_poll(handle, ufds, count);
|
||||
if (err < 0) {
|
||||
if (snd_pcm_state(handle) == SND_PCM_STATE_XRUN ||
|
||||
snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED) {
|
||||
err = snd_pcm_state(handle) == SND_PCM_STATE_XRUN ? -EPIPE : -ESTRPIPE;
|
||||
if (xrun_recovery(handle, err) < 0) {
|
||||
printf("Write error: %s\n", snd_strerror(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
init = 1;
|
||||
} else {
|
||||
printf("Wait for poll failed\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generate_sine(areas, 0, period_size, &phase);
|
||||
ptr = samples;
|
||||
|
@ -287,21 +295,34 @@ static int write_and_poll_loop(snd_pcm_t *handle,
|
|||
printf("Write error: %s\n", snd_strerror(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
init = 1;
|
||||
break; /* skip one period */
|
||||
}
|
||||
if (snd_pcm_state(handle) == SND_PCM_STATE_RUNNING)
|
||||
init = 0;
|
||||
ptr += err * channels;
|
||||
cptr -= err;
|
||||
if (cptr == 0)
|
||||
break;
|
||||
/* it is possible, that initial buffer cannot store */
|
||||
/* all data from last period, so wait awhile */
|
||||
err = wait_for_poll(ufds, count);
|
||||
err = wait_for_poll(handle, ufds, count);
|
||||
if (err < 0) {
|
||||
if (snd_pcm_state(handle) == SND_PCM_STATE_XRUN ||
|
||||
snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED) {
|
||||
err = snd_pcm_state(handle) == SND_PCM_STATE_XRUN ? -EPIPE : -ESTRPIPE;
|
||||
if (xrun_recovery(handle, err) < 0) {
|
||||
printf("Write error: %s\n", snd_strerror(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
init = 1;
|
||||
} else {
|
||||
printf("Wait for poll failed\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue