control: add snd_ctl_elem_add_enumerated()

Handling of user control elements was implemented for all types except
BYTES and ENUMERATED.  Enumerated user controls will be needed for the
device-specific mixers of upcoming FireWire drivers.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
This commit is contained in:
Clemens Ladisch 2011-10-07 22:46:51 +02:00
parent 567cc19a88
commit 15c6f83296
4 changed files with 84 additions and 2 deletions

View file

@ -42,6 +42,7 @@ and IEC958 structure.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
@ -358,6 +359,74 @@ int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
return ctl->ops->element_add(ctl, info);
}
/**
* \brief Create and add a user-defined control element of type enumerated.
* \param[in] ctl Control device handle.
* \param[in] id ID of the new control element.
* \param[in] count Number of element values.
* \param[in] items Range of possible values (0 ... \a items - 1).
* \param[in] names An array containing \a items strings.
* \return Zero on success, otherwise a negative error code.
*
* This function creates a user element, i.e., a control element that is not
* controlled by the control device's driver but that is just stored together
* with the other elements of \a ctl.
*
* The fields of \a id, except numid, must be set to unique values that
* identify the new element.
*
* The new element is locked; its value is initialized as zero.
*
* \par Errors:
* <dl>
* <dt>-EBUSY<dd>A control element with ID \a id already exists.
* <dt>-EINVAL<dd>\a count is not at least one or greater than 128, or \a items
* is not at least one, or a string in \a names is empty or longer than 63
* bytes, or the strings in \a names require more than 64 KB storage.
* <dt>-ENOMEM<dd>Out of memory, or there are too many user control elements.
* <dt>-ENXIO<dd>This driver does not support (enumerated) user controls.
* <dt>-ENODEV<dd>Device unplugged.
* </dl>
*
* \par Compatibility:
* snd_ctl_elem_add_enumerated() was introduced in ALSA 1.0.25.
*/
int snd_ctl_elem_add_enumerated(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
unsigned int count, unsigned int items,
const char *const names[])
{
snd_ctl_elem_info_t *info;
unsigned int i, bytes;
char *buf, *p;
int err;
assert(ctl && id && id->name[0] && names);
snd_ctl_elem_info_alloca(&info);
info->id = *id;
info->type = SND_CTL_ELEM_TYPE_ENUMERATED;
info->count = count;
info->value.enumerated.items = items;
bytes = 0;
for (i = 0; i < items; ++i)
bytes += strlen(names[i]) + 1;
buf = malloc(bytes);
if (!buf)
return -ENOMEM;
info->value.enumerated.names_ptr = (uintptr_t)buf;
info->value.enumerated.names_length = bytes;
p = buf;
for (i = 0; i < items; ++i)
p = stpcpy(p, names[i]) + 1;
err = ctl->ops->element_add(ctl, info);
free(buf);
return err;
}
/**
* \brief Create and add an user IEC958 CTL element
* \param ctl CTL handle