index a7f5d21a05fda44f7045e51a16ce16ea8f494c11..4568cca2bfed71746b551b397f2a12e09207b894 100644 (file)
--- a/mixer.c
+++ b/mixer.c
#include <errno.h>
#include <ctype.h>
+#include <sys/ioctl.h>
+
#include <linux/ioctl.h>
#define __force
#define __bitwise
struct mixer {
int fd;
- struct snd_ctl_elem_info *info;
+ struct snd_ctl_card_info card_info;
+ struct snd_ctl_elem_info *elem_info;
struct mixer_ctl *ctl;
unsigned int count;
};
free(mixer->ctl);
}
- if (mixer->info)
- free(mixer->info);
+ if (mixer->elem_info)
+ free(mixer->elem_info);
free(mixer);
goto fail;
mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
- mixer->info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
- if (!mixer->ctl || !mixer->info)
+ mixer->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
+ if (!mixer->ctl || !mixer->elem_info)
+ goto fail;
+
+ if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0)
goto fail;
eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
goto fail;
for (n = 0; n < mixer->count; n++) {
- struct snd_ctl_elem_info *ei = mixer->info + n;
+ struct snd_ctl_elem_info *ei = mixer->elem_info + n;
ei->id.numid = eid[n].numid;
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0)
goto fail;
return 0;
}
+const char *mixer_get_name(struct mixer *mixer)
+{
+ return (const char *)mixer->card_info.name;
+}
+
unsigned int mixer_get_num_ctls(struct mixer *mixer)
{
if (!mixer)
@@ -187,19 +198,23 @@ struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name)
return NULL;
for (n = 0; n < mixer->count; n++)
- if (!strcmp(name, (char*) mixer->info[n].id.name))
+ if (!strcmp(name, (char*) mixer->elem_info[n].id.name))
return mixer->ctl + n;
return NULL;
}
-int mixer_ctl_get_name(struct mixer_ctl *ctl, char *name, unsigned int size)
+void mixer_ctl_update(struct mixer_ctl *ctl)
{
- if (!ctl || !name || (size == 0))
- return -EINVAL;
+ ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info);
+}
- strncpy(name, (char *)ctl->info->id.name, size);
- return 0;
+const char *mixer_ctl_get_name(struct mixer_ctl *ctl)
+{
+ if (!ctl)
+ return NULL;
+
+ return (const char *)ctl->info->id.name;
}
enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl)
return 0;
}
+int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count)
+{
+ struct snd_ctl_elem_value ev;
+ int ret;
+ size_t size;
+ void *source;
+
+ if (!ctl || (count > ctl->info->count) || !count || !array)
+ return -EINVAL;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.id.numid = ctl->info->id.numid;
+
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
+ if (ret < 0)
+ return ret;
+
+ switch (ctl->info->type) {
+ case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+ case SNDRV_CTL_ELEM_TYPE_INTEGER:
+ size = sizeof(ev.value.integer.value[0]);
+ source = ev.value.integer.value;
+ break;
+
+ case SNDRV_CTL_ELEM_TYPE_BYTES:
+ size = sizeof(ev.value.bytes.data[0]);
+ source = ev.value.bytes.data;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ memcpy(array, source, size * count);
+
+ return 0;
+}
+
int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
{
struct snd_ctl_elem_value ev;
return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
}
-int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
+int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
{
struct snd_ctl_elem_value ev;
- int ret;
+ size_t size;
+ void *dest;
- if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
+ if (!ctl || (count > ctl->info->count) || !count || !array)
return -EINVAL;
memset(&ev, 0, sizeof(ev));
ev.id.numid = ctl->info->id.numid;
- ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
- if (ret < 0)
- return ret;
+
+ switch (ctl->info->type) {
+ case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+ case SNDRV_CTL_ELEM_TYPE_INTEGER:
+ size = sizeof(ev.value.integer.value[0]);
+ dest = ev.value.integer.value;
+ break;
+
+ case SNDRV_CTL_ELEM_TYPE_BYTES:
+ size = sizeof(ev.value.bytes.data[0]);
+ dest = ev.value.bytes.data;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ memcpy(dest, array, size * count);
+
+ return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
+}
+
+int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
+{
+ if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
+ return -EINVAL;
return ctl->info->value.integer.min;
}
int mixer_ctl_get_range_max(struct mixer_ctl *ctl)
{
- struct snd_ctl_elem_value ev;
- int ret;
-
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
return -EINVAL;
- memset(&ev, 0, sizeof(ev));
- ev.id.numid = ctl->info->id.numid;
- ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
- if (ret < 0)
- return ret;
-
return ctl->info->value.integer.max;
}
return ctl->info->value.enumerated.items;
}
-int mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id,
- char *string, unsigned int size)
+const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
+ unsigned int enum_id)
{
- struct snd_ctl_elem_value ev;
- int ret;
-
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) ||
(enum_id >= ctl->info->value.enumerated.items))
- return -EINVAL;
-
- memset(&ev, 0, sizeof(ev));
- ev.id.numid = ctl->info->id.numid;
- ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
- if (ret < 0)
- return ret;
- strncpy(string, (char *)ctl->ename[enum_id], size);
+ return NULL;
- return 0;
+ return (const char *)ctl->ename[enum_id];
}
int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string)