Snap for 6379934 from d32f5fd92bc28ca83caf1ec9414e84474c2357af to r-keystone-qcom-release
Change-Id: Id79853abc81ee5941435be6adb2f409771e4d846
diff --git a/Android.bp b/Android.bp
index 137aa65..090d91c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7,12 +7,7 @@
},
srcs: [
"mixer.c",
- "mixer_hw.c",
- "mixer_plugin.c",
"pcm.c",
- "pcm_hw.c",
- "pcm_plugin.c",
- "snd_utils.c",
],
cflags: ["-Werror", "-Wno-macro-redefined"],
export_include_dirs: ["include"],
@@ -23,8 +18,6 @@
enabled: false,
},
},
-
- system_shared_libs: ["libc","libdl"],
}
cc_binary {
diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h
index 364e385..935c8d0 100644
--- a/include/tinyalsa/asoundlib.h
+++ b/include/tinyalsa/asoundlib.h
@@ -31,7 +31,6 @@
#include <sys/time.h>
#include <stddef.h>
-#include <sound/asound.h>
#if defined(__cplusplus)
extern "C" {
@@ -318,7 +317,6 @@
int mixer_subscribe_events(struct mixer *mixer, int subscribe);
int mixer_wait_event(struct mixer *mixer, int timeout);
int mixer_consume_event(struct mixer *mixer);
-int mixer_read_event(struct mixer *mixer, struct snd_ctl_event *ev);
#if defined(__cplusplus)
} /* extern "C" */
diff --git a/include/tinyalsa/mixer_plugin.h b/include/tinyalsa/mixer_plugin.h
deleted file mode 100644
index 144c9a7..0000000
--- a/include/tinyalsa/mixer_plugin.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-
-#ifndef __MIXER_PLUGIN_H__
-#define __MIXER_PLUGIN_H__
-
-#define MIXER_PLUGIN_OPEN_FN(name) \
- int name##_open(struct mixer_plugin **plugin, \
- unsigned int card)
-
-#define MIXER_PLUGIN_OPEN_FN_PTR() \
- int (*mixer_plugin_open_fn) (struct mixer_plugin **plugin, \
- unsigned int card) \
-
-struct mixer_plugin;
-
-typedef void (*event_callback)(struct mixer_plugin *);
-
-struct mixer_plugin_ops {
- void (*close) (struct mixer_plugin **plugin);
- int (*subscribe_events) (struct mixer_plugin *plugin,
- event_callback event_cb);
- ssize_t (*read_event) (struct mixer_plugin *plugin,
- struct snd_ctl_event *ev, size_t size);
-};
-
-struct snd_control {
- snd_ctl_elem_iface_t iface;
- unsigned int access;
- const char *name;
- snd_ctl_elem_type_t type;
- void *value;
- int (*get) (struct mixer_plugin *plugin,
- struct snd_control *control,
- struct snd_ctl_elem_value *ev);
- int (*put) (struct mixer_plugin *plugin,
- struct snd_control *control,
- struct snd_ctl_elem_value *ev);
- uint32_t private_value;
- void *private_data;
-};
-
-struct mixer_plugin {
- unsigned int card;
- struct mixer_plugin_ops *ops;
- void *priv;
-
- int eventfd;
- int subscribed;
- int event_cnt;
-
- struct snd_control *controls;
- unsigned int num_controls;
-};
-
-struct snd_value_enum {
- unsigned int items;
- char **texts;
-};
-
-struct snd_value_bytes {
- unsigned int size;
-};
-
-struct snd_value_tlv_bytes {
- unsigned int size;
- int (*get) (struct mixer_plugin *plugin,
- struct snd_control *control,
- struct snd_ctl_tlv *tlv);
- int (*put) (struct mixer_plugin *plugin,
- struct snd_control *control,
- struct snd_ctl_tlv *tlv);
-};
-
-struct snd_value_int {
- unsigned int count;
- int min;
- int max;
- int step;
-};
-
-/* static initializers */
-
-#define SND_VALUE_ENUM(etexts, eitems) \
- {.texts = etexts, .items = eitems}
-
-#define SND_VALUE_BYTES(csize) \
- {.size = csize }
-
-#define SND_VALUE_INTEGER(icount, imin, imax, istep) \
- {.count = icount, .min = imin, .max = imax, .step = istep }
-
-#define SND_VALUE_TLV_BYTES(csize, cget, cput) \
- {.size = csize, .get = cget, .put = cput }
-
-#define SND_CONTROL_ENUM(cname, cget, cput, cenum, priv_val, priv_data) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, \
- .name = cname, .value = &cenum, .get = cget, .put = cput, \
- .private_value = priv_val, .private_data = priv_data, \
- }
-
-#define SND_CONTROL_BYTES(cname, cget, cput, cbytes, priv_val, priv_data) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .type = SNDRV_CTL_ELEM_TYPE_BYTES, \
- .name = cname, .value = &cbytes, .get = cget, .put = cput, \
- .private_value = priv_val, .private_data = priv_data, \
- }
-
-#define SND_CONTROL_INTEGER(cname, cget, cput, cint, priv_val, priv_data) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .type = SNDRV_CTL_ELEM_TYPE_INTEGER, \
- .name = cname, .value = &cint, .get = cget, .put = cput, \
- .private_value = priv_val, .private_data = priv_data, \
- }
-
-#define SND_CONTROL_TLV_BYTES(cname, cbytes, priv_val, priv_data) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE, \
- .type = SNDRV_CTL_ELEM_TYPE_BYTES, \
- .name = cname, .value = &cbytes, \
- .private_value = priv_val, .private_data = priv_data, \
- }
-
-/* pointer based initializers */
-#define INIT_SND_CONTROL_INTEGER(c, cname, cget, cput, cint, pval, pdata) \
- { \
- c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \
- c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \
- c->type = SNDRV_CTL_ELEM_TYPE_INTEGER; \
- c->name = cname; c->value = &cint; c->get = cget; c->put = cput; \
- c->private_value = pval; c->private_data = pdata; \
- }
-
-#define INIT_SND_CONTROL_BYTES(c, cname, cget, cput, cint, pval, pdata) \
- { \
- c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \
- c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \
- c->type = SNDRV_CTL_ELEM_TYPE_BYTES; \
- c->name = cname; c->value = &cint; c->get = cget; c->put = cput; \
- c->private_value = pval; c->private_data = pdata; \
- }
-
-#define INIT_SND_CONTROL_ENUM(c, cname, cget, cput, cenum, pval, pdata) \
- { \
- c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \
- c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \
- c->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \
- c->name = cname; c->value = cenum; c->get = cget; c->put = cput; \
- c->private_value = pval; c->private_data = pdata; \
- }
-#define INIT_SND_CONTROL_TLV_BYTES(c, cname, cbytes, priv_val, priv_data) \
- { \
- c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \
- c->access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE; \
- c->type = SNDRV_CTL_ELEM_TYPE_BYTES; \
- c->name = cname; c->value = &cbytes; \
- c->private_value = priv_val; c->private_data = priv_data; \
- }
-#endif /* end of __MIXER_PLUGIN_H__ */
diff --git a/include/tinyalsa/pcm_plugin.h b/include/tinyalsa/pcm_plugin.h
deleted file mode 100644
index 5d6f503..0000000
--- a/include/tinyalsa/pcm_plugin.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* pcm_plugin.h
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#ifndef __PCM_PLUGIN_H__
-#define __PCM_PLUGIN_H__
-
-#define PCM_PLUGIN_OPEN_FN(name) \
- int name##_open(struct pcm_plugin **plugin, \
- unsigned int card, \
- unsigned int device, \
- int mode)
-
-#define PCM_PLUGIN_OPEN_FN_PTR() \
- int (*plugin_open_fn) (struct pcm_plugin **plugin, \
- unsigned int card, \
- unsigned int device, \
- int mode);
-
-struct pcm_plugin;
-
-struct pcm_plugin_ops {
- int (*close) (struct pcm_plugin *plugin);
- int (*hw_params) (struct pcm_plugin *plugin,
- struct snd_pcm_hw_params *params);
- int (*sw_params) (struct pcm_plugin *plugin,
- struct snd_pcm_sw_params *params);
- int (*sync_ptr) (struct pcm_plugin *plugin,
- struct snd_pcm_sync_ptr *sync_ptr);
- int (*writei_frames) (struct pcm_plugin *plugin,
- struct snd_xferi *x);
- int (*readi_frames) (struct pcm_plugin *plugin,
- struct snd_xferi *x);
- int (*ttstamp) (struct pcm_plugin *plugin,
- int *tstamp);
- int (*prepare) (struct pcm_plugin *plugin);
- int (*start) (struct pcm_plugin *plugin);
- int (*drop) (struct pcm_plugin *plugin);
- int (*ioctl) (struct pcm_plugin *plugin,
- int cmd, void *arg);
-};
-
-struct pcm_plugin_min_max {
- unsigned int min;
- unsigned int max;
-};
-
-struct pcm_plugin_hw_constraints {
- uint64_t access;
- /* As of this implementation ALSA supports 52 formats */
- uint64_t format;
- struct pcm_plugin_min_max bit_width;
- struct pcm_plugin_min_max channels;
- struct pcm_plugin_min_max rate;
- struct pcm_plugin_min_max periods;
- struct pcm_plugin_min_max period_bytes;
-};
-
-struct pcm_plugin {
- unsigned int card;
-
- struct pcm_plugin_ops *ops;
- struct pcm_plugin_hw_constraints *constraints;
-
- void *node;
- int mode;
- void *priv;
-
- unsigned int state;
-};
-
-#endif /* end of __PCM_PLUGIN_H__ */
diff --git a/mixer.c b/mixer.c
index f26f43f..f3fdb62 100644
--- a/mixer.c
+++ b/mixer.c
@@ -40,7 +40,6 @@
#include <sys/ioctl.h>
#include <linux/ioctl.h>
-
#define __force
#define __bitwise
#define __user
@@ -51,266 +50,122 @@
#endif
#include <tinyalsa/asoundlib.h>
-#include "mixer_io.h"
struct mixer_ctl {
struct mixer *mixer;
- struct mixer_ctl_group *grp;
struct snd_ctl_elem_info *info;
char **ename;
bool info_retrieved;
};
-struct mixer_ctl_group {
- struct snd_ctl_elem_info *elem_info;
- struct mixer_ctl *ctl;
- unsigned int count;
- int event_cnt;
-
- struct mixer_ops *ops;
- void *data;
-};
-
struct mixer {
int fd;
struct snd_ctl_card_info card_info;
-
- /* hardware/physical mixer control group */
- struct mixer_ctl_group *hw_grp;
-
- /*
- * Virutal mixer control group.
- * Currently supports one virtual mixer (.so)
- * per card. Could be extended to multiple
- */
- struct mixer_ctl_group *virt_grp;
-
- unsigned int total_ctl_count;
+ struct snd_ctl_elem_info *elem_info;
+ struct mixer_ctl *ctl;
+ unsigned int count;
};
-static void mixer_grp_close(struct mixer_ctl_group *grp)
-{
- unsigned int n, m;
-
- if (!grp)
- return;
-
- if (grp->ctl) {
- for (n = 0; n < grp->count; n++) {
- if (grp->ctl[n].ename) {
- unsigned int max = grp->ctl[n].info->value.enumerated.items;
- for (m = 0; m < max; m++)
- free(grp->ctl[n].ename[m]);
- free(grp->ctl[n].ename);
- }
- }
- free(grp->ctl);
- }
-
- if (grp->elem_info)
- free(grp->elem_info);
-
- free(grp);
-}
-
void mixer_close(struct mixer *mixer)
{
+ unsigned int n,m;
+
if (!mixer)
return;
- if (mixer->fd >= 0 && mixer->hw_grp)
- mixer->hw_grp->ops->close(mixer->hw_grp->data);
- mixer_grp_close(mixer->hw_grp);
+ if (mixer->fd >= 0)
+ close(mixer->fd);
- if (mixer->virt_grp)
- mixer->virt_grp->ops->close(mixer->virt_grp->data);
- mixer_grp_close(mixer->virt_grp);
+ if (mixer->ctl) {
+ for (n = 0; n < mixer->count; n++) {
+ if (mixer->ctl[n].ename) {
+ unsigned int max = mixer->ctl[n].info->value.enumerated.items;
+ for (m = 0; m < max; m++)
+ free(mixer->ctl[n].ename[m]);
+ free(mixer->ctl[n].ename);
+ }
+ }
+ free(mixer->ctl);
+ }
+
+ if (mixer->elem_info)
+ free(mixer->elem_info);
free(mixer);
/* TODO: verify frees */
}
-static int mixer_grp_open(struct mixer *mixer,
- struct mixer_ctl_group **ctl_grp,
- struct mixer_ops *ops,
- void *data, int *num_ctls_in_grp)
+struct mixer *mixer_open(unsigned int card)
{
- struct mixer_ctl_group *grp;
struct snd_ctl_elem_list elist;
struct snd_ctl_elem_id *eid = NULL;
+ struct mixer *mixer = NULL;
unsigned int n;
- int ret;
+ int fd;
+ char fn[256];
- grp = calloc(1, sizeof(*grp));
- if (!grp)
- return -ENOMEM;
+ snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
+ fd = open(fn, O_RDWR);
+ if (fd < 0)
+ return 0;
memset(&elist, 0, sizeof(elist));
- ret = ops->ioctl(data, SNDRV_CTL_IOCTL_ELEM_LIST, &elist);
- if (ret < 0)
- goto err_get_elem_list;
+ if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
+ goto fail;
- grp->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
- grp->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
- if (!grp->ctl || !grp->elem_info) {
- ret = -ENOMEM;
- goto err_ctl_alloc;
- }
+ mixer = calloc(1, sizeof(*mixer));
+ if (!mixer)
+ goto fail;
- eid = calloc(elist.count, sizeof(*eid));
- if (!eid) {
- ret = -ENOMEM;
- goto err_ctl_alloc;
- }
+ mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
+ mixer->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
+ if (!mixer->ctl || !mixer->elem_info)
+ goto fail;
- grp->count = elist.count;
- elist.space = grp->count;
+ if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0)
+ goto fail;
+
+ eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
+ if (!eid)
+ goto fail;
+
+ mixer->count = elist.count;
+ mixer->fd = fd;
+ elist.space = mixer->count;
elist.pids = eid;
- ret = ops->ioctl(data, SNDRV_CTL_IOCTL_ELEM_LIST, &elist);
- if (ret < 0)
- goto err_ctl_alloc;
+ if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
+ goto fail;
- for (n = 0; n < grp->count; n++) {
- struct mixer_ctl *ctl = grp->ctl + n;
+ for (n = 0; n < mixer->count; n++) {
+ struct mixer_ctl *ctl = mixer->ctl + n;
- ctl->grp = grp;
ctl->mixer = mixer;
- ctl->info = grp->elem_info + n;
+ ctl->info = mixer->elem_info + n;
ctl->info->id.numid = eid[n].numid;
strncpy((char *)ctl->info->id.name, (char *)eid[n].name,
SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
ctl->info->id.name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN - 1] = 0;
}
- grp->data = data;
- grp->ops = ops;
- *ctl_grp = grp;
- *num_ctls_in_grp = grp->count;
-
free(eid);
- return 0;
-
-err_ctl_alloc:
-
- if (eid)
- free(eid);
-
- if (grp->elem_info)
- free(grp->elem_info);
-
- if (grp->ctl)
- free(grp->ctl);
-
-err_get_elem_list:
-
- free(grp);
- return ret;
-
-}
-
-static int mixer_do_hw_open(struct mixer *mixer, unsigned int card)
-{
- struct mixer_ops *ops;
- void *data;
- int fd, ret, num_grp_ctls = 0;
-
- mixer->fd = -1;
- fd = mixer_hw_open(card, &data, &ops);
- if (fd < 0)
- return fd;
-
- ret = ops->ioctl(data, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info);
- if (ret < 0)
- goto err_card_info;
-
- ret = mixer_grp_open(mixer, &mixer->hw_grp, ops, data, &num_grp_ctls);
- if (ret < 0)
- goto err_card_info;
-
- mixer->total_ctl_count += num_grp_ctls;
-
- mixer->fd = fd;
- return 0;
-
-err_card_info:
- ops->close(data);
- return ret;
-
-}
-
-static int mixer_do_plugin_open(struct mixer *mixer, unsigned int card,
- int is_hw_open_failed)
-{
- struct mixer_ops *ops;
- void *data;
- int ret, num_grp_ctls = 0;
-
- ret = mixer_plugin_open(card, &data, &ops);
- if (ret < 0)
- return ret;
-
- /* Get card_info if hw_open failed */
- if (is_hw_open_failed) {
- ret = ops->ioctl(data, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info);
- if (ret < 0)
- goto err_card_info;
- }
-
- ret = mixer_grp_open(mixer, &mixer->virt_grp, ops, data, &num_grp_ctls);
- if (ret < 0)
- goto err_card_info;
-
- mixer->total_ctl_count += num_grp_ctls;
- return 0;
-
-err_card_info:
- ops->close(data);
- return ret;
-
-}
-
-struct mixer *mixer_open(unsigned int card)
-{
- struct mixer *mixer = NULL;
- int h_status, v_status;
-
- mixer = calloc(1, sizeof(*mixer));
- if (!mixer)
- goto fail;
-
- /* open hardware node first */
- h_status = mixer_do_hw_open(mixer, card);
-
- /*
- * open the virtual node even if hw_open fails
- * since hw_open is expected to fail for virtual cards
- * for which kernel does not register mixer node
- */
- //TODO: open virtual node only if mixer is defined under snd-card-def
- v_status = mixer_do_plugin_open(mixer, card, h_status);
-
- /* Fail mixer_open if both hw and plugin nodes cannot be opened */
- if (h_status < 0 && v_status < 0)
- goto fail;
-
return mixer;
fail:
+ /* TODO: verify frees in failure case */
+ if (eid)
+ free(eid);
if (mixer)
mixer_close(mixer);
-
+ else if (fd >= 0)
+ close(fd);
return 0;
}
static bool mixer_ctl_get_elem_info(struct mixer_ctl* ctl)
{
- struct mixer_ctl_group *grp = ctl->grp;
- unsigned int i;
-
if (!ctl->info_retrieved) {
- if (grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_INFO,
- ctl->info) < 0)
+ if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info) < 0)
return false;
ctl->info_retrieved = true;
}
@@ -323,11 +178,11 @@
if (!enames)
return false;
- for (i = 0; i < ctl->info->value.enumerated.items; i++) {
+ for (unsigned int i = 0; i < ctl->info->value.enumerated.items; i++) {
memset(&tmp, 0, sizeof(tmp));
tmp.id.numid = ctl->info->id.numid;
tmp.value.enumerated.item = i;
- if (grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
+ if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
goto fail;
enames[i] = strdup(tmp.value.enumerated.name);
if (!enames[i])
@@ -351,35 +206,17 @@
if (!mixer)
return 0;
- return mixer->total_ctl_count;
-}
-
-static int mixer_grp_get_count(struct mixer_ctl_group *grp)
-{
- if (!grp)
- return 0;
-
- return grp->count;
+ return mixer->count;
}
struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id)
{
struct mixer_ctl *ctl;
- unsigned int hw_ctl_count, virt_ctl_count;
- if (!mixer || (id >= mixer->total_ctl_count))
+ if (!mixer || (id >= mixer->count))
return NULL;
- hw_ctl_count = mixer_grp_get_count(mixer->hw_grp);
- virt_ctl_count = mixer_grp_get_count(mixer->virt_grp);
-
- if (id < hw_ctl_count)
- ctl = mixer->hw_grp->ctl + id;
- else if ((id - hw_ctl_count) < virt_ctl_count)
- ctl = mixer->virt_grp->ctl + (id - hw_ctl_count);
- else
- return NULL;
-
+ ctl = mixer->ctl + id;
if (!mixer_ctl_get_elem_info(ctl))
return NULL;
@@ -388,37 +225,21 @@
struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name)
{
- struct mixer_ctl_group *grp;
unsigned int n;
- int hw_ctl_count = mixer_grp_get_count(mixer->hw_grp);
if (!mixer)
return NULL;
- if (mixer->hw_grp) {
- grp = mixer->hw_grp;
-
- for (n = 0; n < grp->count; n++)
- if (!strcmp(name, (char*) grp->elem_info[n].id.name))
+ for (n = 0; n < mixer->count; n++)
+ if (!strcmp(name, (char*) mixer->elem_info[n].id.name))
return mixer_get_ctl(mixer, n);
- }
-
- if (mixer->virt_grp) {
- grp = mixer->virt_grp;
-
- for (n = 0; n < grp->count; n++)
- if (!strcmp(name, (char*) grp->elem_info[n].id.name))
- return mixer_get_ctl(mixer, n + hw_ctl_count);
- }
return NULL;
}
void mixer_ctl_update(struct mixer_ctl *ctl)
{
- struct mixer_ctl_group *grp = ctl->grp;
-
- grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info);
+ ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info);
}
const char *mixer_ctl_get_name(struct mixer_ctl *ctl)
@@ -511,7 +332,6 @@
int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id)
{
- struct mixer_ctl_group *grp = ctl->grp;
struct snd_ctl_elem_value ev;
int ret;
@@ -520,7 +340,7 @@
memset(&ev, 0, sizeof(ev));
ev.id.numid = ctl->info->id.numid;
- ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
if (ret < 0)
return ret;
@@ -551,7 +371,6 @@
int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count)
{
- struct mixer_ctl_group *grp = ctl->grp;
struct snd_ctl_elem_value ev;
int ret = 0;
size_t size;
@@ -578,7 +397,7 @@
switch (ctl->info->type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER:
- ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
if (ret < 0)
return ret;
size = sizeof(ev.value.integer.value[0]);
@@ -598,7 +417,7 @@
return -ENOMEM;
tlv->numid = ctl->info->id.numid;
tlv->length = count;
- ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_TLV_READ, tlv);
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_TLV_READ, tlv);
source = tlv->tlv;
memcpy(array, source, count);
@@ -607,7 +426,7 @@
return ret;
} else {
- ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
if (ret < 0)
return ret;
size = sizeof(ev.value.bytes.data[0]);
@@ -631,8 +450,6 @@
int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
{
- struct mixer_ctl_group *grp = ctl->grp;
-
struct snd_ctl_elem_value ev;
int ret;
@@ -641,7 +458,7 @@
memset(&ev, 0, sizeof(ev));
ev.id.numid = ctl->info->id.numid;
- ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
if (ret < 0)
return ret;
@@ -666,12 +483,11 @@
return -EINVAL;
}
- return grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
+ return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
}
int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
{
- struct mixer_ctl_group *grp = ctl->grp;
struct snd_ctl_elem_value ev;
size_t size;
void *dest;
@@ -715,7 +531,7 @@
tlv->length = count;
memcpy(tlv->tlv, array, count);
- ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_TLV_WRITE, tlv);
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_TLV_WRITE, tlv);
free(tlv);
return ret;
@@ -736,7 +552,7 @@
memcpy(dest, array, size * count);
- return grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
+ return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
}
int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
@@ -775,7 +591,6 @@
int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string)
{
- struct mixer_ctl_group *grp = ctl->grp;
unsigned int i, num_enums;
struct snd_ctl_elem_value ev;
int ret;
@@ -789,7 +604,7 @@
memset(&ev, 0, sizeof(ev));
ev.value.enumerated.item[0] = i;
ev.id.numid = ctl->info->id.numid;
- ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
if (ret < 0)
return ret;
return 0;
@@ -808,26 +623,8 @@
*/
int mixer_subscribe_events(struct mixer *mixer, int subscribe)
{
- struct mixer_ctl_group *grp;
-
- if (mixer->hw_grp) {
- grp = mixer->hw_grp;
- if (!subscribe)
- grp->event_cnt = 0;
-
- if (grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS,
- &subscribe) < 0)
- return -1;
- }
-
- if (mixer->virt_grp) {
- grp = mixer->virt_grp;
- if (!subscribe)
- grp->event_cnt = 0;
-
- if (grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS,
- &subscribe) < 0)
- return -1;
+ if (ioctl(mixer->fd, SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, &subscribe) < 0) {
+ return -1;
}
return 0;
}
@@ -842,59 +639,22 @@
*/
int mixer_wait_event(struct mixer *mixer, int timeout)
{
- struct pollfd *pfd;
- struct mixer_ctl_group *grp;
- int count = 0, num_fds = 0, i;
+ struct pollfd pfd;
- if (mixer->fd >= 0)
- num_fds++;
-
- if (mixer->virt_grp)
- num_fds++;
-
- pfd = (struct pollfd *)calloc(sizeof(struct pollfd), num_fds);
- if (!pfd)
- return -ENOMEM;
-
- /* TODO wait events for virt fd */
- if (mixer->fd >= 0) {
- pfd[count].fd = mixer->fd;
- pfd[count].events = POLLIN | POLLOUT | POLLERR | POLLNVAL;
- count++;
- }
-
- if (mixer->virt_grp) {
- grp = mixer->virt_grp;
- if (!grp->ops->get_poll_fd(grp->data, pfd, count)) {
- pfd[count].events = POLLIN | POLLERR | POLLNVAL;
- count++;
- }
- }
-
- if (!count)
- return 0;
+ pfd.fd = mixer->fd;
+ pfd.events = POLLIN | POLLOUT | POLLERR | POLLNVAL;
for (;;) {
int err;
- err = poll(pfd, count, timeout);
+ err = poll(&pfd, 1, timeout);
if (err < 0)
return -errno;
if (!err)
return 0;
- for (i = 0; i < count; i++) {
- if (pfd[i].revents & (POLLERR | POLLNVAL))
- return -EIO;
- if (pfd[i].revents & (POLLIN | POLLOUT)) {
- if ((i == 0) && mixer->fd >= 0) {
- grp = mixer->hw_grp;
- grp->event_cnt++;
- } else {
- grp = mixer->virt_grp;
- grp->event_cnt++;
- }
- return 1;
- }
- }
+ if (pfd.revents & (POLLERR | POLLNVAL))
+ return -EIO;
+ if (pfd.revents & (POLLIN | POLLOUT))
+ return 1;
}
}
@@ -908,69 +668,13 @@
* @returns 0 on success. -errno on failure.
* @ingroup libtinyalsa-mixer
*/
-int mixer_consume_event(struct mixer *mixer)
-{
+int mixer_consume_event(struct mixer *mixer) {
struct snd_ctl_event ev;
- struct mixer_ctl_group *grp;
- ssize_t count = 0;
-
+ ssize_t count = read(mixer->fd, &ev, sizeof(ev));
// Exporting the actual event would require exposing snd_ctl_event
// via the header file, and all associated structs.
// The events generally tell you exactly which value changed,
// but reading values you're interested isn't hard and simplifies
// the interface greatly.
- if (mixer->hw_grp) {
- grp = mixer->hw_grp;
- if (grp->event_cnt) {
- grp->event_cnt--;
- count = grp->ops->read_event(grp->data, &ev, sizeof(ev));
- return (count >= 0) ? 0 : -errno;
- }
- }
-
- if (mixer->virt_grp) {
- grp = mixer->virt_grp;
- if (grp->event_cnt) {
- grp->event_cnt--;
- count += grp->ops->read_event(grp->data, &ev, sizeof(ev));
- return (count >= 0) ? 0 : -errno;
- }
- }
- return (count >= 0) ? 0 : -errno;
-}
-
-/** Read a mixer event.
- * If mixer_subscribe_events has been called,
- * mixer_wait_event will identify when a control value has changed.
- * This function will read and clear a single event from the mixer
- * so that further events can be alerted.
- *
- * @param mixer A mixer handle.
- * @param ev snd_ctl_event pointer where event needs to be read
- * @returns 0 on success. -errno on failure.
- * @ingroup libtinyalsa-mixer
- */
-int mixer_read_event(struct mixer *mixer, struct snd_ctl_event *ev)
-{
- struct mixer_ctl_group *grp;
- ssize_t count = 0;
-
- if (mixer->hw_grp) {
- grp = mixer->hw_grp;
- if (grp->event_cnt) {
- grp->event_cnt--;
- count = grp->ops->read_event(grp->data, ev, sizeof(*ev));
- return (count >= 0) ? 0 : -errno;
- }
- }
-
- if (mixer->virt_grp) {
- grp = mixer->virt_grp;
- if (grp->event_cnt) {
- grp->event_cnt--;
- count = grp->ops->read_event(grp->data, ev, sizeof(*ev));
- return (count >= 0) ? 0 : -errno;
- }
- }
return (count >= 0) ? 0 : -errno;
}
diff --git a/mixer_hw.c b/mixer_hw.c
deleted file mode 100644
index a051d3a..0000000
--- a/mixer_hw.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* mixer_hw.c
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <poll.h>
-
-#include <sys/ioctl.h>
-
-#include <linux/ioctl.h>
-#include <sound/asound.h>
-
-#include "mixer_io.h"
-
-struct mixer_hw_data {
- unsigned int card;
- int fd;
-};
-
-static void mixer_hw_close(void *data)
-{
- struct mixer_hw_data *hw_data = data;
-
- if (!hw_data)
- return;
-
- if (hw_data->fd >= 0)
- close(hw_data->fd);
-
- hw_data->fd = -1;
- free(hw_data);
- hw_data = NULL;
-}
-
-static int mixer_hw_ioctl(void *data, unsigned int cmd, ...)
-{
- struct mixer_hw_data *hw_data = data;
- va_list ap;
- void *arg;
-
- va_start(ap, cmd);
- arg = va_arg(ap, void *);
- va_end(ap);
-
- return ioctl(hw_data->fd, cmd, arg);
-}
-
-static ssize_t mixer_hw_read_event(void *data, struct snd_ctl_event *ev,
- size_t size)
-{
- struct mixer_hw_data *hw_data = data;
-
- return read(hw_data->fd, ev, size);
-}
-
-static struct mixer_ops mixer_hw_ops = {
- .close = mixer_hw_close,
- .ioctl = mixer_hw_ioctl,
- .read_event = mixer_hw_read_event,
-};
-
-int mixer_hw_open(unsigned int card, void **data,
- struct mixer_ops **ops)
-{
- struct mixer_hw_data *hw_data;
- int fd;
- char fn[256];
-
- snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
- fd = open(fn, O_RDWR);
- if (fd < 0)
- return fd;
-
- hw_data = calloc(1, sizeof(*hw_data));
- if (!hw_data)
- return -1;
-
- hw_data->card = card;
- hw_data->fd = fd;
- *data = hw_data;
- *ops = &mixer_hw_ops;
-
- return fd;
-}
diff --git a/mixer_io.h b/mixer_io.h
deleted file mode 100644
index 77daae0..0000000
--- a/mixer_io.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* mixer_io.h
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#ifndef __MIXER_H__
-#define __MIXER_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sound/asound.h>
-
-struct mixer_ops;
-
-int mixer_hw_open(unsigned int card, void **data,
- struct mixer_ops **ops);
-int mixer_plugin_open(unsigned int card, void **data,
- struct mixer_ops **ops);
-
-struct mixer_ops {
- void (*close) (void *data);
- int (*get_poll_fd) (void *data, struct pollfd *pfd, int count);
- ssize_t (*read_event) (void *data, struct snd_ctl_event *ev, size_t size);
- int (*ioctl) (void *data, unsigned int cmd, ...);
-};
-
-#endif /* end of __MIXER_H__ */
diff --git a/mixer_plugin.c b/mixer_plugin.c
deleted file mode 100644
index b3f1ccf..0000000
--- a/mixer_plugin.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/* mixer_plugin.c
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <poll.h>
-#include <dlfcn.h>
-#include <string.h>
-#include <sys/eventfd.h>
-#include <sys/ioctl.h>
-
-#include <linux/ioctl.h>
-#include <sound/asound.h>
-
-#include <tinyalsa/mixer_plugin.h>
-#include "snd_utils.h"
-
-#include "mixer_io.h"
-
-struct mixer_plug_data {
- int card;
- void *mixer_node;
-
- struct mixer_plugin *plugin;
- void *dl_hdl;
- MIXER_PLUGIN_OPEN_FN_PTR();
-};
-
-static int mixer_plug_get_elem_id(struct mixer_plug_data *plug_data,
- struct snd_ctl_elem_id *id, unsigned int offset)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- struct snd_control *ctl;
-
- if (offset >= plugin->num_controls) {
- printf("%s: invalid offset %u\n", __func__, offset);
- return -EINVAL;
- }
-
- ctl = plugin->controls + offset;
- id->numid = offset;
- id->iface = ctl->iface;
-
- strncpy((char *)id->name, (char *)ctl->name,
- sizeof(id->name));
-
- return 0;
-}
-
-static int mixer_plug_info_enum(struct snd_control *ctl,
- struct snd_ctl_elem_info *einfo)
-{
- struct snd_value_enum *val = ctl->value;
-
- einfo->count = 1;
- einfo->value.enumerated.items = val->items;
-
- if (einfo->value.enumerated.item > val->items)
- return -EINVAL;
-
- strncpy(einfo->value.enumerated.name,
- val->texts[einfo->value.enumerated.item],
- sizeof(einfo->value.enumerated.name));
-
- return 0;
-}
-
-static int mixer_plug_info_bytes(struct snd_control *ctl,
- struct snd_ctl_elem_info *einfo)
-{
- struct snd_value_bytes *val;
- struct snd_value_tlv_bytes *val_tlv;
-
- if (ctl->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
- val_tlv = ctl->value;
- einfo->count = val_tlv->size;
- } else {
- val = ctl->value;
- einfo->count = val->size;
- }
-
- return 0;
-}
-
-static int mixer_plug_info_integer(struct snd_control *ctl,
- struct snd_ctl_elem_info *einfo)
-{
- struct snd_value_int *val = ctl->value;
-
- einfo->count = val->count;
- einfo->value.integer.min = val->min;
- einfo->value.integer.max = val->max;
- einfo->value.integer.step = val->step;
-
- return 0;
-}
-
-void mixer_plug_notifier_cb(struct mixer_plugin *plugin)
-{
- eventfd_write(plugin->eventfd, 1);
- plugin->event_cnt++;
-}
-
-/* In consume_event/read, do not call eventfd_read until all events are read from list.
- This will make poll getting unblocked until all events are read */
-static ssize_t mixer_plug_read_event(void *data, struct snd_ctl_event *ev, size_t size)
-{
- struct mixer_plug_data *plug_data = data;
- struct mixer_plugin *plugin = plug_data->plugin;
- eventfd_t evfd;
- ssize_t result = 0;
-
- result = plugin->ops->read_event(plugin, ev, size);
-
- if (result > 0) {
- plugin->event_cnt -= result / sizeof(struct snd_ctl_event);
- if (plugin->event_cnt == 0)
- eventfd_read(plugin->eventfd, &evfd);
- }
-
- return result;
-}
-
-static int mixer_plug_subscribe_events(struct mixer_plug_data *plug_data,
- int *subscribe)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- eventfd_t evfd;
-
- if (*subscribe < 0 || *subscribe > 1) {
- *subscribe = plugin->subscribed;
- return -EINVAL;
- }
-
- if (*subscribe && !plugin->subscribed) {
- plugin->ops->subscribe_events(plugin, &mixer_plug_notifier_cb);
- } else if (plugin->subscribed && !*subscribe) {
- plugin->ops->subscribe_events(plugin, NULL);
-
- if (plugin->event_cnt)
- eventfd_read(plugin->eventfd, &evfd);
-
- plugin->event_cnt = 0;
- }
-
- plugin->subscribed = *subscribe;
- return 0;
-}
-
-static int mixer_plug_get_poll_fd(void *data, struct pollfd *pfd, int count)
-{
- struct mixer_plug_data *plug_data = data;
- struct mixer_plugin *plugin = plug_data->plugin;
-
- if (plugin->eventfd != -1) {
- pfd[count].fd = plugin->eventfd;
- return 0;
- }
- return -ENODEV;
-}
-
-static int mixer_plug_tlv_write(struct mixer_plug_data *plug_data,
- struct snd_ctl_tlv *tlv)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- struct snd_control *ctl;
- struct snd_value_tlv_bytes *val_tlv;
-
- ctl = plugin->controls + tlv->numid;
- val_tlv = ctl->value;
-
- return val_tlv->put(plugin, ctl, tlv);
-}
-
-static int mixer_plug_tlv_read(struct mixer_plug_data *plug_data,
- struct snd_ctl_tlv *tlv)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- struct snd_control *ctl;
- struct snd_value_tlv_bytes *val_tlv;
-
- ctl = plugin->controls + tlv->numid;
- val_tlv = ctl->value;
-
- return val_tlv->get(plugin, ctl, tlv);
-}
-
-static int mixer_plug_elem_write(struct mixer_plug_data *plug_data,
- struct snd_ctl_elem_value *ev)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- struct snd_control *ctl;
- int ret;
-
- ret = mixer_plug_get_elem_id(plug_data, &ev->id, ev->id.numid);
- if (ret < 0)
- return ret;
-
- ctl = plugin->controls + ev->id.numid;
-
- return ctl->put(plugin, ctl, ev);
-}
-
-static int mixer_plug_elem_read(struct mixer_plug_data *plug_data,
- struct snd_ctl_elem_value *ev)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- struct snd_control *ctl;
- int ret;
-
- ret = mixer_plug_get_elem_id(plug_data, &ev->id, ev->id.numid);
- if (ret < 0)
- return ret;
-
- ctl = plugin->controls + ev->id.numid;
-
- return ctl->get(plugin, ctl, ev);
-
-}
-
-static int mixer_plug_get_elem_info(struct mixer_plug_data *plug_data,
- struct snd_ctl_elem_info *einfo)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- struct snd_control *ctl;
- int ret;
-
- ret = mixer_plug_get_elem_id(plug_data, &einfo->id,
- einfo->id.numid);
- if (ret < 0)
- return ret;
-
- ctl = plugin->controls + einfo->id.numid;
- einfo->type = ctl->type;
- einfo->access = ctl->access;
-
- switch (einfo->type) {
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
- ret = mixer_plug_info_enum(ctl, einfo);
- if (ret < 0)
- return ret;
- break;
- case SNDRV_CTL_ELEM_TYPE_BYTES:
- ret = mixer_plug_info_bytes(ctl, einfo);
- if (ret < 0)
- return ret;
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER:
- ret = mixer_plug_info_integer(ctl, einfo);
- if (ret < 0)
- return ret;
- break;
- default:
- printf("%s: unknown type %d\n", __func__, einfo->type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int mixer_plug_get_elem_list(struct mixer_plug_data *plug_data,
- struct snd_ctl_elem_list *elist)
-{
- struct mixer_plugin *plugin = plug_data->plugin;
- unsigned int avail;
- struct snd_ctl_elem_id *id;
- int ret;
-
- elist->count = plugin->num_controls;
- elist->used = 0;
- avail = elist->space;
-
- while (avail > 0) {
- id = elist->pids + elist->used;
- ret = mixer_plug_get_elem_id(plug_data, id, elist->used);
- if (ret < 0)
- return ret;
-
- avail--;
- elist->used++;
- }
-
- return 0;
-}
-
-static int mixer_plug_get_card_info(struct mixer_plug_data *plug_data,
- struct snd_ctl_card_info *card_info)
-{
- /*TODO: Fill card_info here from snd-card-def */
- memset(card_info, 0, sizeof(*card_info));
- card_info->card = plug_data->card;
- memcpy(card_info->id, "card_id", sizeof(card_info->id));
- memcpy(card_info->driver, "mymixer-so-name", sizeof(card_info->driver));
- memcpy(card_info->name, "card-name", sizeof(card_info->name));
- memcpy(card_info->longname, "card-name", sizeof(card_info->longname));
- memcpy(card_info->mixername, "mixer-name", sizeof(card_info->mixername));
-
- printf("%s: card = %d\n", __func__, plug_data->card);
-
- return 0;
-}
-
-static void mixer_plug_close(void *data)
-{
- struct mixer_plug_data *plug_data = data;
- struct mixer_plugin *plugin = plug_data->plugin;
- eventfd_t evfd;
-
- if (plugin->event_cnt)
- eventfd_read(plugin->eventfd, &evfd);
-
- plugin->ops->close(&plugin);
- dlclose(plug_data->dl_hdl);
- snd_utils_put_dev_node(plug_data->mixer_node);
- free(plug_data);
- plug_data = NULL;
-}
-
-static int mixer_plug_ioctl(void *data, unsigned int cmd, ...)
-{
- struct mixer_plug_data *plug_data = data;
- int ret;
- va_list ap;
- void *arg;
-
- va_start(ap, cmd);
- arg = va_arg(ap, void *);
- va_end(ap);
-
- switch (cmd) {
- case SNDRV_CTL_IOCTL_CARD_INFO:
- ret = mixer_plug_get_card_info(plug_data, arg);
- break;
- case SNDRV_CTL_IOCTL_ELEM_LIST:
- ret = mixer_plug_get_elem_list(plug_data, arg);
- break;
- case SNDRV_CTL_IOCTL_ELEM_INFO:
- ret = mixer_plug_get_elem_info(plug_data, arg);
- break;
- case SNDRV_CTL_IOCTL_ELEM_READ:
- ret = mixer_plug_elem_read(plug_data, arg);
- break;
- case SNDRV_CTL_IOCTL_ELEM_WRITE:
- ret = mixer_plug_elem_write(plug_data, arg);
- break;
- case SNDRV_CTL_IOCTL_TLV_READ:
- ret = mixer_plug_tlv_read(plug_data, arg);
- break;
- case SNDRV_CTL_IOCTL_TLV_WRITE:
- ret = mixer_plug_tlv_write(plug_data, arg);
- break;
- case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
- ret = mixer_plug_subscribe_events(plug_data, arg);
- break;
- default:
- /* TODO: plugin should support ioctl */
- ret = -EFAULT;
- break;
- }
-
- return ret;
-}
-
-static struct mixer_ops mixer_plug_ops = {
- .close = mixer_plug_close,
- .read_event = mixer_plug_read_event,
- .get_poll_fd = mixer_plug_get_poll_fd,
- .ioctl = mixer_plug_ioctl,
-};
-
-int mixer_plugin_open(unsigned int card, void **data,
- struct mixer_ops **ops)
-{
- struct mixer_plug_data *plug_data;
- struct mixer_plugin *plugin = NULL;
- const char *err = NULL;
- void *dl_hdl;
- char *name, *so_name;
- char *open_fn_name, token[80];
- int ret;
-
- plug_data = calloc(1, sizeof(*plug_data));
- if (!plug_data)
- return -ENOMEM;
-
- /* mixer id is fixed to 1 in snd-card-def xml */
- plug_data->mixer_node = snd_utils_get_dev_node(card, 1, NODE_MIXER);
- if (!plug_data->mixer_node) {
- /* Do not print error here.
- * It is valid for card to not have virtual mixer node
- */
- goto err_get_mixer_node;
- }
-
- ret = snd_utils_get_str(plug_data->mixer_node, "so-name",
- &so_name);
- if(ret) {
- fprintf(stderr, "%s: mixer so-name not found for card %u\n",
- __func__, card);
- goto err_get_mixer_node;
-
- }
-
- dl_hdl = dlopen(so_name, RTLD_NOW);
- if (!dl_hdl) {
- fprintf(stderr, "%s: unable to open %s\n",
- __func__, so_name);
- goto err_get_mixer_node;
- }
-
- sscanf(so_name, "lib%s", token);
- name = strtok(token, ".");
-
- open_fn_name = calloc(1, strlen(name) + strlen("_open") + 1);
- if (!open_fn_name) {
- ret = -ENOMEM;
- goto err_get_mixer_node;
- }
-
- strncpy(open_fn_name, name, strlen(name) + 1);
- strcat(open_fn_name, "_open");
-
- printf("%s - %s\n", __func__, open_fn_name);
-
- dlerror();
- plug_data->mixer_plugin_open_fn = dlsym(dl_hdl, open_fn_name);
- if (err) {
- fprintf(stderr, "%s: dlsym open fn failed: %s\n",
- __func__, err);
- goto err_get_name;
- }
- ret = plug_data->mixer_plugin_open_fn(&plugin, card);
- if (ret) {
- fprintf(stderr, "%s: failed to open plugin, err: %d\n",
- __func__, ret);
- goto err_get_name;
- }
-
- plug_data->plugin = plugin;
- plug_data->card = card;
- plug_data->dl_hdl = dl_hdl;
- plugin->eventfd = eventfd(0, 0);
-
- *data = plug_data;
- *ops = &mixer_plug_ops;
-
- printf("%s: card = %d\n", __func__, plug_data->card);
-
- return 0;
-
-err_get_name:
- snd_utils_put_dev_node(plug_data->mixer_node);
- dlclose(dl_hdl);
-
-err_get_mixer_node:
-
- free(plug_data);
- return -1;
-}
diff --git a/pcm.c b/pcm.c
index f64eb40..4ae321b 100644
--- a/pcm.c
+++ b/pcm.c
@@ -47,13 +47,6 @@
#include <sound/asound.h>
#include <tinyalsa/asoundlib.h>
-#include "pcm_io.h"
-#include "snd_utils.h"
-
-enum {
- PCM_NODE_TYPE_HW = 0,
- PCM_NODE_TYPE_PLUGIN,
-};
#define PARAM_MAX SNDRV_PCM_HW_PARAM_LAST_INTERVAL
@@ -130,9 +123,6 @@
#endif
};
-extern struct pcm_ops hw_ops;
-extern struct pcm_ops plug_ops;
-
/* refer to SNDRV_PCM_SUBFORMAT_##index in sound/asound.h. */
static const char * const subformat_lookup[] = {
"STD",
@@ -267,10 +257,6 @@
unsigned int noirq_frames_per_msec;
int wait_for_avail_min;
unsigned int subdevice;
-
- struct pcm_ops *ops;
- void *data;
- void *snd_node;
};
unsigned int pcm_get_buffer_size(struct pcm *pcm)
@@ -350,8 +336,7 @@
static int pcm_sync_ptr(struct pcm *pcm, int flags) {
if (pcm->sync_ptr) {
pcm->sync_ptr->flags = flags;
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_SYNC_PTR,
- pcm->sync_ptr) < 0)
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SYNC_PTR, pcm->sync_ptr) < 0)
return -1;
}
return 0;
@@ -547,12 +532,12 @@
int prepare_error = pcm_prepare(pcm);
if (prepare_error)
return prepare_error;
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x))
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x))
return oops(pcm, errno, "cannot write initial data");
pcm->running = 1;
return 0;
}
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
pcm->prepared = 0;
pcm->running = 0;
if (errno == EPIPE) {
@@ -588,7 +573,7 @@
return -errno;
}
}
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
pcm->prepared = 0;
pcm->running = 0;
if (errno == EPIPE) {
@@ -610,22 +595,15 @@
unsigned int flags)
{
struct snd_pcm_hw_params *params;
- enum snd_node_type pcm_type;
- struct pcm_ops *ops;
- void *snd_node, *data;
+ char fn[256];
int fd;
- snd_node = snd_utils_get_dev_node(card, device, NODE_PCM);
- pcm_type = snd_utils_get_node_type(snd_node);
- if (pcm_type == SND_NODE_TYPE_PLUGIN)
- ops = &plug_ops;
- else
- ops = &hw_ops;
+ snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device,
+ flags & PCM_IN ? 'c' : 'p');
- fd = ops->open(card, device, flags, &data, snd_node);
+ fd = open(fn, O_RDWR);
if (fd < 0) {
- fprintf(stderr, "cannot open device %u for card %u\n",
- device, card);
+ fprintf(stderr, "cannot open device '%s'\n", fn);
goto err_open;
}
@@ -634,22 +612,20 @@
goto err_calloc;
param_init(params);
- if (ops->ioctl(data, SNDRV_PCM_IOCTL_HW_REFINE, params)) {
+ if (ioctl(fd, SNDRV_PCM_IOCTL_HW_REFINE, params)) {
fprintf(stderr, "SNDRV_PCM_IOCTL_HW_REFINE error (%d)\n", errno);
goto err_hw_refine;
}
- snd_utils_put_dev_node(snd_node);
- ops->close(data);
+ close(fd);
return (struct pcm_params *)params;
err_hw_refine:
free(params);
err_calloc:
- ops->close(data);
+ close(fd);
err_open:
- snd_utils_put_dev_node(snd_node);
return NULL;
}
@@ -886,9 +862,8 @@
munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
}
- pcm->ops->close(pcm->data);
- snd_utils_put_dev_node(pcm->snd_node);
-
+ if (pcm->fd >= 0)
+ close(pcm->fd);
pcm->prepared = 0;
pcm->running = 0;
pcm->buffer_size = 0;
@@ -904,7 +879,8 @@
struct snd_pcm_info info;
struct snd_pcm_hw_params params;
struct snd_pcm_sw_params sparams;
- int rc, pcm_type;
+ char fn[256];
+ int rc;
if (!config) {
return &bad_pcm; /* TODO: could support default config here */
@@ -914,23 +890,24 @@
return &bad_pcm; /* TODO: could support default config here */
pcm->config = *config;
+
+ snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device,
+ flags & PCM_IN ? 'c' : 'p');
+
pcm->flags = flags;
-
- pcm->snd_node = snd_utils_get_dev_node(card, device, NODE_PCM);
- pcm_type = snd_utils_get_node_type(pcm->snd_node);
- if (pcm_type == SND_NODE_TYPE_PLUGIN)
- pcm->ops = &plug_ops;
- else
- pcm->ops = &hw_ops;
-
- pcm->fd = pcm->ops->open(card, device, flags, &pcm->data, pcm->snd_node);
+ pcm->fd = open(fn, O_RDWR|O_NONBLOCK);
if (pcm->fd < 0) {
- oops(pcm, errno, "cannot open device %u for card %u",
- device, card);
- goto fail_open;
+ oops(pcm, errno, "cannot open device '%s'", fn);
+ return pcm;
}
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_INFO, &info)) {
+ if (fcntl(pcm->fd, F_SETFL, fcntl(pcm->fd, F_GETFL) &
+ ~O_NONBLOCK) < 0) {
+ oops(pcm, errno, "failed to reset blocking mode '%s'", fn);
+ goto fail_close;
+ }
+
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_INFO, &info)) {
oops(pcm, errno, "cannot get info");
goto fail_close;
}
@@ -968,7 +945,7 @@
param_set_mask(¶ms, SNDRV_PCM_HW_PARAM_ACCESS,
SNDRV_PCM_ACCESS_RW_INTERLEAVED);
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_HW_PARAMS, ¶ms)) {
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_PARAMS, ¶ms)) {
oops(pcm, errno, "cannot set hw params");
goto fail_close;
}
@@ -1029,7 +1006,7 @@
while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size)
pcm->boundary *= 2;
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) {
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) {
oops(pcm, errno, "cannot set sw params");
goto fail;
}
@@ -1043,7 +1020,7 @@
#ifdef SNDRV_PCM_IOCTL_TTSTAMP
if (pcm->flags & PCM_MONOTONIC) {
int arg = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
- rc = pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_TTSTAMP, &arg);
+ rc = ioctl(pcm->fd, SNDRV_PCM_IOCTL_TTSTAMP, &arg);
if (rc < 0) {
oops(pcm, errno, "cannot set timestamp type");
goto fail;
@@ -1058,11 +1035,8 @@
if (flags & PCM_MMAP)
munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
fail_close:
- pcm->ops->close(pcm->data);
+ close(pcm->fd);
pcm->fd = -1;
-
-fail_open:
- snd_utils_put_dev_node(pcm->snd_node);
return pcm;
}
@@ -1076,7 +1050,7 @@
if (pcm->prepared)
return 0;
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_PREPARE) < 0)
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE) < 0)
return oops(pcm, errno, "cannot prepare channel");
pcm->prepared = 1;
@@ -1090,9 +1064,9 @@
return prepare_error;
if (pcm->flags & PCM_MMAP)
- pcm_sync_ptr(pcm, 0);
+ pcm_sync_ptr(pcm, 0);
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_START) < 0)
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START) < 0)
return oops(pcm, errno, "cannot start channel");
pcm->running = 1;
@@ -1101,7 +1075,7 @@
int pcm_stop(struct pcm *pcm)
{
- if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_DROP) < 0)
+ if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0)
return oops(pcm, errno, "cannot stop channel");
pcm->prepared = 0;
@@ -1277,7 +1251,7 @@
}
/* start the audio if we reach the threshold */
- if (!pcm->running &&
+ if (!pcm->running &&
(pcm->buffer_size - avail) >= pcm->config.start_threshold) {
if (pcm_start(pcm) < 0) {
fprintf(stderr, "start error: hw 0x%x app 0x%x avail 0x%x\n",
@@ -1373,5 +1347,5 @@
arg = va_arg(ap, void *);
va_end(ap);
- return pcm->ops->ioctl(pcm->data, request, arg);
+ return ioctl(pcm->fd, request, arg);
}
diff --git a/pcm_hw.c b/pcm_hw.c
deleted file mode 100644
index bcd076f..0000000
--- a/pcm_hw.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* pcm_hw.c
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <poll.h>
-
-#include <sys/ioctl.h>
-#include <linux/ioctl.h>
-#include <sound/asound.h>
-#include <tinyalsa/asoundlib.h>
-
-#include "pcm_io.h"
-
-struct pcm_hw_data {
- unsigned int card;
- unsigned int device;
- unsigned int fd;
- void *snd_node;
-};
-
-static void pcm_hw_close(void *data)
-{
- struct pcm_hw_data *hw_data = data;
-
- if (hw_data->fd > 0)
- close(hw_data->fd);
-
- free(hw_data);
-}
-
-static int pcm_hw_ioctl(void *data, unsigned int cmd, ...)
-{
- struct pcm_hw_data *hw_data = data;
- va_list ap;
- void *arg;
-
- va_start(ap, cmd);
- arg = va_arg(ap, void *);
- va_end(ap);
-
- return ioctl(hw_data->fd, cmd, arg);
-}
-
-static int pcm_hw_open(unsigned int card, unsigned int device,
- unsigned int flags, void **data,
- __attribute__((unused)) void *node)
-{
- struct pcm_hw_data *hw_data;
- char fn[256];
- int fd;
-
- hw_data = calloc(1, sizeof(*hw_data));
- if (!hw_data) {
- return -ENOMEM;
- }
-
- snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device,
- flags & PCM_IN ? 'c' : 'p');
- fd = open(fn, O_RDWR|O_NONBLOCK);
- if (fd < 0) {
- printf("%s: cannot open device '%s'", __func__, fn);
- return fd;
- }
-
- if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK) < 0) {
- printf("%s: failed to reset blocking mode '%s'",
- __func__, fn);
- goto err_close;
- }
-
- hw_data->snd_node = node;
- hw_data->card = card;
- hw_data->device = device;
- hw_data->fd = fd;
-
- *data = hw_data;
-
- return fd;
-
-err_close:
- close(fd);
- free(hw_data);
- return -ENODEV;
-}
-
-struct pcm_ops hw_ops = {
- .open = pcm_hw_open,
- .close = pcm_hw_close,
- .ioctl = pcm_hw_ioctl,
-};
-
diff --git a/pcm_io.h b/pcm_io.h
deleted file mode 100644
index c4e1315..0000000
--- a/pcm_io.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* pcm.h
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#ifndef __PCM_H__
-#define __PCM_H__
-
-#include <sound/asound.h>
-
-struct pcm_ops {
- int (*open) (unsigned int card, unsigned int device,
- unsigned int flags, void **data, void *node);
- void (*close) (void *data);
- int (*ioctl) (void *data, unsigned int cmd, ...);
-};
-
-#endif /* end of __PCM_H__ */
diff --git a/pcm_plugin.c b/pcm_plugin.c
deleted file mode 100644
index 8ffe6ae..0000000
--- a/pcm_plugin.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/* pcm_plugin.c
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <poll.h>
-#include <dlfcn.h>
-
-#include <sys/ioctl.h>
-#include <linux/ioctl.h>
-#include <sound/asound.h>
-#include <tinyalsa/asoundlib.h>
-#include <tinyalsa/pcm_plugin.h>
-
-#include "pcm_io.h"
-#include "snd_utils.h"
-
-/* 2 words of uint32_t = 64 bits of mask */
-#define PCM_MASK_SIZE (2)
-#define ARRAY_SIZE(a) \
- (sizeof(a) / sizeof(a[0]))
-
-#define PCM_PARAM_GET_MASK(p, n) \
- &p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK];
-
-enum {
- PCM_PLUG_HW_PARAM_SELECT_MIN,
- PCM_PLUG_HW_PARAM_SELECT_MAX,
- PCM_PLUG_HW_PARAM_SELECT_VAL,
-};
-
-enum {
- PCM_PLUG_STATE_OPEN,
- PCM_PLUG_STATE_SETUP,
- PCM_PLUG_STATE_PREPARED,
- PCM_PLUG_STATE_RUNNING,
-};
-
-struct pcm_plug_data {
- unsigned int card;
- unsigned int device;
- unsigned int fd;
- unsigned int flags;
-
- void *dl_hdl;
- PCM_PLUGIN_OPEN_FN_PTR();
-
- struct pcm_plugin *plugin;
- void *dev_node;
-};
-
-static unsigned int my_params[] = {
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- SNDRV_PCM_HW_PARAM_RATE,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- SNDRV_PCM_HW_PARAM_PERIODS,
-};
-
-static void pcm_plug_close(void *data)
-{
- struct pcm_plug_data *plug_data = data;
- struct pcm_plugin *plugin = plug_data->plugin;
-
- plugin->ops->close(plugin);
- dlclose(plug_data->dl_hdl);
-
- free(plug_data);
-}
-
-static int pcm_plug_info(struct pcm_plug_data *plug_data,
- struct snd_pcm_info *info)
-{
- int stream = SNDRV_PCM_STREAM_PLAYBACK;
- int ret = 0, val = -1;
- char *name;
-
- memset(info, 0, sizeof(*info));
-
- if (plug_data->flags & PCM_IN) {
- stream = SNDRV_PCM_STREAM_CAPTURE;
- ret = snd_utils_get_int(plug_data->dev_node, "capture", &val);
- if (ret || !val) {
- fprintf(stderr, "%s: not a capture device\n", __func__);
- return -EINVAL;
- }
- } else {
- stream = SNDRV_PCM_STREAM_PLAYBACK;
- ret = snd_utils_get_int(plug_data->dev_node, "playback", &val);
- if (ret || !val) {
- fprintf(stderr, "%s: not a playback device\n", __func__);
- return -EINVAL;
- }
- }
-
- info->stream = stream;
- info->card = plug_data->card;
- info->device = plug_data->device;
-
- ret = snd_utils_get_str(plug_data->dev_node, "name", &name);
- if (ret) {
- fprintf(stderr, "%s: failed to get pcm device name\n", __func__);
- return ret;
- }
-
- strncpy((char *)info->id, name, sizeof(info->id));
- strncpy((char *)info->name, name, sizeof(info->name));
- strncpy((char *)info->subname, name, sizeof(info->subname));
-
- info->subdevices_count = 1;
-
- return ret;
-}
-
-static void pcm_plug_set_mask(struct snd_pcm_hw_params *p, int n, uint64_t v)
-{
- struct snd_mask *mask;
-
- mask = PCM_PARAM_GET_MASK(p, n);
-
- mask->bits[0] |= (v & 0xFFFFFFFF);
- mask->bits[1] |= ((v >> 32) & 0xFFFFFFFF);
- /*
- * currently only supporting 64 bits, may need to update to support
- * more than 64 bits
- */
-}
-
-static void pcm_plug_set_interval(struct snd_pcm_hw_params *params,
- int p, struct pcm_plugin_min_max *v, int is_integer)
-{
- struct snd_interval *i;
-
- i = ¶ms->intervals[p - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
-
- i->min = v->min;
- i->max = v->max;
-
- if (is_integer)
- i->integer = 1;
-}
-
-static int pcm_plug_frames_to_bytes(unsigned int frames,
- unsigned int frame_bits)
-{
- return (frames * (frame_bits / 8));
-}
-
-static int pcm_plug_bytes_to_frames(unsigned int size,
- unsigned int frame_bits)
-{
- return (size * 8) / frame_bits;
-}
-
-static int pcm_plug_get_params(struct pcm_plugin *plugin,
- struct snd_pcm_hw_params *params)
-{
- struct pcm_plugin_min_max bw, ch, pb, periods;
- struct pcm_plugin_min_max val;
- struct pcm_plugin_min_max frame_bits, buffer_bytes;
-
- /*
- * populate the struct snd_pcm_hw_params structure
- * using the hw_param constraints provided by plugin
- * via the plugin->constraints
- */
-
- /* Set the mask params */
- pcm_plug_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- plugin->constraints->access);
- pcm_plug_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- plugin->constraints->format);
- pcm_plug_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_SUBFORMAT_STD);
-
- /* Set the standard interval params */
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- &plugin->constraints->bit_width, 1);
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- &plugin->constraints->channels, 1);
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_RATE,
- &plugin->constraints->rate, 1);
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- &plugin->constraints->period_bytes, 0);
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_PERIODS,
- &plugin->constraints->periods, 1);
-
- /* set the calculated interval params */
-
- bw.min = plugin->constraints->bit_width.min;
- bw.max = plugin->constraints->bit_width.max;
-
- ch.min = plugin->constraints->channels.min;
- ch.max = plugin->constraints->channels.max;
-
- pb.min = plugin->constraints->period_bytes.min;
- pb.max = plugin->constraints->period_bytes.max;
-
- periods.min = plugin->constraints->periods.min;
- periods.max = plugin->constraints->periods.max;
-
- /* Calculate and set frame bits */
- frame_bits.min = bw.min * ch.min;
- frame_bits.max = bw.max * ch.max;
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- &frame_bits, 1);
-
-
- /* Calculate and set period_size in frames */
- val.min = pcm_plug_bytes_to_frames(pb.min, frame_bits.min);
- val.max = pcm_plug_bytes_to_frames(pb.max, frame_bits.min);
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- &val, 1);
-
- /* Calculate and set buffer_bytes */
- buffer_bytes.min = pb.min * periods.min;
- buffer_bytes.max = pb.max * periods.max;
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- &buffer_bytes, 1);
-
- /* Calculate and set buffer_size in frames */
- val.min = pcm_plug_bytes_to_frames(buffer_bytes.min, frame_bits.min);
- val.max = pcm_plug_bytes_to_frames(buffer_bytes.max, frame_bits.min);
- pcm_plug_set_interval(params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- &val, 1);
- return 0;
-}
-
-static int pcm_plug_masks_refine(struct snd_pcm_hw_params *p,
- struct snd_pcm_hw_params *c)
-{
- struct snd_mask *req_mask;
- struct snd_mask *con_mask;
- unsigned int idx, i, masks;
-
- masks = SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK;
-
- for (idx = 0; idx <= masks; idx++) {
-
- if (!(p->rmask & (1 << (idx + SNDRV_PCM_HW_PARAM_FIRST_MASK))))
- continue;
-
- req_mask = PCM_PARAM_GET_MASK(p, idx);
- con_mask = PCM_PARAM_GET_MASK(c, idx);
-
- /*
- * set the changed mask if requested mask value is not the same as
- * constrained mask value
- */
- if (memcmp(req_mask, con_mask, PCM_MASK_SIZE * sizeof(uint32_t)))
- p->cmask |= 1 << (idx + SNDRV_PCM_HW_PARAM_FIRST_MASK);
-
- /* Actually change the requested mask to constrained mask */
- for (i = 0; i < PCM_MASK_SIZE; i++)
- req_mask->bits[i] &= con_mask->bits[i];
- }
-
- return 0;
-}
-
-static int pcm_plug_interval_refine(struct snd_pcm_hw_params *p,
- struct snd_pcm_hw_params *c)
-{
- struct snd_interval *ri;
- struct snd_interval *ci;
- unsigned int idx;
- unsigned int intervals;
- int changed = 0;
-
- intervals = SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
- SNDRV_PCM_HW_PARAM_FIRST_INTERVAL;
-
- for (idx = 0; idx <= intervals; idx++) {
- ri = &p->intervals[idx];
- ci = &c->intervals[idx];
-
- if (!(p->rmask & (1 << (idx + SNDRV_PCM_HW_PARAM_FIRST_INTERVAL)) ))
- continue;
-
- if (ri->min < ci->min) {
- ri->min = ci->min;
- ri->openmin = ci->openmin;
- changed = 1;
- } else if (ri->min == ci->min && !ri->openmin && ci->openmin) {
- ri->openmin = 1;
- changed = 1;
- }
-
- if (ri->max > ci->max) {
- ri->max = ci->max;
- ri->openmax = ci->openmax;
- changed = 1;
- } else if (ri->max == ci->max && !ri->openmax && ci->openmax) {
- ri->openmax = 1;
- changed = 1;
- };
-
- if (!ri->integer && ci->integer) {
- ri->integer = 1;
- changed = 1;
- }
-
- if (ri->integer) {
- if (ri->openmin) {
- ri->min++;
- ri->openmin = 0;
- }
- if (ri->openmax) {
- ri->max--;
- ri->openmax = 0;
- }
- } else if (!ri->openmin && !ri->openmax && ri->min == ri->max) {
- ri->integer = 1;
- }
-
- /* Set the changed mask */
- if (changed)
- p->cmask |= (1 << (idx + SNDRV_PCM_HW_PARAM_FIRST_INTERVAL));
- }
-
- return 0;
-}
-
-
-static int pcm_plug_hw_params_refine(struct snd_pcm_hw_params *p,
- struct snd_pcm_hw_params *c)
-{
- int rc;
-
- rc = pcm_plug_masks_refine(p, c);
- if (rc) {
- fprintf(stderr, "%s: masks refine failed %d\n", __func__, rc);
- return rc;
- }
-
- rc = pcm_plug_interval_refine(p, c);
- if (rc) {
- fprintf(stderr, "%s: interval refine failed %d\n", __func__, rc);
- return rc;
- }
-
- /* clear the requested params */
- p->rmask = 0;
-
- return rc;
-}
-
-static int __pcm_plug_hrefine(struct pcm_plug_data *plug_data,
- struct snd_pcm_hw_params *params)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
- struct snd_pcm_hw_params plug_params;
- int rc;
-
- memset(&plug_params, 0, sizeof(plug_params));
- rc = pcm_plug_get_params(plugin, &plug_params);
- if (rc) {
- fprintf(stderr, "%s: pcm_plug_get_params failed %d\n",
- __func__, rc);
- return -EINVAL;
- }
-
- return pcm_plug_hw_params_refine(params, &plug_params);
-
-}
-
-static int pcm_plug_hrefine(struct pcm_plug_data *plug_data,
- struct snd_pcm_hw_params *params)
-{
- return __pcm_plug_hrefine(plug_data, params);
-}
-
-static int pcm_plug_interval_select(struct snd_pcm_hw_params *p,
- unsigned int param, unsigned int select, unsigned int val)
-{
- struct snd_interval *i;
-
- if (param < SNDRV_PCM_HW_PARAM_FIRST_INTERVAL ||
- param > SNDRV_PCM_HW_PARAM_LAST_INTERVAL)
- return -EINVAL;
-
- i = &p->intervals[param - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
-
- if (!i->min)
- return -EINVAL;
-
- switch (select) {
-
- case PCM_PLUG_HW_PARAM_SELECT_MIN:
- i->max = i->min;
- break;
-
- case PCM_PLUG_HW_PARAM_SELECT_MAX:
- i->min = i->max;
- break;
-
- case PCM_PLUG_HW_PARAM_SELECT_VAL:
- i->min = i->max = val;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void pcm_plug_hw_params_set(struct snd_pcm_hw_params *p)
-{
- unsigned int i, select;
- unsigned int bw, ch, period_sz, periods;
- unsigned int val1, val2, offset;
-
- offset = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL;
-
- /* Select the min values first */
- select = PCM_PLUG_HW_PARAM_SELECT_MIN;
- for (i = 0; i < ARRAY_SIZE(my_params); i++)
- pcm_plug_interval_select(p, my_params[i], select, 0);
-
- /* Select calculated values */
- select = PCM_PLUG_HW_PARAM_SELECT_VAL;
- bw = (p->intervals[SNDRV_PCM_HW_PARAM_SAMPLE_BITS - offset]).min;
- ch = (p->intervals[SNDRV_PCM_HW_PARAM_CHANNELS - offset]).min;
- period_sz = (p->intervals[SNDRV_PCM_HW_PARAM_PERIOD_SIZE - offset]).min;
- periods = (p->intervals[SNDRV_PCM_HW_PARAM_PERIODS - offset]).min;
-
- val1 = bw * ch; // frame_bits;
- pcm_plug_interval_select(p, SNDRV_PCM_HW_PARAM_FRAME_BITS, select, val1);
-
- val2 = pcm_plug_frames_to_bytes(period_sz, val1); // period_bytes;
- pcm_plug_interval_select(p, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, select,
- val2);
-
- val2 = period_sz * periods; //buffer_size;
- pcm_plug_interval_select(p, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, select, val2);
-
- val2 = pcm_plug_frames_to_bytes(period_sz * periods, val1); //buffer_bytes;
- pcm_plug_interval_select(p, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, select, val2);
-}
-
-static int pcm_plug_hparams(struct pcm_plug_data *plug_data,
- struct snd_pcm_hw_params *params)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
- int rc;
-
- if (plugin->state != PCM_PLUG_STATE_OPEN)
- return -EBADFD;
-
- params->rmask = ~0U;
-
- rc = __pcm_plug_hrefine(plug_data, params);
- if (rc) {
- fprintf(stderr, "%s: __pcm_plug_hrefine failed %d\n",
- __func__, rc);
- return rc;
- }
-
- pcm_plug_hw_params_set(params);
-
- rc = plugin->ops->hw_params(plugin, params);
- if (!rc)
- plugin->state = PCM_PLUG_STATE_SETUP;
-
- return rc;
-}
-
-static int pcm_plug_sparams(struct pcm_plug_data *plug_data,
- struct snd_pcm_sw_params *params)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
-
- if (plugin->state != PCM_PLUG_STATE_SETUP)
- return -EBADFD;
-
- return plugin->ops->sw_params(plugin, params);
-}
-
-static int pcm_plug_sync_ptr(struct pcm_plug_data *plug_data,
- struct snd_pcm_sync_ptr *sync_ptr)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
-
- return plugin->ops->sync_ptr(plugin, sync_ptr);
-}
-
-static int pcm_plug_writei_frames(struct pcm_plug_data *plug_data,
- struct snd_xferi *x)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
-
- if (plugin->state != PCM_PLUG_STATE_PREPARED &&
- plugin->state != PCM_PLUG_STATE_RUNNING)
- return -EBADFD;
-
- return plugin->ops->writei_frames(plugin, x);
-}
-
-static int pcm_plug_readi_frames(struct pcm_plug_data *plug_data,
- struct snd_xferi *x)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
-
- if (plugin->state != PCM_PLUG_STATE_RUNNING)
- return -EBADFD;
-
- return plugin->ops->readi_frames(plugin, x);
-}
-
-static int pcm_plug_ttstamp(struct pcm_plug_data *plug_data,
- int *tstamp)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
-
- if (plugin->state != PCM_PLUG_STATE_RUNNING)
- return -EBADFD;
-
- return plugin->ops->ttstamp(plugin, tstamp);
-}
-
-static int pcm_plug_prepare(struct pcm_plug_data *plug_data)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
- int rc;
-
- if (plugin->state != PCM_PLUG_STATE_SETUP)
- return -EBADFD;
-
- rc = plugin->ops->prepare(plugin);
- if (!rc)
- plugin->state = PCM_PLUG_STATE_PREPARED;
-
- return rc;
-}
-
-static int pcm_plug_start(struct pcm_plug_data *plug_data)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
- int rc;
-
- if (plugin->state != PCM_PLUG_STATE_PREPARED)
- return -EBADFD;
-
- rc = plugin->ops->start(plugin);
- if (!rc)
- plugin->state = PCM_PLUG_STATE_RUNNING;
-
- return rc;
-}
-
-static int pcm_plug_drop(struct pcm_plug_data *plug_data)
-{
- struct pcm_plugin *plugin = plug_data->plugin;
- int rc = 0;
-
- rc = plugin->ops->drop(plugin);
- if (!rc)
- plugin->state = PCM_PLUG_STATE_SETUP;
-
- return rc;
-}
-
-static int pcm_plug_ioctl(void *data, unsigned int cmd, ...)
-{
- struct pcm_plug_data *plug_data = data;
- struct pcm_plugin *plugin = plug_data->plugin;
- int ret;
- va_list ap;
- void *arg;
-
- va_start(ap, cmd);
- arg = va_arg(ap, void *);
- va_end(ap);
-
- switch (cmd) {
- case SNDRV_PCM_IOCTL_INFO:
- ret = pcm_plug_info(plug_data, arg);
- break;
- case SNDRV_PCM_IOCTL_TTSTAMP:
- ret = pcm_plug_ttstamp(plug_data, arg);
- break;
- case SNDRV_PCM_IOCTL_HW_REFINE:
- ret = pcm_plug_hrefine(plug_data, arg);
- break;
- case SNDRV_PCM_IOCTL_HW_PARAMS:
- ret = pcm_plug_hparams(plug_data, arg);
- break;
- case SNDRV_PCM_IOCTL_SW_PARAMS:
- ret = pcm_plug_sparams(plug_data, arg);
- break;
- case SNDRV_PCM_IOCTL_SYNC_PTR:
- ret = pcm_plug_sync_ptr(plug_data, arg);
- break;
- case SNDRV_PCM_IOCTL_PREPARE:
- ret = pcm_plug_prepare(plug_data);
- break;
- case SNDRV_PCM_IOCTL_START:
- ret = pcm_plug_start(plug_data);
- break;
- case SNDRV_PCM_IOCTL_DROP:
- ret = pcm_plug_drop(plug_data);
- break;
- case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
- ret = pcm_plug_writei_frames(plug_data, arg);
- break;
- case SNDRV_PCM_IOCTL_READI_FRAMES:
- ret = pcm_plug_readi_frames(plug_data, arg);
- break;
- default:
- ret = plugin->ops->ioctl(plugin, cmd, arg);
- break;
- }
-
- return ret;
-}
-
-static int pcm_plug_open(unsigned int card, unsigned int device,
- unsigned int flags, void **data, void *pcm_node)
-{
- struct pcm_plug_data *plug_data;
- const char *err = NULL;
- void *dl_hdl;
- int rc = 0;
- char *so_name, token[80], *name, *open_fn;
-
- plug_data = calloc(1, sizeof(*plug_data));
- if (!plug_data) {
- return -ENOMEM;
- }
-
- rc = snd_utils_get_str(pcm_node, "so-name", &so_name);
- if (rc) {
- fprintf(stderr, "%s: failed to get plugin lib name\n", __func__);
- goto err_get_lib;
- }
-
- dl_hdl = dlopen(so_name, RTLD_NOW);
- if (!dl_hdl) {
- fprintf(stderr, "%s: unable to open %s\n", __func__, so_name);
- goto err_dl_open;
- } else {
- fprintf(stderr, "%s: dlopen successful for %s\n", __func__, so_name);
- }
-
- dlerror();
-
- sscanf(so_name, "lib%s", token);
- name = strtok(token, ".");
-
- open_fn = calloc(1, strlen(name) + strlen("_open") + 1);
- if (!open_fn) {
- rc = -ENOMEM;
- goto err_open_fn;
- }
-
- strncpy(open_fn, name, strlen(name) + 1);
- strcat(open_fn, "_open");
-
- printf("%s - %s\n", __func__, open_fn);
- plug_data->plugin_open_fn = dlsym(dl_hdl, open_fn);
- err = dlerror();
-
- if (err) {
- fprintf(stderr, "%s: dlsym to open fn failed, err = '%s'\n",
- __func__, err);
- goto err_dlsym;
- }
-
- rc = plug_data->plugin_open_fn(&plug_data->plugin,
- card, device, flags);
- if (rc) {
- fprintf(stderr, "%s: failed to open plugin\n", __func__);
- goto err_dlsym;
- }
-
- /* Call snd-card-def to get card and pcm nodes */
- /* Check how to manage fd for plugin */
-
- plug_data->dl_hdl = dl_hdl;
- plug_data->card = card;
- plug_data->device = device;
- plug_data->dev_node = pcm_node;
- plug_data->flags = flags;
-
- *data = plug_data;
-
- plug_data->plugin->state = PCM_PLUG_STATE_OPEN;
-
- return 0;
-
-err_dlsym:
- free(open_fn);
-err_open_fn:
- dlclose(dl_hdl);
-err_get_lib:
-err_dl_open:
- free(plug_data);
-
- return rc;
-}
-
-struct pcm_ops plug_ops = {
- .open = pcm_plug_open,
- .close = pcm_plug_close,
- .ioctl = pcm_plug_ioctl,
-};
diff --git a/snd_utils.c b/snd_utils.c
deleted file mode 100644
index ac3ddf9..0000000
--- a/snd_utils.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* snd_utils.c
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "snd_utils.h"
-
-#define SND_DLSYM(h, p, s, err) \
-do { \
- err = 0; \
- p = dlsym(h, s); \
- if (!p) \
- err = -ENODEV; \
-} while(0)
-
-int snd_utils_get_int(struct snd_node *node, const char *prop, int *val)
-{
- if (!node || !node->card_node || !node->dev_node)
- return SND_NODE_TYPE_HW;
-
- return node->get_int(node->dev_node, prop, val);
-}
-
-int snd_utils_get_str(struct snd_node *node, const char *prop, char **val)
-{
- if (!node || !node->card_node || !node->dev_node)
- return SND_NODE_TYPE_HW;
-
- return node->get_str(node->dev_node, prop, val);
-}
-
-void snd_utils_put_dev_node(struct snd_node *node)
-{
- if (!node)
- return;
-
- if (node->card_node)
- node->put_card(node->card_node);
-
- if (node->dl_hdl)
- dlclose(node->dl_hdl);
-
- free(node);
-}
-
-enum snd_node_type snd_utils_get_node_type(struct snd_node *node)
-{
- int val = SND_NODE_TYPE_HW;
-
- if (!node || !node->card_node || !node->dev_node)
- return SND_NODE_TYPE_HW;
-
- node->get_int(node->dev_node, "type", &val);
-
- return val;
-};
-
-
-static int snd_utils_resolve_symbols(struct snd_node *node)
-{
- void *dl = node->dl_hdl;
- int err;
-
- SND_DLSYM(dl, node->get_card, "snd_card_def_get_card", err);
- if (err)
- goto done;
- SND_DLSYM(dl, node->put_card, "snd_card_def_put_card", err);
- if (err)
- goto done;
- SND_DLSYM(dl, node->get_node, "snd_card_def_get_node", err);
- if (err)
- goto done;
- SND_DLSYM(dl, node->get_int, "snd_card_def_get_int", err);
- if (err)
- goto done;
- SND_DLSYM(dl, node->get_str, "snd_card_def_get_str", err);
-
-done:
- return err;
-}
-
-struct snd_node *snd_utils_get_dev_node(unsigned int card,
- unsigned int device, int dev_type)
-{
- struct snd_node *node;
- int rc = 0;
-
- node = calloc(1, sizeof(*node));
- if (!node)
- return NULL;
-
- node->dl_hdl = dlopen("libsndcardparser.so", RTLD_NOW);
- if (!node->dl_hdl) {
- goto err_dl_open;
- }
-
- rc = snd_utils_resolve_symbols(node);
- if (rc < 0)
- goto err_resolve_symbols;
-
- node->card_node = node->get_card(card);
- if (!node->card_node)
- goto err_resolve_symbols;
-
- node->dev_node = node->get_node(node->card_node,
- device, dev_type);
- if (!node->dev_node)
- goto err_get_node;
-
- return node;
-
-err_get_node:
- node->put_card(node->card_node);
-
-err_resolve_symbols:
- dlclose(node->dl_hdl);
-
-err_dl_open:
- free(node);
- return NULL;
-}
diff --git a/snd_utils.h b/snd_utils.h
deleted file mode 100644
index 64bfeb8..0000000
--- a/snd_utils.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* snd_utils.h
-**
-** Copyright (c) 2019, The Linux Foundation. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above
-** copyright notice, this list of conditions and the following
-** disclaimer in the documentation and/or other materials provided
-** with the distribution.
-** * Neither the name of The Linux Foundation nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#ifndef __SND_CARD_UTILS_H__
-#define __SND_CARD_UTILS_H__
-
-#include <dlfcn.h>
-
-struct snd_node {
- void *card_node;
- void *dev_node;
- void *dl_hdl;
-
- void* (*get_card) (unsigned int card);
- void (*put_card) (void *card);
- void* (*get_node) (void *card, unsigned int id,
- int type);
- int (*get_int) (void *node, const char *prop, int *val);
- int (*get_str) (void *node, const char *prop, char **val);
-};
-
-enum {
- NODE_PCM,
- NODE_MIXER,
-};
-
-enum snd_node_type {
- SND_NODE_TYPE_HW = 0,
- SND_NODE_TYPE_PLUGIN,
- SND_NODE_TYPE_INVALID,
-};
-
-struct snd_node *snd_utils_get_dev_node(unsigned int card,
- unsigned int device, int dev_type);
-
-void snd_utils_put_dev_node(struct snd_node *node);
-
-enum snd_node_type snd_utils_get_node_type(struct snd_node *node);
-
-int snd_utils_get_int(struct snd_node *node, const char *prop, int *val);
-
-int snd_utils_get_str(struct snd_node *node, const char *prop, char **val);
-
-#endif /* end of __SND_CARD_UTILS_H__ */