typedef struct snd_pcm_extplug snd_pcm_extplug_t;
typedef struct snd_pcm_extplug_callback snd_pcm_extplug_callback_t;
+/**
+ * Protocol version
+ */
+#define SND_PCM_EXTPLUG_VERSION_MAJOR 1
+#define SND_PCM_EXTPLUG_VERSION_MINOR 0
+#define SND_PCM_EXTPLUG_VERSION_TINY 0
+#define SND_PCM_EXTPLUG_VERSION ((SND_PCM_EXTPLUG_VERSION_MAJOR<<16) |\
+ (SND_PCM_EXTPLUG_VERSION_MINOR<<8) |\
+ (SND_PCM_EXTPLUG_VERSION_TINY))
+
/** handle of extplug */
struct snd_pcm_extplug {
+ /**
+ * protocol version; SND_PCM_EXTPLUG_VERSION must be filled here
+ * before calling #snd_pcm_extplug_create()
+ */
+ unsigned int version;
/**
* name of this plugin; must be filled before calling #snd_pcm_extplug_create()
*/
*/
#define SND_PCM_IOPLUG_FLAG_LISTED (1<<0) /* list up this PCM */
+/**
+ * Protocol version
+ */
+#define SND_PCM_IOPLUG_VERSION_MAJOR 1
+#define SND_PCM_IOPLUG_VERSION_MINOR 0
+#define SND_PCM_IOPLUG_VERSION_TINY 0
+#define SND_PCM_IOPLUG_VERSION ((SND_PCM_IOPLUG_VERSION_MAJOR<<16) |\
+ (SND_PCM_IOPLUG_VERSION_MINOR<<8) |\
+ (SND_PCM_IOPLUG_VERSION_TINY))
+
/** handle of ioplug */
struct snd_pcm_ioplug {
+ /**
+ * protocol version; SND_PCM_IOPLUG_VERSION must be filled here
+ * before calling #snd_pcm_ioplug_create()
+ */
+ unsigned int version;
/**
* name of this plugin; must be filled before calling #snd_pcm_ioplug_create()
*/
* resume; optional
*/
int (*resume)(snd_pcm_ioplug_t *io);
+ /**
+ * poll descriptors count; optional
+ */
+ int (*poll_descriptors_count)(snd_pcm_ioplug_t *io);
+ /**
+ * poll descriptors; optional
+ */
+ int (*poll_descriptors)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int space);
/**
* mangle poll events; optional
*/
.dump = snd_pcm_extplug_dump,
.nonblock = snd_pcm_generic_nonblock,
.async = snd_pcm_generic_async,
+ .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
+ .poll_descriptors = snd_pcm_generic_poll_descriptors,
.poll_revents = snd_pcm_generic_poll_revents,
.mmap = snd_pcm_generic_mmap,
.munmap = snd_pcm_generic_munmap,
assert(extplug->callback->transfer);
assert(slave_conf);
+ if (extplug->version != SND_PCM_EXTPLUG_VERSION) {
+ SNDERR("extplug: Plugin version mismatch\n");
+ return -ENXIO;
+ }
+
err = snd_pcm_slave_conf(root, slave_conf, &sconf, 0);
if (err < 0)
return err;
int change = 0, change1, change2, err;
ioplug_priv_t *io = pcm->private_data;
struct snd_ext_parm *p;
- int i;
+ unsigned int i;
/* access, format */
for (i = SND_PCM_IOPLUG_HW_ACCESS; i <= SND_PCM_IOPLUG_HW_FORMAT; i++) {
return 0;
}
+static int snd_pcm_ioplug_poll_descriptors_count(snd_pcm_t *pcm)
+{
+ ioplug_priv_t *io = pcm->private_data;
+
+ if (io->data->callback->poll_descriptors_count)
+ return io->data->callback->poll_descriptors_count(io->data);
+ else
+ return 1;
+}
+
+static int snd_pcm_ioplug_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
+{
+ ioplug_priv_t *io = pcm->private_data;
+
+ if (io->data->callback->poll_descriptors)
+ return io->data->callback->poll_descriptors(io->data, pfds, space);
+ if (pcm->poll_fd < 0)
+ return -EIO;
+ if (space >= 1 && pfds) {
+ pfds->fd = pcm->poll_fd;
+ pfds->events = pcm->poll_events | POLLERR | POLLNVAL;
+ } else {
+ return 0;
+ }
+ return 1;
+}
+
static int snd_pcm_ioplug_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
ioplug_priv_t *io = pcm->private_data;
.close = snd_pcm_ioplug_close,
.nonblock = snd_pcm_ioplug_nonblock,
.async = snd_pcm_ioplug_async,
+ .poll_descriptors_count = snd_pcm_ioplug_poll_descriptors_count,
+ .poll_descriptors = snd_pcm_ioplug_poll_descriptors,
.poll_revents = snd_pcm_ioplug_poll_revents,
.info = snd_pcm_ioplug_info,
.hw_refine = snd_pcm_ioplug_hw_refine,
ioplug->callback->stop &&
ioplug->callback->pointer);
+ if (ioplug->version != SND_PCM_IOPLUG_VERSION) {
+ SNDERR("ioplug: Plugin version mismatch\n");
+ return -ENXIO;
+ }
+
io = calloc(1, sizeof(*io));
if (! io)
return -ENOMEM;