mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
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:
parent
567cc19a88
commit
15c6f83296
4 changed files with 84 additions and 2 deletions
|
|
@ -418,6 +418,7 @@ void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val);
|
|||
int snd_ctl_elem_add_integer(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long imin, long imax, long istep);
|
||||
int snd_ctl_elem_add_integer64(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long long imin, long long imax, long long istep);
|
||||
int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count);
|
||||
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[]);
|
||||
int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id);
|
||||
int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@
|
|||
#if defined(LINUX) || defined(__LINUX__) || defined(__linux__)
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/time.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
|
|
@ -734,7 +734,7 @@ struct sndrv_timer_tread {
|
|||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
|
||||
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
|
||||
|
||||
struct sndrv_ctl_card_info {
|
||||
int card; /* card number */
|
||||
|
|
@ -833,6 +833,8 @@ struct sndrv_ctl_elem_info {
|
|||
unsigned int items; /* R: number of items */
|
||||
unsigned int item; /* W: item number */
|
||||
char name[64]; /* R: value name */
|
||||
__u64 names_ptr; /* W: names list (ELEM_ADD only) */
|
||||
unsigned int names_length;
|
||||
} enumerated;
|
||||
unsigned char reserved[128];
|
||||
} value;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -148,6 +148,11 @@ static int snd_ctl_hw_elem_info(snd_ctl_t *handle, snd_ctl_elem_info_t *info)
|
|||
static int snd_ctl_hw_elem_add(snd_ctl_t *handle, snd_ctl_elem_info_t *info)
|
||||
{
|
||||
snd_ctl_hw_t *hw = handle->private_data;
|
||||
|
||||
if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED &&
|
||||
hw->protocol < SNDRV_PROTOCOL_VERSION(2, 0, 7))
|
||||
return -ENXIO;
|
||||
|
||||
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEM_ADD, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
|
|
@ -156,6 +161,11 @@ static int snd_ctl_hw_elem_add(snd_ctl_t *handle, snd_ctl_elem_info_t *info)
|
|||
static int snd_ctl_hw_elem_replace(snd_ctl_t *handle, snd_ctl_elem_info_t *info)
|
||||
{
|
||||
snd_ctl_hw_t *hw = handle->private_data;
|
||||
|
||||
if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED &&
|
||||
hw->protocol < SNDRV_PROTOCOL_VERSION(2, 0, 7))
|
||||
return -ENXIO;
|
||||
|
||||
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEM_REPLACE, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue