Completed control and mixer API

This commit is contained in:
Abramo Bagnara 2001-02-09 11:20:31 +00:00
parent c709b0a627
commit fea0c73cdb
23 changed files with 1988 additions and 1251 deletions

View file

@ -555,8 +555,6 @@ int ctl_shm_close(client_t *client)
return 0;
}
extern int snd_ctl_read1(snd_ctl_t *ctl, snd_ctl_event_t *event);
int ctl_shm_cmd(client_t *client)
{
snd_ctl_shm_ctrl_t *ctrl = client->transport.shm.ctrl;
@ -571,28 +569,31 @@ int ctl_shm_cmd(client_t *client)
ctrl->cmd = 0;
ctl = client->device.control.handle;
switch (cmd) {
case SND_CTL_IOCTL_ASYNC:
ctrl->result = snd_ctl_async(ctl, ctrl->u.async.sig, ctrl->u.async.pid);
break;
case SNDRV_CTL_IOCTL_INFO:
ctrl->result = snd_ctl_card_info(ctl, &ctrl->u.hw_info);
break;
case SNDRV_CTL_IOCTL_ELEMENT_LIST:
case SNDRV_CTL_IOCTL_ELEM_LIST:
{
size_t maxsize = CTL_SHM_DATA_MAXLEN;
if (ctrl->u.clist.space * sizeof(*ctrl->u.clist.pids) > maxsize) {
if (ctrl->u.element_list.space * sizeof(*ctrl->u.element_list.pids) > maxsize) {
ctrl->result = -EFAULT;
break;
}
ctrl->u.clist.pids = (snd_ctl_element_id_t*) ctrl->data;
ctrl->result = snd_ctl_clist(ctl, &ctrl->u.clist);
ctrl->u.element_list.pids = (snd_ctl_elem_id_t*) ctrl->data;
ctrl->result = snd_ctl_elem_list(ctl, &ctrl->u.element_list);
break;
}
case SNDRV_CTL_IOCTL_ELEMENT_INFO:
ctrl->result = snd_ctl_element_info(ctl, &ctrl->u.cinfo);
case SNDRV_CTL_IOCTL_ELEM_INFO:
ctrl->result = snd_ctl_elem_info(ctl, &ctrl->u.element_info);
break;
case SNDRV_CTL_IOCTL_ELEMENT_READ:
ctrl->result = snd_ctl_element_read(ctl, &ctrl->u.cread);
case SNDRV_CTL_IOCTL_ELEM_READ:
ctrl->result = snd_ctl_elem_read(ctl, &ctrl->u.element_read);
break;
case SNDRV_CTL_IOCTL_ELEMENT_WRITE:
ctrl->result = snd_ctl_element_write(ctl, &ctrl->u.cwrite);
case SNDRV_CTL_IOCTL_ELEM_WRITE:
ctrl->result = snd_ctl_elem_write(ctl, &ctrl->u.element_write);
break;
case SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE:
ctrl->result = snd_ctl_hwdep_next_device(ctl, &ctrl->u.device);
@ -619,7 +620,7 @@ int ctl_shm_cmd(client_t *client)
ctrl->result = snd_ctl_rawmidi_prefer_subdevice(ctl, ctrl->u.rawmidi_prefer_subdevice);
break;
case SND_CTL_IOCTL_READ:
ctrl->result = snd_ctl_read1(ctl, &ctrl->u.read);
ctrl->result = snd_ctl_read(ctl, &ctrl->u.read);
break;
case SND_CTL_IOCTL_CLOSE:
client->ops->close(client);

View file

@ -3,9 +3,10 @@ sysinclude_HEADERS = asoundlib.h
# This is the order they will be concatenated into asoundlib.h!
#
header_files=header.h version.h global.h input.h output.h error.h mixer.h \
header_files=header.h version.h global.h input.h output.h error.h \
pcm.h pcm_m4.h rawmidi.h rawmidi_m4.h timer.h \
hwdep.h hwdep_m4.h control.h control_m4.h \
mixer.h mixer_m4.h \
seq.h seqmid.h seq_midi_event.h \
conv.h instr.h conf.h footer.h

View file

@ -83,17 +83,22 @@ typedef struct {
#define SND_CTL_IOCTL_READ _IOR('U', 0xf1, snd_ctl_event_t)
#define SND_CTL_IOCTL_CLOSE _IO ('U', 0xf2)
#define SND_CTL_IOCTL_POLL_DESCRIPTOR _IO ('U', 0xf3)
#define SND_CTL_IOCTL_ASYNC _IO ('U', 0xf4)
typedef struct {
int result;
int cmd;
union {
struct {
int sig;
pid_t pid;
} async;
int device;
snd_ctl_card_info_t hw_info;
snd_ctl_element_list_t clist;
snd_ctl_element_info_t cinfo;
snd_ctl_element_t cread;
snd_ctl_element_t cwrite;
snd_ctl_elem_list_t element_list;
snd_ctl_elem_info_t element_info;
snd_ctl_elem_t element_read;
snd_ctl_elem_t element_write;
snd_hwdep_info_t hwdep_info;
snd_pcm_info_t pcm_info;
int pcm_prefer_subdevice;

View file

@ -7,21 +7,21 @@
typedef struct sndrv_aes_iec958 snd_aes_iec958_t;
typedef struct _snd_ctl_card_info snd_ctl_card_info_t;
typedef struct _snd_ctl_element_id snd_ctl_element_id_t;
typedef struct _snd_ctl_element_list snd_ctl_element_list_t;
typedef struct _snd_ctl_element_info snd_ctl_element_info_t;
typedef struct _snd_ctl_element snd_ctl_element_t;
typedef struct _snd_ctl_elem_id snd_ctl_elem_id_t;
typedef struct _snd_ctl_elem_list snd_ctl_elem_list_t;
typedef struct _snd_ctl_elem_info snd_ctl_elem_info_t;
typedef struct _snd_ctl_elem snd_ctl_elem_t;
typedef struct _snd_ctl_event snd_ctl_event_t;
#ifdef SND_ENUM_TYPECHECK
typedef struct __snd_card_type *snd_card_type_t;
typedef struct __snd_ctl_element_type *snd_ctl_element_type_t;
typedef struct __snd_ctl_element_iface *snd_ctl_element_iface_t;
typedef struct __snd_ctl_elem_type *snd_ctl_elem_type_t;
typedef struct __snd_ctl_elem_iface *snd_ctl_elem_iface_t;
typedef struct __snd_ctl_event_type *snd_ctl_event_type_t;
#else
typedef enum sndrv_card_type snd_card_type_t;
typedef enum sndrv_ctl_element_type snd_ctl_element_type_t;
typedef enum sndrv_ctl_element_iface snd_ctl_element_iface_t;
typedef enum sndrv_ctl_elem_type snd_ctl_elem_type_t;
typedef enum sndrv_ctl_elem_iface snd_ctl_elem_iface_t;
typedef enum sndrv_ctl_event_type snd_ctl_event_type_t;
#endif
@ -95,22 +95,22 @@ typedef enum sndrv_ctl_event_type snd_ctl_event_type_t;
#define SND_CARD_TYPE_VIA8233 ((snd_card_type_t) SNDRV_CARD_TYPE_VIA8233)
#define SND_CARD_TYPE_LAST ((snd_card_type_t) SNDRV_CARD_TYPE_LAST)
#define SND_CTL_ELEMENT_TYPE_NONE ((snd_ctl_element_type_t) SNDRV_CTL_ELEMENT_TYPE_NONE)
#define SND_CTL_ELEMENT_TYPE_BOOLEAN ((snd_ctl_element_type_t) SNDRV_CTL_ELEMENT_TYPE_BOOLEAN)
#define SND_CTL_ELEMENT_TYPE_INTEGER ((snd_ctl_element_type_t) SNDRV_CTL_ELEMENT_TYPE_INTEGER)
#define SND_CTL_ELEMENT_TYPE_ENUMERATED ((snd_ctl_element_type_t) SNDRV_CTL_ELEMENT_TYPE_ENUMERATED)
#define SND_CTL_ELEMENT_TYPE_BYTES ((snd_ctl_element_type_t) SNDRV_CTL_ELEMENT_TYPE_BYTES)
#define SND_CTL_ELEMENT_TYPE_IEC958 ((snd_ctl_element_type_t) SNDRV_CTL_ELEMENT_TYPE_IEC958)
#define SND_CTL_ELEMENT_TYPE_LAST ((snd_ctl_element_type_t) SNDRV_CTL_ELEMENT_TYPE_LAST)
#define SND_CTL_ELEM_TYPE_NONE ((snd_ctl_elem_type_t) SNDRV_CTL_ELEM_TYPE_NONE)
#define SND_CTL_ELEM_TYPE_BOOLEAN ((snd_ctl_elem_type_t) SNDRV_CTL_ELEM_TYPE_BOOLEAN)
#define SND_CTL_ELEM_TYPE_INTEGER ((snd_ctl_elem_type_t) SNDRV_CTL_ELEM_TYPE_INTEGER)
#define SND_CTL_ELEM_TYPE_ENUMERATED ((snd_ctl_elem_type_t) SNDRV_CTL_ELEM_TYPE_ENUMERATED)
#define SND_CTL_ELEM_TYPE_BYTES ((snd_ctl_elem_type_t) SNDRV_CTL_ELEM_TYPE_BYTES)
#define SND_CTL_ELEM_TYPE_IEC958 ((snd_ctl_elem_type_t) SNDRV_CTL_ELEM_TYPE_IEC958)
#define SND_CTL_ELEM_TYPE_LAST ((snd_ctl_elem_type_t) SNDRV_CTL_ELEM_TYPE_LAST)
#define SND_CTL_ELEMENT_IFACE_CARD ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_CARD)
#define SND_CTL_ELEMENT_IFACE_HWDEP ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_HWDEP)
#define SND_CTL_ELEMENT_IFACE_MIXER ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_MIXER)
#define SND_CTL_ELEMENT_IFACE_PCM ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_PCM)
#define SND_CTL_ELEMENT_IFACE_RAWMIDI ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_RAWMIDI)
#define SND_CTL_ELEMENT_IFACE_TIMER ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_TIMER)
#define SND_CTL_ELEMENT_IFACE_SEQUENCER ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_SEQUENCER)
#define SND_CTL_ELEMENT_IFACE_LAST ((snd_ctl_element_iface_t) SNDRV_CTL_ELEMENT_IFACE_LAST)
#define SND_CTL_ELEM_IFACE_CARD ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_CARD)
#define SND_CTL_ELEM_IFACE_HWDEP ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_HWDEP)
#define SND_CTL_ELEM_IFACE_MIXER ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_MIXER)
#define SND_CTL_ELEM_IFACE_PCM ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_PCM)
#define SND_CTL_ELEM_IFACE_RAWMIDI ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_RAWMIDI)
#define SND_CTL_ELEM_IFACE_TIMER ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_TIMER)
#define SND_CTL_ELEM_IFACE_SEQUENCER ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_SEQUENCER)
#define SND_CTL_ELEM_IFACE_LAST ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_LAST)
#define SND_CTL_EVENT_REBUILD ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_REBUILD)
#define SND_CTL_EVENT_VALUE ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_VALUE)
@ -136,7 +136,6 @@ typedef enum _snd_ctl_type snd_ctl_type_t;
#define SND_CTL_TYPE_INET ((snd_ctl_type_t) SND_CTL_TYPE_INET)
typedef struct _snd_ctl snd_ctl_t;
typedef struct _snd_ctl_callbacks snd_ctl_callbacks_t;
#ifdef __cplusplus
extern "C" {
@ -155,35 +154,37 @@ int snd_defaults_pcm_device(void);
int snd_defaults_rawmidi_card(void);
int snd_defaults_rawmidi_device(void);
snd_ctl_type_t snd_ctl_type(snd_ctl_t *handle);
int snd_ctl_open(snd_ctl_t **handle, char *name);
int snd_ctl_close(snd_ctl_t *handle);
int snd_ctl_card(snd_ctl_t *handle);
int snd_ctl_poll_descriptor(snd_ctl_t *handle);
int snd_ctl_card_info(snd_ctl_t *handle, snd_ctl_card_info_t *info);
int snd_ctl_clist(snd_ctl_t *handle, snd_ctl_element_list_t * list);
int snd_ctl_element_info(snd_ctl_t *handle, snd_ctl_element_info_t * sw);
int snd_ctl_element_read(snd_ctl_t *handle, snd_ctl_element_t * control);
int snd_ctl_element_write(snd_ctl_t *handle, snd_ctl_element_t * control);
int snd_ctl_hwdep_next_device(snd_ctl_t *handle, int * device);
int snd_ctl_hwdep_info(snd_ctl_t *handle, snd_hwdep_info_t * info);
int snd_ctl_pcm_next_device(snd_ctl_t *handle, int *device);
int snd_ctl_pcm_info(snd_ctl_t *handle, snd_pcm_info_t * info);
int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *handle, int subdev);
int snd_ctl_rawmidi_next_device(snd_ctl_t *handle, int * device);
int snd_ctl_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info);
int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *handle, int subdev);
snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl);
int snd_ctl_open(snd_ctl_t **ctl, char *name);
int snd_ctl_close(snd_ctl_t *ctl);
int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock);
int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid);
int snd_ctl_poll_descriptor(snd_ctl_t *ctl);
int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info);
int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t * list);
int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info);
int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_t *value);
int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_t *value);
int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int * device);
int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info);
int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int *device);
int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info);
int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev);
int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device);
int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info);
int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev);
int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks);
int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event);
int snd_ctl_wait(snd_ctl_t *ctl, int timeout);
void snd_ctl_element_set_bytes(snd_ctl_element_t *obj, void *data, size_t size);
void snd_ctl_elem_set_bytes(snd_ctl_elem_t *obj, void *data, size_t size);
const char *snd_ctl_element_type_name(snd_ctl_element_type_t type);
const char *snd_ctl_element_iface_name(snd_ctl_element_iface_t iface);
const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type);
const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface);
const char *snd_ctl_event_type_name(snd_ctl_event_type_t type);
int snd_ctl_element_list_alloc_space(snd_ctl_element_list_t *obj, unsigned int entries);
void snd_ctl_element_list_free_space(snd_ctl_element_list_t *obj);
int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries);
void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj);
#ifdef __cplusplus
}
@ -193,41 +194,35 @@ void snd_ctl_element_list_free_space(snd_ctl_element_list_t *obj);
* Highlevel API for controls
*/
typedef struct _snd_hctl_element_list snd_hctl_element_list_t;
typedef struct _snd_hctl_element snd_hctl_element_t;
typedef struct _snd_hctl_elem snd_hctl_elem_t;
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*snd_ctl_hsort_t)(const snd_hctl_element_t *c1, const snd_hctl_element_t *c2);
typedef void (*snd_ctl_hcallback_rebuild_t)(snd_ctl_t *handle, void *private_data);
typedef void (*snd_ctl_hcallback_add_t)(snd_ctl_t *handle, void *private_data, snd_hctl_element_t *helem);
typedef void (*snd_hctl_element_callback_t)(snd_ctl_t *handle, snd_hctl_element_t *helem);
typedef void (*snd_hctl_element_private_free_t)(snd_hctl_element_t *helem);
typedef int (*snd_hctl_compare_t)(const snd_hctl_elem_t *e1,
const snd_hctl_elem_t *e2);
typedef int (*snd_hctl_callback_t)(snd_ctl_t *ctl,
snd_ctl_event_type_t event,
snd_hctl_elem_t *elem);
typedef int (*snd_hctl_elem_callback_t)(snd_hctl_elem_t *elem,
snd_ctl_event_type_t event);
int snd_ctl_hbuild(snd_ctl_t *handle, snd_ctl_hsort_t csort);
int snd_ctl_hfree(snd_ctl_t *handle);
snd_hctl_element_t *snd_ctl_hfirst(snd_ctl_t *handle);
snd_hctl_element_t *snd_ctl_hlast(snd_ctl_t *handle);
snd_hctl_element_t *snd_ctl_hnext(snd_ctl_t *handle, snd_hctl_element_t *helem);
snd_hctl_element_t *snd_ctl_hprev(snd_ctl_t *handle, snd_hctl_element_t *helem);
int snd_ctl_hcount(snd_ctl_t *handle);
snd_hctl_element_t *snd_ctl_hfind(snd_ctl_t *handle, snd_ctl_element_id_t *id);
int snd_ctl_hlist(snd_ctl_t *handle, snd_hctl_element_list_t *hlist);
int snd_ctl_hsort(const snd_hctl_element_t *c1, const snd_hctl_element_t *c2);
int snd_ctl_hresort(snd_ctl_t *handle, snd_ctl_hsort_t csort);
int snd_ctl_hcallback_rebuild(snd_ctl_t *handle, snd_ctl_hcallback_rebuild_t callback, void *private_data);
int snd_ctl_hcallback_add(snd_ctl_t *handle, snd_ctl_hcallback_add_t callback, void *private_data);
int snd_ctl_hevent(snd_ctl_t *handle);
int snd_ctl_hbag_create(void **bag);
int snd_ctl_hbag_destroy(void **bag, void (*hctl_element_free)(snd_hctl_element_t *helem));
int snd_ctl_hbag_add(void **bag, snd_hctl_element_t *helem);
int snd_ctl_hbag_del(void **bag, snd_hctl_element_t *helem);
snd_hctl_element_t *snd_ctl_hbag_find(void **bag, snd_ctl_element_id_t *id);
int snd_hctl_element_list_alloc_space(snd_hctl_element_list_t *obj, unsigned int entries);
void snd_hctl_element_list_free_space(snd_hctl_element_list_t *obj);
int snd_hctl_build(snd_ctl_t *ctl);
snd_hctl_elem_t *snd_hctl_first_elem(snd_ctl_t *ctl);
snd_hctl_elem_t *snd_hctl_last_elem(snd_ctl_t *ctl);
snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem);
snd_hctl_elem_t *snd_hctl_elem_prev(snd_hctl_elem_t *elem);
int snd_hctl_elem_info(snd_hctl_elem_t *elem, snd_ctl_elem_info_t *info);
int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_t * value);
int snd_hctl_elem_write(snd_hctl_elem_t *elem, snd_ctl_elem_t * value);
unsigned int snd_hctl_get_count(snd_ctl_t *ctl);
snd_hctl_elem_t *snd_hctl_find_elem(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id);
void snd_hctl_set_callback(snd_ctl_t *ctl, snd_hctl_callback_t callback);
void snd_hctl_set_callback_private(snd_ctl_t *ctl, void *private);
void *snd_hctl_get_callback_private(snd_ctl_t *ctl);
int snd_hctl_event(snd_ctl_t *ctl, snd_ctl_event_t *event);
int snd_hctl_events(snd_ctl_t *ctl);
#ifdef __cplusplus
}

View file

@ -2,35 +2,35 @@
extern "C" {
#endif
size_t snd_ctl_element_id_sizeof();
#define snd_ctl_element_id_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_element_id_t *) alloca(snd_ctl_element_id_sizeof()); memset(*ptr, 0, snd_ctl_element_id_sizeof()); 0; })
int snd_ctl_element_id_malloc(snd_ctl_element_id_t **ptr);
void snd_ctl_element_id_free(snd_ctl_element_id_t *obj);
void snd_ctl_element_id_copy(snd_ctl_element_id_t *dst, const snd_ctl_element_id_t *src);
size_t snd_ctl_elem_id_sizeof();
#define snd_ctl_elem_id_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_elem_id_t *) alloca(snd_ctl_elem_id_sizeof()); memset(*ptr, 0, snd_ctl_elem_id_sizeof()); 0; })
int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr);
void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj);
void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src);
unsigned int snd_ctl_element_id_get_numid(const snd_ctl_element_id_t *obj);
unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj);
snd_ctl_element_iface_t snd_ctl_element_id_get_interface(const snd_ctl_element_id_t *obj);
snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj);
unsigned int snd_ctl_element_id_get_device(const snd_ctl_element_id_t *obj);
unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj);
unsigned int snd_ctl_element_id_get_subdevice(const snd_ctl_element_id_t *obj);
unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj);
const char *snd_ctl_element_id_get_name(const snd_ctl_element_id_t *obj);
const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj);
unsigned int snd_ctl_element_id_get_index(const snd_ctl_element_id_t *obj);
unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj);
void snd_ctl_element_id_set_numid(snd_ctl_element_id_t *obj, unsigned int val);
void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val);
void snd_ctl_element_id_set_interface(snd_ctl_element_id_t *obj, snd_ctl_element_iface_t val);
void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val);
void snd_ctl_element_id_set_device(snd_ctl_element_id_t *obj, unsigned int val);
void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val);
void snd_ctl_element_id_set_subdevice(snd_ctl_element_id_t *obj, unsigned int val);
void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val);
void snd_ctl_element_id_set_name(snd_ctl_element_id_t *obj, const char *val);
void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val);
void snd_ctl_element_id_set_index(snd_ctl_element_id_t *obj, unsigned int val);
void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val);
size_t snd_ctl_card_info_sizeof();
#define snd_ctl_card_info_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_card_info_t *) alloca(snd_ctl_card_info_sizeof()); memset(*ptr, 0, snd_ctl_card_info_sizeof()); 0; })
@ -64,9 +64,9 @@ snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj);
unsigned int snd_ctl_event_get_numid(const snd_ctl_event_t *obj);
void snd_ctl_event_get_id(const snd_ctl_event_t *obj, snd_ctl_element_id_t *ptr);
void snd_ctl_event_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr);
snd_ctl_element_iface_t snd_ctl_event_get_interface(const snd_ctl_event_t *obj);
snd_ctl_elem_iface_t snd_ctl_event_get_interface(const snd_ctl_event_t *obj);
unsigned int snd_ctl_event_get_device(const snd_ctl_event_t *obj);
@ -76,207 +76,175 @@ const char *snd_ctl_event_get_name(const snd_ctl_event_t *obj);
unsigned int snd_ctl_event_get_index(const snd_ctl_event_t *obj);
size_t snd_ctl_element_list_sizeof();
#define snd_ctl_element_list_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_element_list_t *) alloca(snd_ctl_element_list_sizeof()); memset(*ptr, 0, snd_ctl_element_list_sizeof()); 0; })
int snd_ctl_element_list_malloc(snd_ctl_element_list_t **ptr);
void snd_ctl_element_list_free(snd_ctl_element_list_t *obj);
void snd_ctl_element_list_copy(snd_ctl_element_list_t *dst, const snd_ctl_element_list_t *src);
size_t snd_ctl_elem_list_sizeof();
#define snd_ctl_elem_list_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_elem_list_t *) alloca(snd_ctl_elem_list_sizeof()); memset(*ptr, 0, snd_ctl_elem_list_sizeof()); 0; })
int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr);
void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj);
void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src);
void snd_ctl_element_list_set_offset(snd_ctl_element_list_t *obj, unsigned int val);
void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val);
unsigned int snd_ctl_element_list_get_used(const snd_ctl_element_list_t *obj);
unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj);
unsigned int snd_ctl_element_list_get_count(const snd_ctl_element_list_t *obj);
unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj);
void snd_ctl_element_list_get_id(const snd_ctl_element_list_t *obj, unsigned int idx, snd_ctl_element_id_t *ptr);
void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr);
unsigned int snd_ctl_element_list_get_numid(const snd_ctl_element_list_t *obj, unsigned int idx);
unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx);
snd_ctl_element_iface_t snd_ctl_element_list_get_interface(const snd_ctl_element_list_t *obj, unsigned int idx);
snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx);
unsigned int snd_ctl_element_list_get_device(const snd_ctl_element_list_t *obj, unsigned int idx);
unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx);
unsigned int snd_ctl_element_list_get_subdevice(const snd_ctl_element_list_t *obj, unsigned int idx);
unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx);
const char *snd_ctl_element_list_get_name(const snd_ctl_element_list_t *obj, unsigned int idx);
const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx);
unsigned int snd_ctl_element_list_get_index(const snd_ctl_element_list_t *obj, unsigned int idx);
unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx);
size_t snd_ctl_element_info_sizeof();
#define snd_ctl_element_info_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_element_info_t *) alloca(snd_ctl_element_info_sizeof()); memset(*ptr, 0, snd_ctl_element_info_sizeof()); 0; })
int snd_ctl_element_info_malloc(snd_ctl_element_info_t **ptr);
void snd_ctl_element_info_free(snd_ctl_element_info_t *obj);
void snd_ctl_element_info_copy(snd_ctl_element_info_t *dst, const snd_ctl_element_info_t *src);
size_t snd_ctl_elem_info_sizeof();
#define snd_ctl_elem_info_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_elem_info_t *) alloca(snd_ctl_elem_info_sizeof()); memset(*ptr, 0, snd_ctl_elem_info_sizeof()); 0; })
int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr);
void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj);
void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src);
snd_ctl_element_type_t snd_ctl_element_info_get_type(const snd_ctl_element_info_t *obj);
snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj);
int snd_ctl_element_info_is_readable(const snd_ctl_element_info_t *obj);
int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj);
int snd_ctl_element_info_is_writable(const snd_ctl_element_info_t *obj);
int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj);
int snd_ctl_element_info_is_volatile(const snd_ctl_element_info_t *obj);
int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj);
int snd_ctl_element_info_is_inactive(const snd_ctl_element_info_t *obj);
int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj);
int snd_ctl_element_info_is_locked(const snd_ctl_element_info_t *obj);
int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj);
int snd_ctl_element_info_is_indirect(const snd_ctl_element_info_t *obj);
int snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t *obj);
unsigned int snd_ctl_element_info_get_count(const snd_ctl_element_info_t *obj);
unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj);
long snd_ctl_element_info_get_min(const snd_ctl_element_info_t *obj);
long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj);
long snd_ctl_element_info_get_max(const snd_ctl_element_info_t *obj);
long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj);
long snd_ctl_element_info_get_step(const snd_ctl_element_info_t *obj);
long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj);
unsigned int snd_ctl_element_info_get_items(const snd_ctl_element_info_t *obj);
unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj);
void snd_ctl_element_info_set_item(snd_ctl_element_info_t *obj, unsigned int val);
void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val);
const char *snd_ctl_element_info_get_item_name(const snd_ctl_element_info_t *obj);
const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj);
void snd_ctl_element_info_get_id(const snd_ctl_element_info_t *obj, snd_ctl_element_id_t *ptr);
void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr);
unsigned int snd_ctl_element_info_get_numid(const snd_ctl_element_info_t *obj);
unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj);
snd_ctl_element_iface_t snd_ctl_element_info_get_interface(const snd_ctl_element_info_t *obj);
snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj);
unsigned int snd_ctl_element_info_get_device(const snd_ctl_element_info_t *obj);
unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj);
unsigned int snd_ctl_element_info_get_subdevice(const snd_ctl_element_info_t *obj);
unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj);
const char *snd_ctl_element_info_get_name(const snd_ctl_element_info_t *obj);
const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj);
unsigned int snd_ctl_element_info_get_index(const snd_ctl_element_info_t *obj);
unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj);
void snd_ctl_element_info_set_id(snd_ctl_element_info_t *obj, const snd_ctl_element_id_t *ptr);
void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr);
void snd_ctl_element_info_set_numid(snd_ctl_element_info_t *obj, unsigned int val);
void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val);
void snd_ctl_element_info_set_interface(snd_ctl_element_info_t *obj, snd_ctl_element_iface_t val);
void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val);
void snd_ctl_element_info_set_device(snd_ctl_element_info_t *obj, unsigned int val);
void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val);
void snd_ctl_element_info_set_subdevice(snd_ctl_element_info_t *obj, unsigned int val);
void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val);
void snd_ctl_element_info_set_name(snd_ctl_element_info_t *obj, const char *val);
void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val);
void snd_ctl_element_info_set_index(snd_ctl_element_info_t *obj, unsigned int val);
void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val);
size_t snd_ctl_element_sizeof();
#define snd_ctl_element_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_element_t *) alloca(snd_ctl_element_sizeof()); memset(*ptr, 0, snd_ctl_element_sizeof()); 0; })
int snd_ctl_element_malloc(snd_ctl_element_t **ptr);
void snd_ctl_element_free(snd_ctl_element_t *obj);
void snd_ctl_element_copy(snd_ctl_element_t *dst, const snd_ctl_element_t *src);
size_t snd_ctl_elem_sizeof();
#define snd_ctl_elem_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_elem_t *) alloca(snd_ctl_elem_sizeof()); memset(*ptr, 0, snd_ctl_elem_sizeof()); 0; })
int snd_ctl_elem_malloc(snd_ctl_elem_t **ptr);
void snd_ctl_elem_free(snd_ctl_elem_t *obj);
void snd_ctl_elem_copy(snd_ctl_elem_t *dst, const snd_ctl_elem_t *src);
void snd_ctl_element_get_id(const snd_ctl_element_t *obj, snd_ctl_element_id_t *ptr);
void snd_ctl_elem_get_id(const snd_ctl_elem_t *obj, snd_ctl_elem_id_t *ptr);
unsigned int snd_ctl_element_get_numid(const snd_ctl_element_t *obj);
unsigned int snd_ctl_elem_get_numid(const snd_ctl_elem_t *obj);
snd_ctl_element_iface_t snd_ctl_element_get_interface(const snd_ctl_element_t *obj);
snd_ctl_elem_iface_t snd_ctl_elem_get_interface(const snd_ctl_elem_t *obj);
unsigned int snd_ctl_element_get_device(const snd_ctl_element_t *obj);
unsigned int snd_ctl_elem_get_device(const snd_ctl_elem_t *obj);
unsigned int snd_ctl_element_get_subdevice(const snd_ctl_element_t *obj);
unsigned int snd_ctl_elem_get_subdevice(const snd_ctl_elem_t *obj);
const char *snd_ctl_element_get_name(const snd_ctl_element_t *obj);
const char *snd_ctl_elem_get_name(const snd_ctl_elem_t *obj);
unsigned int snd_ctl_element_get_index(const snd_ctl_element_t *obj);
unsigned int snd_ctl_elem_get_index(const snd_ctl_elem_t *obj);
void snd_ctl_element_set_id(snd_ctl_element_t *obj, const snd_ctl_element_id_t *ptr);
void snd_ctl_elem_set_id(snd_ctl_elem_t *obj, const snd_ctl_elem_id_t *ptr);
void snd_ctl_element_set_numid(snd_ctl_element_t *obj, unsigned int val);
void snd_ctl_elem_set_numid(snd_ctl_elem_t *obj, unsigned int val);
void snd_ctl_element_set_interface(snd_ctl_element_t *obj, snd_ctl_element_iface_t val);
void snd_ctl_elem_set_interface(snd_ctl_elem_t *obj, snd_ctl_elem_iface_t val);
void snd_ctl_element_set_device(snd_ctl_element_t *obj, unsigned int val);
void snd_ctl_elem_set_device(snd_ctl_elem_t *obj, unsigned int val);
void snd_ctl_element_set_subdevice(snd_ctl_element_t *obj, unsigned int val);
void snd_ctl_elem_set_subdevice(snd_ctl_elem_t *obj, unsigned int val);
void snd_ctl_element_set_name(snd_ctl_element_t *obj, const char *val);
void snd_ctl_elem_set_name(snd_ctl_elem_t *obj, const char *val);
void snd_ctl_element_set_index(snd_ctl_element_t *obj, unsigned int val);
void snd_ctl_elem_set_index(snd_ctl_elem_t *obj, unsigned int val);
long snd_ctl_element_get_boolean(const snd_ctl_element_t *obj, unsigned int idx);
long snd_ctl_elem_get_boolean(const snd_ctl_elem_t *obj, unsigned int idx);
long snd_ctl_element_get_integer(const snd_ctl_element_t *obj, unsigned int idx);
long snd_ctl_elem_get_integer(const snd_ctl_elem_t *obj, unsigned int idx);
unsigned int snd_ctl_element_get_enumerated(const snd_ctl_element_t *obj, unsigned int idx);
unsigned int snd_ctl_elem_get_enumerated(const snd_ctl_elem_t *obj, unsigned int idx);
unsigned char snd_ctl_element_get_byte(const snd_ctl_element_t *obj, unsigned int idx);
unsigned char snd_ctl_elem_get_byte(const snd_ctl_elem_t *obj, unsigned int idx);
void snd_ctl_element_set_boolean(snd_ctl_element_t *obj, unsigned int idx, long val);
void snd_ctl_elem_set_boolean(snd_ctl_elem_t *obj, unsigned int idx, long val);
void snd_ctl_element_set_integer(snd_ctl_element_t *obj, unsigned int idx, long val);
void snd_ctl_elem_set_integer(snd_ctl_elem_t *obj, unsigned int idx, long val);
void snd_ctl_element_set_enumerated(snd_ctl_element_t *obj, unsigned int idx, unsigned int val);
void snd_ctl_elem_set_enumerated(snd_ctl_elem_t *obj, unsigned int idx, unsigned int val);
void snd_ctl_element_set_byte(snd_ctl_element_t *obj, unsigned int idx, unsigned char val);
void snd_ctl_elem_set_byte(snd_ctl_elem_t *obj, unsigned int idx, unsigned char val);
const void * snd_ctl_element_get_bytes(const snd_ctl_element_t *obj);
const void * snd_ctl_elem_get_bytes(const snd_ctl_elem_t *obj);
void snd_ctl_element_get_iec958(const snd_ctl_element_t *obj, snd_aes_iec958_t *ptr);
void snd_ctl_elem_get_iec958(const snd_ctl_elem_t *obj, snd_aes_iec958_t *ptr);
void snd_ctl_element_set_iec958(snd_ctl_element_t *obj, const snd_aes_iec958_t *ptr);
void snd_ctl_elem_set_iec958(snd_ctl_elem_t *obj, const snd_aes_iec958_t *ptr);
size_t snd_hctl_element_list_sizeof();
#define snd_hctl_element_list_alloca(ptr) ({ assert(ptr); *ptr = (snd_hctl_element_list_t *) alloca(snd_hctl_element_list_sizeof()); memset(*ptr, 0, snd_hctl_element_list_sizeof()); 0; })
int snd_hctl_element_list_malloc(snd_hctl_element_list_t **ptr);
void snd_hctl_element_list_free(snd_hctl_element_list_t *obj);
void snd_hctl_element_list_copy(snd_hctl_element_list_t *dst, const snd_hctl_element_list_t *src);
size_t snd_hctl_elem_sizeof();
#define snd_hctl_elem_alloca(ptr) ({ assert(ptr); *ptr = (snd_hctl_elem_t *) alloca(snd_hctl_elem_sizeof()); memset(*ptr, 0, snd_hctl_elem_sizeof()); 0; })
int snd_hctl_elem_malloc(snd_hctl_elem_t **ptr);
void snd_hctl_elem_free(snd_hctl_elem_t *obj);
void snd_hctl_elem_copy(snd_hctl_elem_t *dst, const snd_hctl_elem_t *src);
void snd_hctl_element_list_set_offset(snd_hctl_element_list_t *obj, unsigned int val);
void snd_hctl_elem_get_id(const snd_hctl_elem_t *obj, snd_ctl_elem_id_t *ptr);
unsigned int snd_hctl_element_list_get_used(const snd_hctl_element_list_t *obj);
unsigned int snd_hctl_elem_get_numid(const snd_hctl_elem_t *obj);
unsigned int snd_hctl_element_list_get_count(const snd_hctl_element_list_t *obj);
snd_ctl_elem_iface_t snd_hctl_elem_get_interface(const snd_hctl_elem_t *obj);
void snd_hctl_element_list_get_id(const snd_hctl_element_list_t *obj, unsigned int idx, snd_ctl_element_id_t *ptr);
unsigned int snd_hctl_elem_get_device(const snd_hctl_elem_t *obj);
unsigned int snd_hctl_element_list_get_numid(const snd_hctl_element_list_t *obj, unsigned int idx);
unsigned int snd_hctl_elem_get_subdevice(const snd_hctl_elem_t *obj);
snd_ctl_element_iface_t snd_hctl_element_list_get_interface(const snd_hctl_element_list_t *obj, unsigned int idx);
const char *snd_hctl_elem_get_name(const snd_hctl_elem_t *obj);
unsigned int snd_hctl_element_list_get_device(const snd_hctl_element_list_t *obj, unsigned int idx);
unsigned int snd_hctl_elem_get_index(const snd_hctl_elem_t *obj);
unsigned int snd_hctl_element_list_get_subdevice(const snd_hctl_element_list_t *obj, unsigned int idx);
void snd_hctl_elem_set_callback(snd_hctl_elem_t *obj, snd_hctl_elem_callback_t val);
const char *snd_hctl_element_list_get_name(const snd_hctl_element_list_t *obj, unsigned int idx);
void * snd_hctl_elem_get_callback_private(const snd_hctl_elem_t *obj);
unsigned int snd_hctl_element_list_get_index(const snd_hctl_element_list_t *obj, unsigned int idx);
size_t snd_hctl_element_sizeof();
#define snd_hctl_element_alloca(ptr) ({ assert(ptr); *ptr = (snd_hctl_element_t *) alloca(snd_hctl_element_sizeof()); memset(*ptr, 0, snd_hctl_element_sizeof()); 0; })
int snd_hctl_element_malloc(snd_hctl_element_t **ptr);
void snd_hctl_element_free(snd_hctl_element_t *obj);
void snd_hctl_element_copy(snd_hctl_element_t *dst, const snd_hctl_element_t *src);
void snd_hctl_element_get_id(const snd_hctl_element_t *obj, snd_ctl_element_id_t *ptr);
unsigned int snd_hctl_element_get_numid(const snd_hctl_element_t *obj);
snd_ctl_element_iface_t snd_hctl_element_get_interface(const snd_hctl_element_t *obj);
unsigned int snd_hctl_element_get_device(const snd_hctl_element_t *obj);
unsigned int snd_hctl_element_get_subdevice(const snd_hctl_element_t *obj);
const char *snd_hctl_element_get_name(const snd_hctl_element_t *obj);
unsigned int snd_hctl_element_get_index(const snd_hctl_element_t *obj);
void snd_hctl_element_set_callback_change(snd_hctl_element_t *obj, snd_hctl_element_callback_t val);
void snd_hctl_element_set_callback_value(snd_hctl_element_t *obj, snd_hctl_element_callback_t val);
void snd_hctl_element_set_callback_remove(snd_hctl_element_t *obj, snd_hctl_element_callback_t val);
void * snd_hctl_element_get_private_data(const snd_hctl_element_t *obj);
void snd_hctl_element_set_private_data(snd_hctl_element_t *obj, void * val);
void snd_hctl_element_set_private_free(snd_hctl_element_t *obj, snd_hctl_element_private_free_t val);
void snd_hctl_elem_set_callback_private(snd_hctl_elem_t *obj, void * val);
#ifdef __cplusplus

View file

@ -29,10 +29,10 @@
#define _snd_pcm_status sndrv_pcm_status
#define _snd_ctl_card_info sndrv_ctl_card_info
#define _snd_ctl_element_id sndrv_ctl_element_id
#define _snd_ctl_element_list sndrv_ctl_element_list
#define _snd_ctl_element_info sndrv_ctl_element_info
#define _snd_ctl_element sndrv_ctl_element
#define _snd_ctl_elem_id sndrv_ctl_elem_id
#define _snd_ctl_elem_list sndrv_ctl_elem_list
#define _snd_ctl_elem_info sndrv_ctl_elem_info
#define _snd_ctl_elem sndrv_ctl_elem
#define _snd_ctl_event sndrv_ctl_event
#define _snd_rawmidi_info sndrv_rawmidi_info

View file

@ -6,15 +6,42 @@
****************************************************************************/
typedef struct _snd_mixer snd_mixer_t;
typedef struct _snd_mixer_info snd_mixer_info_t;
typedef struct _snd_mixer_elem snd_mixer_elem_t;
typedef int (*snd_mixer_callback_t)(snd_mixer_t *ctl,
snd_ctl_event_type_t event,
snd_mixer_elem_t *elem);
typedef int (*snd_mixer_elem_callback_t)(snd_mixer_elem_t *elem,
snd_ctl_event_type_t event);
enum _snd_mixer_elem_type {
SND_MIXER_ELEM_SIMPLE,
SND_MIXER_ELEM_LAST = SND_MIXER_ELEM_SIMPLE,
};
#ifdef SND_ENUM_TYPECHECK
typedef struct __snd_mixer_elem_type *snd_mixer_elem_type_t;
#else
typedef enum _snd_mixer_elem_type snd_mixer_elem_type_t;
#endif
#define SND_MIXER_ELEM_SIMPLE ((snd_mixer_elem_type_t) SND_MIXER_ELEM_SIMPLE)
#define SND_MIXER_ELEM_LAST ((snd_mixer_elem_type_t) SND_MIXER_ELEM_LAST)
#ifdef __cplusplus
extern "C" {
#endif
int snd_mixer_open(snd_mixer_t **handle, char *name);
int snd_mixer_close(snd_mixer_t *handle);
int snd_mixer_card(snd_mixer_t *handle);
int snd_mixer_poll_descriptor(snd_mixer_t *handle);
int snd_mixer_open(snd_mixer_t **mixer, char *name);
int snd_mixer_close(snd_mixer_t *mixer);
int snd_mixer_poll_descriptor(snd_mixer_t *mixer);
int snd_mixer_info(snd_mixer_t *mixer, snd_mixer_info_t *info);
snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer);
snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer);
snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem);
snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *helem);
int snd_mixer_events(snd_mixer_t *mixer);
#ifdef __cplusplus
}
@ -36,6 +63,11 @@ enum _snd_mixer_channel_id {
SND_MIXER_CHN_MONO = SND_MIXER_CHN_FRONT_LEFT
};
/* Simple mixer */
typedef struct _snd_mixer_selem snd_mixer_selem_t;
typedef struct _snd_mixer_selem_id snd_mixer_selem_id_t;
#ifdef SND_ENUM_TYPECHECK
typedef struct __snd_mixer_channel_id *snd_mixer_channel_id_t;
#else
@ -52,79 +84,32 @@ typedef enum _snd_mixer_channel_id snd_mixer_channel_id_t;
#define SND_MIXER_CHN_LAST ((snd_mixer_channel_id_t) SND_MIXER_CHN_LAST)
#define SND_MIXER_CHN_MONO ((snd_mixer_channel_id_t) SND_MIXER_CHN_MONO)
#define SND_MIXER_CHN_MASK_MONO (1<<snd_enum_to_int(SND_MIXER_CHN_MONO))
#define SND_MIXER_CHN_MASK_FRONT_LEFT (1<<snd_enum_to_int(SND_MIXER_CHN_FRONT_LEFT))
#define SND_MIXER_CHN_MASK_FRONT_RIGHT (1<<snd_enum_to_int(SND_MIXER_CHN_FRONT_RIGHT))
#define SND_MIXER_CHN_MASK_FRONT_CENTER (1<<snd_enum_to_int(SND_MIXER_CHN_FRONT_CENTER))
#define SND_MIXER_CHN_MASK_REAR_LEFT (1<<snd_enum_to_int(SND_MIXER_CHN_REAR_LEFT))
#define SND_MIXER_CHN_MASK_REAR_RIGHT (1<<snd_enum_to_int(SND_MIXER_CHN_REAR_RIGHT))
#define SND_MIXER_CHN_MASK_WOOFER (1<<snd_enum_to_int(SND_MIXER_CHN_WOOFER))
#define SND_MIXER_CHN_MASK_STEREO (SND_MIXER_CHN_MASK_FRONT_LEFT|SND_MIXER_CHN_MASK_FRONT_RIGHT)
#define SND_MIXER_SCTCAP_VOLUME (1<<0)
#define SND_MIXER_SCTCAP_JOINTLY_VOLUME (1<<1)
#define SND_MIXER_SCTCAP_MUTE (1<<2)
#define SND_MIXER_SCTCAP_JOINTLY_MUTE (1<<3)
#define SND_MIXER_SCTCAP_CAPTURE (1<<4)
#define SND_MIXER_SCTCAP_JOINTLY_CAPTURE (1<<5)
#define SND_MIXER_SCTCAP_EXCL_CAPTURE (1<<6)
typedef struct _snd_mixer_sid {
unsigned char name[60];
unsigned int index;
} snd_mixer_sid_t;
typedef struct _snd_mixer_simple_element_list {
unsigned int controls_offset; /* W: first control ID to get */
unsigned int controls_request; /* W: count of control IDs to get */
unsigned int controls_count; /* R: count of available (set) IDs */
unsigned int controls; /* R: count of all available controls */
snd_mixer_sid_t *pids; /* W: IDs */
char reserved[50];
} snd_mixer_simple_element_list_t;
typedef struct _snd_mixer_simple_element {
snd_mixer_sid_t sid; /* WR: simple control identification */
unsigned int caps; /* RO: capabilities */
unsigned int channels; /* RO: bitmap of active channels */
unsigned int mute; /* RW: bitmap of muted channels */
unsigned int capture; /* RW: bitmap of capture channels */
int capture_group; /* RO: capture group (for exclusive capture) */
long min; /* RO: minimum value */
long max; /* RO: maximum value */
char reserved[32];
union {
struct {
long front_left; /* front left value */
long front_right; /* front right value */
long front_center; /* front center */
long rear_left; /* left rear */
long rear_right; /* right rear */
long woofer; /* woofer */
} names;
long values[32];
} volume; /* RW */
} snd_mixer_simple_element_t;
typedef struct _snd_mixer_simple_callbacks {
void *private_data; /* may be used by an application */
void (*rebuild) (snd_mixer_t *handle, void *private_data);
void (*value) (snd_mixer_t *handle, void *private_data, snd_mixer_sid_t *id);
void (*change) (snd_mixer_t *handle, void *private_data, snd_mixer_sid_t *id);
void (*add) (snd_mixer_t *handle, void *private_data, snd_mixer_sid_t *id);
void (*remove) (snd_mixer_t *handle, void *private_data, snd_mixer_sid_t *id);
void *reserved[58]; /* reserved for future use - must be NULL!!! */
} snd_mixer_simple_callbacks_t;
#ifdef __cplusplus
extern "C" {
#endif
const char *snd_mixer_simple_channel_name(snd_mixer_channel_id_t channel);
int snd_mixer_simple_element_list(snd_mixer_t *handle, snd_mixer_simple_element_list_t *list);
int snd_mixer_simple_element_read(snd_mixer_t *handle, snd_mixer_simple_element_t *simple);
int snd_mixer_simple_element_write(snd_mixer_t *handle, snd_mixer_simple_element_t *simple);
int snd_mixer_simple_read(snd_mixer_t *handle, snd_mixer_simple_callbacks_t *callbacks);
const char *snd_mixer_channel_name(snd_mixer_channel_id_t channel);
int snd_mixer_simple_build(snd_mixer_t *mixer);
snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer,
const snd_mixer_selem_id_t *id);
void snd_mixer_selem_get_id(snd_mixer_elem_t *element,
snd_mixer_selem_id_t *id);
int snd_mixer_selem_read(snd_mixer_elem_t *element,
snd_mixer_selem_t *simple);
int snd_mixer_selem_write(snd_mixer_elem_t *element,
const snd_mixer_selem_t *simple);
int snd_mixer_selem_is_mono(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_channel(const snd_mixer_selem_t *obj, snd_mixer_channel_id_t channel);
long snd_mixer_selem_get_volume(const snd_mixer_selem_t *obj, snd_mixer_channel_id_t channel);
void snd_mixer_selem_set_volume(snd_mixer_selem_t *obj, snd_mixer_channel_id_t channel, long value);
int snd_mixer_selem_get_mute(const snd_mixer_selem_t *obj, snd_mixer_channel_id_t channel);
int snd_mixer_selem_get_capture(const snd_mixer_selem_t *obj, snd_mixer_channel_id_t channel);
void snd_mixer_selem_set_mute(snd_mixer_selem_t *obj, snd_mixer_channel_id_t channel, int mute);
void snd_mixer_selem_set_capture(snd_mixer_selem_t *obj, snd_mixer_channel_id_t channel, int capture);
void snd_mixer_selem_set_mute_all(snd_mixer_selem_t *obj, int mute);
void snd_mixer_selem_set_capture_all(snd_mixer_selem_t *obj, int capture);
void snd_mixer_selem_set_volume_all(snd_mixer_selem_t *obj, long value);
#ifdef __cplusplus
}

64
include/mixer_m4.h Normal file
View file

@ -0,0 +1,64 @@
#ifdef __cplusplus
extern "C" {
#endif
size_t snd_mixer_selem_id_sizeof();
#define snd_mixer_selem_id_alloca(ptr) ({ assert(ptr); *ptr = (snd_mixer_selem_id_t *) alloca(snd_mixer_selem_id_sizeof()); memset(*ptr, 0, snd_mixer_selem_id_sizeof()); 0; })
int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr);
void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj);
void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src);
const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj);
unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj);
void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val);
void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val);
void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val);
void * snd_mixer_get_callback_private(const snd_mixer_t *obj);
void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val);
unsigned int snd_mixer_get_count(const snd_mixer_t *obj);
void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val);
void * snd_mixer_elem_get_callback_private(const snd_mixer_elem_t *obj);
void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val);
snd_mixer_elem_type_t snd_mixer_elem_get_type(const snd_mixer_elem_t *obj);
size_t snd_mixer_selem_sizeof();
#define snd_mixer_selem_alloca(ptr) ({ assert(ptr); *ptr = (snd_mixer_selem_t *) alloca(snd_mixer_selem_sizeof()); memset(*ptr, 0, snd_mixer_selem_sizeof()); 0; })
int snd_mixer_selem_malloc(snd_mixer_selem_t **ptr);
void snd_mixer_selem_free(snd_mixer_selem_t *obj);
void snd_mixer_selem_copy(snd_mixer_selem_t *dst, const snd_mixer_selem_t *src);
long snd_mixer_selem_get_min(const snd_mixer_selem_t *obj);
long snd_mixer_selem_get_max(const snd_mixer_selem_t *obj);
int snd_mixer_selem_get_capture_group(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_volume(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_joined_volume(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_mute(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_joined_mute(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_capture(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_joined_capture(const snd_mixer_selem_t *obj);
int snd_mixer_selem_has_exclusive_capture(const snd_mixer_selem_t *obj);
#ifdef __cplusplus
}
#endif

View file

@ -808,11 +808,18 @@ void string_print(char *str, int id, snd_output_t *out)
unsigned char *p = str;
if (!id) {
switch (*p) {
case 0:
assert(0);
break;
case '0' ... '9':
case '-':
goto quoted;
}
}
if (!*p) {
snd_output_puts(out, "''");
return;
}
loop:
switch (*p) {
case 0:

View file

@ -1,6 +1,6 @@
EXTRA_LTLIBRARIES = libcontrol.la
libcontrol_la_SOURCES = cards.c controls.c bag.c defaults.c \
libcontrol_la_SOURCES = cards.c hcontrol.c defaults.c \
control.c control_m4.c control_hw.c control_shm.c
all: libcontrol.la

View file

@ -26,6 +26,7 @@
#include <string.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/poll.h>
#include "control_local.h"
snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl)
@ -38,10 +39,28 @@ int snd_ctl_close(snd_ctl_t *ctl)
int res;
assert(ctl);
res = ctl->ops->close(ctl);
snd_hctl_free(ctl);
free(ctl);
return res;
}
int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
{
int err;
assert(ctl);
err = ctl->ops->nonblock(ctl, nonblock);
if (err < 0)
return err;
ctl->nonblock = nonblock;
return 0;
}
int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid)
{
assert(ctl);
return ctl->ops->async(ctl, sig, pid);
}
int snd_ctl_poll_descriptor(snd_ctl_t *ctl)
{
assert(ctl);
@ -54,28 +73,29 @@ int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
return ctl->ops->hw_info(ctl, info);
}
int snd_ctl_clist(snd_ctl_t *ctl, snd_ctl_element_list_t *list)
int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list)
{
assert(ctl && list);
return ctl->ops->clist(ctl, list);
assert(list->space == 0 || list->pids);
return ctl->ops->element_list(ctl, list);
}
int snd_ctl_element_info(snd_ctl_t *ctl, snd_ctl_element_info_t *info)
int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info)
{
assert(ctl && info && (info->id.name[0] || info->id.numid));
return ctl->ops->cinfo(ctl, info);
return ctl->ops->element_info(ctl, info);
}
int snd_ctl_element_read(snd_ctl_t *ctl, snd_ctl_element_t *control)
int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_t *control)
{
assert(ctl && control && (control->id.name[0] || control->id.numid));
return ctl->ops->cread(ctl, control);
return ctl->ops->element_read(ctl, control);
}
int snd_ctl_element_write(snd_ctl_t *ctl, snd_ctl_element_t *control)
int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_t *control)
{
assert(ctl && control && (control->id.name[0] || control->id.numid));
return ctl->ops->cwrite(ctl, control);
return ctl->ops->element_write(ctl, control);
}
int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int *device)
@ -126,49 +146,22 @@ int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
return ctl->ops->rawmidi_prefer_subdevice(ctl, subdev);
}
int snd_ctl_read1(snd_ctl_t *ctl, snd_ctl_event_t *event)
int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
{
assert(ctl && event);
return ctl->ops->read(ctl, event);
}
int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_callbacks_t * callbacks)
int snd_ctl_wait(snd_ctl_t *ctl, int timeout)
{
int result, count;
snd_ctl_event_t r;
assert(ctl);
count = 0;
while ((result = snd_ctl_read1(ctl, &r)) > 0) {
if (result != sizeof(r))
return -EIO;
if (!callbacks)
continue;
switch (r.type) {
case SND_CTL_EVENT_REBUILD:
if (callbacks->rebuild)
callbacks->rebuild(ctl, callbacks->private_data);
break;
case SND_CTL_EVENT_VALUE:
if (callbacks->value)
callbacks->value(ctl, callbacks->private_data, &r.data.id);
break;
case SND_CTL_EVENT_CHANGE:
if (callbacks->change)
callbacks->change(ctl, callbacks->private_data, &r.data.id);
break;
case SND_CTL_EVENT_ADD:
if (callbacks->add)
callbacks->add(ctl, callbacks->private_data, &r.data.id);
break;
case SND_CTL_EVENT_REMOVE:
if (callbacks->remove)
callbacks->remove(ctl, callbacks->private_data, &r.data.id);
break;
}
count++;
}
return result >= 0 ? count : -errno;
struct pollfd pfd;
int err;
pfd.fd = snd_ctl_poll_descriptor(ctl);
pfd.events = POLLIN;
err = poll(&pfd, 1, timeout);
if (err < 0)
return -errno;
return 0;
}
int snd_ctl_open(snd_ctl_t **ctlp, char *name)
@ -239,18 +232,18 @@ int snd_ctl_open(snd_ctl_t **ctlp, char *name)
return open_func(ctlp, name, ctl_conf);
}
void snd_ctl_element_set_bytes(snd_ctl_element_t *obj, void *data, size_t size)
void snd_ctl_elem_set_bytes(snd_ctl_elem_t *obj, void *data, size_t size)
{
assert(obj);
assert(size <= sizeof(obj->value.bytes.data));
memcpy(obj->value.bytes.data, data, size);
}
#define TYPE(v) [SND_CTL_ELEMENT_TYPE_##v] = #v
#define IFACE(v) [SND_CTL_ELEMENT_IFACE_##v] = #v
#define TYPE(v) [SND_CTL_ELEM_TYPE_##v] = #v
#define IFACE(v) [SND_CTL_ELEM_IFACE_##v] = #v
#define EVENT(v) [SND_CTL_EVENT_##v] = #v
const char *snd_ctl_element_type_names[] = {
const char *snd_ctl_elem_type_names[] = {
TYPE(NONE),
TYPE(BOOLEAN),
TYPE(INTEGER),
@ -259,7 +252,7 @@ const char *snd_ctl_element_type_names[] = {
TYPE(IEC958),
};
const char *snd_ctl_element_iface_names[] = {
const char *snd_ctl_elem_iface_names[] = {
IFACE(CARD),
IFACE(HWDEP),
IFACE(MIXER),
@ -277,16 +270,16 @@ const char *snd_ctl_event_type_names[] = {
EVENT(REMOVE),
};
const char *snd_ctl_element_type_name(snd_ctl_element_type_t type)
const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type)
{
assert(type <= SND_CTL_ELEMENT_TYPE_LAST);
return snd_ctl_element_type_names[snd_enum_to_int(type)];
assert(type <= SND_CTL_ELEM_TYPE_LAST);
return snd_ctl_elem_type_names[snd_enum_to_int(type)];
}
const char *snd_ctl_element_iface_name(snd_ctl_element_iface_t iface)
const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface)
{
assert(iface <= SND_CTL_ELEMENT_IFACE_LAST);
return snd_ctl_element_iface_names[snd_enum_to_int(iface)];
assert(iface <= SND_CTL_ELEM_IFACE_LAST);
return snd_ctl_elem_iface_names[snd_enum_to_int(iface)];
}
const char *snd_ctl_event_type_name(snd_ctl_event_type_t type)
@ -295,8 +288,10 @@ const char *snd_ctl_event_type_name(snd_ctl_event_type_t type)
return snd_ctl_event_type_names[snd_enum_to_int(type)];
}
int snd_ctl_element_list_alloc_space(snd_ctl_element_list_t *obj, unsigned int entries)
int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries)
{
if (obj->pids)
free(obj->pids);
obj->pids = calloc(entries, sizeof(*obj->pids));
if (!obj->pids) {
obj->space = 0;
@ -306,7 +301,7 @@ int snd_ctl_element_list_alloc_space(snd_ctl_element_list_t *obj, unsigned int e
return 0;
}
void snd_ctl_element_list_free_space(snd_ctl_element_list_t *obj)
void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj)
{
free(obj->pids);
obj->pids = NULL;

View file

@ -23,11 +23,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "control_local.h"
#ifndef F_SETSIG
#define F_SETSIG 10
#endif
#define SNDRV_FILE_CONTROL "/dev/snd/controlC%i"
#define SNDRV_CTL_VERSION_MAX SNDRV_PROTOCOL_VERSION(2, 0, 0)
@ -45,6 +50,61 @@ static int snd_ctl_hw_close(snd_ctl_t *handle)
return res;
}
static int snd_ctl_hw_nonblock(snd_ctl_t *handle, int nonblock)
{
snd_ctl_hw_t *hw = handle->private;
long flags;
int fd = hw->fd;
if ((flags = fcntl(fd, F_GETFL)) < 0) {
SYSERR("F_GETFL failed");
return -errno;
}
if (nonblock)
flags |= O_NONBLOCK;
else
flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0) {
SYSERR("F_SETFL for O_NONBLOCK failed");
return -errno;
}
return 0;
}
static int snd_ctl_hw_async(snd_ctl_t *ctl, int sig, pid_t pid)
{
long flags;
snd_ctl_hw_t *hw = ctl->private;
int fd = hw->fd;
if ((flags = fcntl(fd, F_GETFL)) < 0) {
SYSERR("F_GETFL failed");
return -errno;
}
if (sig >= 0)
flags |= O_ASYNC;
else
flags &= ~O_ASYNC;
if (fcntl(fd, F_SETFL, flags) < 0) {
SYSERR("F_SETFL for O_ASYNC failed");
return -errno;
}
if (sig < 0)
return 0;
if (sig == 0)
sig = SIGIO;
if (fcntl(fd, F_SETSIG, sig) < 0) {
SYSERR("F_SETSIG failed");
return -errno;
}
if (pid == 0)
pid = getpid();
if (fcntl(fd, F_SETOWN, pid) < 0) {
SYSERR("F_SETOWN failed");
return -errno;
}
return 0;
}
static int snd_ctl_hw_poll_descriptor(snd_ctl_t *handle)
{
snd_ctl_hw_t *hw = handle->private;
@ -59,34 +119,34 @@ static int snd_ctl_hw_hw_info(snd_ctl_t *handle, snd_ctl_card_info_t *info)
return 0;
}
static int snd_ctl_hw_clist(snd_ctl_t *handle, snd_ctl_element_list_t *list)
static int snd_ctl_hw_elem_list(snd_ctl_t *handle, snd_ctl_elem_list_t *list)
{
snd_ctl_hw_t *hw = handle->private;
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEMENT_LIST, list) < 0)
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEM_LIST, list) < 0)
return -errno;
return 0;
}
static int snd_ctl_hw_cinfo(snd_ctl_t *handle, snd_ctl_element_info_t *info)
static int snd_ctl_hw_elem_info(snd_ctl_t *handle, snd_ctl_elem_info_t *info)
{
snd_ctl_hw_t *hw = handle->private;
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEMENT_INFO, info) < 0)
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEM_INFO, info) < 0)
return -errno;
return 0;
}
static int snd_ctl_hw_cread(snd_ctl_t *handle, snd_ctl_element_t *control)
static int snd_ctl_hw_elem_read(snd_ctl_t *handle, snd_ctl_elem_t *control)
{
snd_ctl_hw_t *hw = handle->private;
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEMENT_READ, control) < 0)
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEM_READ, control) < 0)
return -errno;
return 0;
}
static int snd_ctl_hw_cwrite(snd_ctl_t *handle, snd_ctl_element_t *control)
static int snd_ctl_hw_elem_write(snd_ctl_t *handle, snd_ctl_elem_t *control)
{
snd_ctl_hw_t *hw = handle->private;
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEMENT_WRITE, control) < 0)
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, control) < 0)
return -errno;
return 0;
}
@ -158,17 +218,23 @@ static int snd_ctl_hw_rawmidi_prefer_subdevice(snd_ctl_t *handle, int subdev)
static int snd_ctl_hw_read(snd_ctl_t *handle, snd_ctl_event_t *event)
{
snd_ctl_hw_t *hw = handle->private;
return read(hw->fd, event, sizeof(*event));
ssize_t res = read(hw->fd, event, sizeof(*event));
if (res <= 0)
return res;
assert(res == sizeof(*event));
return 1;
}
snd_ctl_ops_t snd_ctl_hw_ops = {
close: snd_ctl_hw_close,
nonblock: snd_ctl_hw_nonblock,
async: snd_ctl_hw_async,
poll_descriptor: snd_ctl_hw_poll_descriptor,
hw_info: snd_ctl_hw_hw_info,
clist: snd_ctl_hw_clist,
cinfo: snd_ctl_hw_cinfo,
cread: snd_ctl_hw_cread,
cwrite: snd_ctl_hw_cwrite,
element_list: snd_ctl_hw_elem_list,
element_info: snd_ctl_hw_elem_info,
element_read: snd_ctl_hw_elem_read,
element_write: snd_ctl_hw_elem_write,
hwdep_next_device: snd_ctl_hw_hwdep_next_device,
hwdep_info: snd_ctl_hw_hwdep_info,
pcm_next_device: snd_ctl_hw_pcm_next_device,

View file

@ -24,12 +24,14 @@
typedef struct _snd_ctl_ops {
int (*close)(snd_ctl_t *handle);
int (*nonblock)(snd_ctl_t *handle, int nonblock);
int (*async)(snd_ctl_t *handle, int sig, pid_t pid);
int (*poll_descriptor)(snd_ctl_t *handle);
int (*hw_info)(snd_ctl_t *handle, snd_ctl_card_info_t *info);
int (*clist)(snd_ctl_t *handle, snd_ctl_element_list_t *list);
int (*cinfo)(snd_ctl_t *handle, snd_ctl_element_info_t *info);
int (*cread)(snd_ctl_t *handle, snd_ctl_element_t *control);
int (*cwrite)(snd_ctl_t *handle, snd_ctl_element_t *control);
int (*element_list)(snd_ctl_t *handle, snd_ctl_elem_list_t *list);
int (*element_info)(snd_ctl_t *handle, snd_ctl_elem_info_t *info);
int (*element_read)(snd_ctl_t *handle, snd_ctl_elem_t *control);
int (*element_write)(snd_ctl_t *handle, snd_ctl_elem_t *control);
int (*hwdep_next_device)(snd_ctl_t *handle, int *device);
int (*hwdep_info)(snd_ctl_t *handle, snd_hwdep_info_t * info);
int (*pcm_next_device)(snd_ctl_t *handle, int *device);
@ -47,51 +49,30 @@ struct _snd_ctl {
snd_ctl_type_t type;
snd_ctl_ops_t *ops;
void *private;
int hcount;
int herr;
int nonblock;
struct list_head hlist; /* list of all controls */
void *hroot; /* root of controls */
void *hroot_new; /* new croot */
snd_ctl_hsort_t hsort;
snd_ctl_hcallback_rebuild_t callback_rebuild;
void *callback_rebuild_private_data;
snd_ctl_hcallback_add_t callback_add;
void *callback_add_private_data;
unsigned int halloc;
unsigned int hcount;
snd_hctl_elem_t **helems;
snd_hctl_compare_t hcompare;
snd_hctl_callback_t callback;
void *callback_private;
};
struct _snd_ctl_callbacks {
void *private_data; /* may be used by an application */
void (*rebuild) (snd_ctl_t *handle, void *private_data);
void (*value) (snd_ctl_t *handle, void *private_data, snd_ctl_element_id_t * id);
void (*change) (snd_ctl_t *handle, void *private_data, snd_ctl_element_id_t * id);
void (*add) (snd_ctl_t *handle, void *private_data, snd_ctl_element_id_t * id);
void (*remove) (snd_ctl_t *handle, void *private_data, snd_ctl_element_id_t * id);
void *reserved[58]; /* reserved for the future use - must be NULL!!! */
};
struct _snd_hctl_element_list {
unsigned int offset; /* W: first control ID to get */
unsigned int space; /* W: count of control IDs to get */
unsigned int used; /* R: count of available (set) controls */
unsigned int count; /* R: count of all available controls */
snd_ctl_element_id_t *pids; /* W: IDs */
};
struct _snd_hctl_element {
snd_ctl_element_id_t id; /* must be always on top */
struct list_head list; /* links for list of all helems */
int change: 1, /* structure change */
value: 1; /* value change */
/* event callbacks */
snd_hctl_element_callback_t callback_change;
snd_hctl_element_callback_t callback_value;
snd_hctl_element_callback_t callback_remove;
/* private data */
void *private_data;
snd_hctl_element_private_free_t private_free;
struct _snd_hctl_elem {
snd_ctl_elem_id_t id; /* must be always on top */
struct list_head list; /* links for list of all helems */
/* event callback */
snd_hctl_elem_callback_t callback;
void *callback_private;
/* links */
snd_ctl_t *handle; /* associated handle */
snd_ctl_t *ctl; /* associated handle */
};
int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card);
int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *socket, const char *sname);
int snd_hctl_free(snd_ctl_t *ctl);
int snd_hctl_compare_default(const snd_hctl_elem_t *c1,
const snd_hctl_elem_t *c2);

View file

@ -21,98 +21,98 @@
#include "control_local.h"
size_t snd_ctl_element_id_sizeof()
size_t snd_ctl_elem_id_sizeof()
{
return sizeof(snd_ctl_element_id_t);
return sizeof(snd_ctl_elem_id_t);
}
int snd_ctl_element_id_malloc(snd_ctl_element_id_t **ptr)
int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_ctl_element_id_t));
*ptr = calloc(1, sizeof(snd_ctl_elem_id_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_ctl_element_id_free(snd_ctl_element_id_t *obj)
void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj)
{
free(obj);
}
void snd_ctl_element_id_copy(snd_ctl_element_id_t *dst, const snd_ctl_element_id_t *src)
void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src)
{
assert(dst && src);
*dst = *src;
}
unsigned int snd_ctl_element_id_get_numid(const snd_ctl_element_id_t *obj)
unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj)
{
assert(obj);
return obj->numid;
}
snd_ctl_element_iface_t snd_ctl_element_id_get_interface(const snd_ctl_element_id_t *obj)
snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj)
{
assert(obj);
return snd_int_to_enum(obj->iface);
}
unsigned int snd_ctl_element_id_get_device(const snd_ctl_element_id_t *obj)
unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj)
{
assert(obj);
return obj->device;
}
unsigned int snd_ctl_element_id_get_subdevice(const snd_ctl_element_id_t *obj)
unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj)
{
assert(obj);
return obj->subdevice;
}
const char *snd_ctl_element_id_get_name(const snd_ctl_element_id_t *obj)
const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj)
{
assert(obj);
return obj->name;
}
unsigned int snd_ctl_element_id_get_index(const snd_ctl_element_id_t *obj)
unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj)
{
assert(obj);
return obj->index;
}
void snd_ctl_element_id_set_numid(snd_ctl_element_id_t *obj, unsigned int val)
void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val)
{
assert(obj);
obj->numid = val;
}
void snd_ctl_element_id_set_interface(snd_ctl_element_id_t *obj, snd_ctl_element_iface_t val)
void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val)
{
assert(obj);
obj->iface = snd_enum_to_int(val);
}
void snd_ctl_element_id_set_device(snd_ctl_element_id_t *obj, unsigned int val)
void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val)
{
assert(obj);
obj->device = val;
}
void snd_ctl_element_id_set_subdevice(snd_ctl_element_id_t *obj, unsigned int val)
void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val)
{
assert(obj);
obj->subdevice = val;
}
void snd_ctl_element_id_set_name(snd_ctl_element_id_t *obj, const char *val)
void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val)
{
assert(obj);
strncpy(obj->name, val, sizeof(obj->name));
}
void snd_ctl_element_id_set_index(snd_ctl_element_id_t *obj, unsigned int val)
void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val)
{
assert(obj);
obj->index = val;
@ -229,14 +229,14 @@ unsigned int snd_ctl_event_get_numid(const snd_ctl_event_t *obj)
return obj->data.id.numid;
}
void snd_ctl_event_get_id(const snd_ctl_event_t *obj, snd_ctl_element_id_t *ptr)
void snd_ctl_event_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr)
{
assert(obj && ptr);
assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
*ptr = obj->data.id;
}
snd_ctl_element_iface_t snd_ctl_event_get_interface(const snd_ctl_event_t *obj)
snd_ctl_elem_iface_t snd_ctl_event_get_interface(const snd_ctl_event_t *obj)
{
assert(obj);
assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
@ -271,667 +271,557 @@ unsigned int snd_ctl_event_get_index(const snd_ctl_event_t *obj)
return obj->data.id.index;
}
size_t snd_ctl_element_list_sizeof()
size_t snd_ctl_elem_list_sizeof()
{
return sizeof(snd_ctl_element_list_t);
return sizeof(snd_ctl_elem_list_t);
}
int snd_ctl_element_list_malloc(snd_ctl_element_list_t **ptr)
int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_ctl_element_list_t));
*ptr = calloc(1, sizeof(snd_ctl_elem_list_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_ctl_element_list_free(snd_ctl_element_list_t *obj)
void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj)
{
free(obj);
}
void snd_ctl_element_list_copy(snd_ctl_element_list_t *dst, const snd_ctl_element_list_t *src)
void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src)
{
assert(dst && src);
*dst = *src;
}
void snd_ctl_element_list_set_offset(snd_ctl_element_list_t *obj, unsigned int val)
void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val)
{
assert(obj);
obj->offset = val;
}
unsigned int snd_ctl_element_list_get_used(const snd_ctl_element_list_t *obj)
unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj)
{
assert(obj);
return obj->used;
}
unsigned int snd_ctl_element_list_get_count(const snd_ctl_element_list_t *obj)
unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj)
{
assert(obj);
return obj->count;
}
void snd_ctl_element_list_get_id(const snd_ctl_element_list_t *obj, unsigned int idx, snd_ctl_element_id_t *ptr)
void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr)
{
assert(obj && ptr);
assert(idx < obj->used);
*ptr = obj->pids[idx];
}
unsigned int snd_ctl_element_list_get_numid(const snd_ctl_element_list_t *obj, unsigned int idx)
unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].numid;
}
snd_ctl_element_iface_t snd_ctl_element_list_get_interface(const snd_ctl_element_list_t *obj, unsigned int idx)
snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return snd_int_to_enum(obj->pids[idx].iface);
}
unsigned int snd_ctl_element_list_get_device(const snd_ctl_element_list_t *obj, unsigned int idx)
unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].device;
}
unsigned int snd_ctl_element_list_get_subdevice(const snd_ctl_element_list_t *obj, unsigned int idx)
unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].subdevice;
}
const char *snd_ctl_element_list_get_name(const snd_ctl_element_list_t *obj, unsigned int idx)
const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].name;
}
unsigned int snd_ctl_element_list_get_index(const snd_ctl_element_list_t *obj, unsigned int idx)
unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].index;
}
size_t snd_ctl_element_info_sizeof()
size_t snd_ctl_elem_info_sizeof()
{
return sizeof(snd_ctl_element_info_t);
return sizeof(snd_ctl_elem_info_t);
}
int snd_ctl_element_info_malloc(snd_ctl_element_info_t **ptr)
int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_ctl_element_info_t));
*ptr = calloc(1, sizeof(snd_ctl_elem_info_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_ctl_element_info_free(snd_ctl_element_info_t *obj)
void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj)
{
free(obj);
}
void snd_ctl_element_info_copy(snd_ctl_element_info_t *dst, const snd_ctl_element_info_t *src)
void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src)
{
assert(dst && src);
*dst = *src;
}
snd_ctl_element_type_t snd_ctl_element_info_get_type(const snd_ctl_element_info_t *obj)
snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return snd_int_to_enum(obj->type);
}
int snd_ctl_element_info_is_readable(const snd_ctl_element_info_t *obj)
int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return !!(obj->access & SNDRV_CTL_ELEMENT_ACCESS_READ);
return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_READ);
}
int snd_ctl_element_info_is_writable(const snd_ctl_element_info_t *obj)
int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return !!(obj->access & SNDRV_CTL_ELEMENT_ACCESS_WRITE);
return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_WRITE);
}
int snd_ctl_element_info_is_volatile(const snd_ctl_element_info_t *obj)
int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return !!(obj->access & SNDRV_CTL_ELEMENT_ACCESS_VOLATILE);
return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE);
}
int snd_ctl_element_info_is_inactive(const snd_ctl_element_info_t *obj)
int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return !!(obj->access & SNDRV_CTL_ELEMENT_ACCESS_INACTIVE);
return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE);
}
int snd_ctl_element_info_is_locked(const snd_ctl_element_info_t *obj)
int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return !!(obj->access & SNDRV_CTL_ELEMENT_ACCESS_LOCK);
return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_LOCK);
}
int snd_ctl_element_info_is_indirect(const snd_ctl_element_info_t *obj)
int snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return !!(obj->access & SNDRV_CTL_ELEMENT_ACCESS_INDIRECT);
return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT);
}
unsigned int snd_ctl_element_info_get_count(const snd_ctl_element_info_t *obj)
unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return obj->count;
}
long snd_ctl_element_info_get_min(const snd_ctl_element_info_t *obj)
long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj)
{
assert(obj);
assert(obj->type == SNDRV_CTL_ELEMENT_TYPE_INTEGER);
assert(obj->type == SNDRV_CTL_ELEM_TYPE_INTEGER);
return obj->value.integer.min;
}
long snd_ctl_element_info_get_max(const snd_ctl_element_info_t *obj)
long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj)
{
assert(obj);
assert(obj->type == SNDRV_CTL_ELEMENT_TYPE_INTEGER);
assert(obj->type == SNDRV_CTL_ELEM_TYPE_INTEGER);
return obj->value.integer.max;
}
long snd_ctl_element_info_get_step(const snd_ctl_element_info_t *obj)
long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj)
{
assert(obj);
assert(obj->type == SNDRV_CTL_ELEMENT_TYPE_INTEGER);
assert(obj->type == SNDRV_CTL_ELEM_TYPE_INTEGER);
return obj->value.integer.step;
}
unsigned int snd_ctl_element_info_get_items(const snd_ctl_element_info_t *obj)
unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj)
{
assert(obj);
assert(obj->type == SNDRV_CTL_ELEMENT_TYPE_ENUMERATED);
assert(obj->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED);
return obj->value.enumerated.items;
}
void snd_ctl_element_info_set_item(snd_ctl_element_info_t *obj, unsigned int val)
void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val)
{
assert(obj);
obj->value.enumerated.item = val;
}
const char *snd_ctl_element_info_get_item_name(const snd_ctl_element_info_t *obj)
const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj)
{
assert(obj);
assert(obj->type == SNDRV_CTL_ELEMENT_TYPE_ENUMERATED);
assert(obj->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED);
return obj->value.enumerated.name;
}
void snd_ctl_element_info_get_id(const snd_ctl_element_info_t *obj, snd_ctl_element_id_t *ptr)
void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr)
{
assert(obj && ptr);
*ptr = obj->id;
}
unsigned int snd_ctl_element_info_get_numid(const snd_ctl_element_info_t *obj)
unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return obj->id.numid;
}
snd_ctl_element_iface_t snd_ctl_element_info_get_interface(const snd_ctl_element_info_t *obj)
snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return snd_int_to_enum(obj->id.iface);
}
unsigned int snd_ctl_element_info_get_device(const snd_ctl_element_info_t *obj)
unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return obj->id.device;
}
unsigned int snd_ctl_element_info_get_subdevice(const snd_ctl_element_info_t *obj)
unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return obj->id.subdevice;
}
const char *snd_ctl_element_info_get_name(const snd_ctl_element_info_t *obj)
const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return obj->id.name;
}
unsigned int snd_ctl_element_info_get_index(const snd_ctl_element_info_t *obj)
unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj)
{
assert(obj);
return obj->id.index;
}
void snd_ctl_element_info_set_id(snd_ctl_element_info_t *obj, const snd_ctl_element_id_t *ptr)
void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr)
{
assert(obj && ptr);
obj->id = *ptr;
}
void snd_ctl_element_info_set_numid(snd_ctl_element_info_t *obj, unsigned int val)
void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val)
{
assert(obj);
obj->id.numid = val;
}
void snd_ctl_element_info_set_interface(snd_ctl_element_info_t *obj, snd_ctl_element_iface_t val)
void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val)
{
assert(obj);
obj->id.iface = snd_enum_to_int(val);
}
void snd_ctl_element_info_set_device(snd_ctl_element_info_t *obj, unsigned int val)
void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val)
{
assert(obj);
obj->id.device = val;
}
void snd_ctl_element_info_set_subdevice(snd_ctl_element_info_t *obj, unsigned int val)
void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val)
{
assert(obj);
obj->id.subdevice = val;
}
void snd_ctl_element_info_set_name(snd_ctl_element_info_t *obj, const char *val)
void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val)
{
assert(obj);
strncpy(obj->id.name, val, sizeof(obj->id.name));
}
void snd_ctl_element_info_set_index(snd_ctl_element_info_t *obj, unsigned int val)
void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val)
{
assert(obj);
obj->id.index = val;
}
size_t snd_ctl_element_sizeof()
size_t snd_ctl_elem_sizeof()
{
return sizeof(snd_ctl_element_t);
return sizeof(snd_ctl_elem_t);
}
int snd_ctl_element_malloc(snd_ctl_element_t **ptr)
int snd_ctl_elem_malloc(snd_ctl_elem_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_ctl_element_t));
*ptr = calloc(1, sizeof(snd_ctl_elem_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_ctl_element_free(snd_ctl_element_t *obj)
void snd_ctl_elem_free(snd_ctl_elem_t *obj)
{
free(obj);
}
void snd_ctl_element_copy(snd_ctl_element_t *dst, const snd_ctl_element_t *src)
void snd_ctl_elem_copy(snd_ctl_elem_t *dst, const snd_ctl_elem_t *src)
{
assert(dst && src);
*dst = *src;
}
void snd_ctl_element_get_id(const snd_ctl_element_t *obj, snd_ctl_element_id_t *ptr)
void snd_ctl_elem_get_id(const snd_ctl_elem_t *obj, snd_ctl_elem_id_t *ptr)
{
assert(obj && ptr);
*ptr = obj->id;
}
unsigned int snd_ctl_element_get_numid(const snd_ctl_element_t *obj)
unsigned int snd_ctl_elem_get_numid(const snd_ctl_elem_t *obj)
{
assert(obj);
return obj->id.numid;
}
snd_ctl_element_iface_t snd_ctl_element_get_interface(const snd_ctl_element_t *obj)
snd_ctl_elem_iface_t snd_ctl_elem_get_interface(const snd_ctl_elem_t *obj)
{
assert(obj);
return snd_int_to_enum(obj->id.iface);
}
unsigned int snd_ctl_element_get_device(const snd_ctl_element_t *obj)
unsigned int snd_ctl_elem_get_device(const snd_ctl_elem_t *obj)
{
assert(obj);
return obj->id.device;
}
unsigned int snd_ctl_element_get_subdevice(const snd_ctl_element_t *obj)
unsigned int snd_ctl_elem_get_subdevice(const snd_ctl_elem_t *obj)
{
assert(obj);
return obj->id.subdevice;
}
const char *snd_ctl_element_get_name(const snd_ctl_element_t *obj)
const char *snd_ctl_elem_get_name(const snd_ctl_elem_t *obj)
{
assert(obj);
return obj->id.name;
}
unsigned int snd_ctl_element_get_index(const snd_ctl_element_t *obj)
unsigned int snd_ctl_elem_get_index(const snd_ctl_elem_t *obj)
{
assert(obj);
return obj->id.index;
}
void snd_ctl_element_set_id(snd_ctl_element_t *obj, const snd_ctl_element_id_t *ptr)
void snd_ctl_elem_set_id(snd_ctl_elem_t *obj, const snd_ctl_elem_id_t *ptr)
{
assert(obj && ptr);
obj->id = *ptr;
}
void snd_ctl_element_set_numid(snd_ctl_element_t *obj, unsigned int val)
void snd_ctl_elem_set_numid(snd_ctl_elem_t *obj, unsigned int val)
{
assert(obj);
obj->id.numid = val;
}
void snd_ctl_element_set_interface(snd_ctl_element_t *obj, snd_ctl_element_iface_t val)
void snd_ctl_elem_set_interface(snd_ctl_elem_t *obj, snd_ctl_elem_iface_t val)
{
assert(obj);
obj->id.iface = snd_enum_to_int(val);
}
void snd_ctl_element_set_device(snd_ctl_element_t *obj, unsigned int val)
void snd_ctl_elem_set_device(snd_ctl_elem_t *obj, unsigned int val)
{
assert(obj);
obj->id.device = val;
}
void snd_ctl_element_set_subdevice(snd_ctl_element_t *obj, unsigned int val)
void snd_ctl_elem_set_subdevice(snd_ctl_elem_t *obj, unsigned int val)
{
assert(obj);
obj->id.subdevice = val;
}
void snd_ctl_element_set_name(snd_ctl_element_t *obj, const char *val)
void snd_ctl_elem_set_name(snd_ctl_elem_t *obj, const char *val)
{
assert(obj);
strncpy(obj->id.name, val, sizeof(obj->id.name));
}
void snd_ctl_element_set_index(snd_ctl_element_t *obj, unsigned int val)
void snd_ctl_elem_set_index(snd_ctl_elem_t *obj, unsigned int val)
{
assert(obj);
obj->id.index = val;
}
long snd_ctl_element_get_boolean(const snd_ctl_element_t *obj, unsigned int idx)
long snd_ctl_elem_get_boolean(const snd_ctl_elem_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < sizeof(obj->value.integer.value) / sizeof(obj->value.integer.value[0]));
return obj->value.integer.value[idx];
}
long snd_ctl_element_get_integer(const snd_ctl_element_t *obj, unsigned int idx)
long snd_ctl_elem_get_integer(const snd_ctl_elem_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < sizeof(obj->value.integer.value) / sizeof(obj->value.integer.value[0]));
return obj->value.integer.value[idx];
}
unsigned int snd_ctl_element_get_enumerated(const snd_ctl_element_t *obj, unsigned int idx)
unsigned int snd_ctl_elem_get_enumerated(const snd_ctl_elem_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < sizeof(obj->value.enumerated.item) / sizeof(obj->value.enumerated.item[0]));
return obj->value.enumerated.item[idx];
}
unsigned char snd_ctl_element_get_byte(const snd_ctl_element_t *obj, unsigned int idx)
unsigned char snd_ctl_elem_get_byte(const snd_ctl_elem_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < sizeof(obj->value.bytes.data));
return obj->value.bytes.data[idx];
}
void snd_ctl_element_set_boolean(snd_ctl_element_t *obj, unsigned int idx, long val)
void snd_ctl_elem_set_boolean(snd_ctl_elem_t *obj, unsigned int idx, long val)
{
assert(obj);
obj->value.integer.value[idx] = val;
}
void snd_ctl_element_set_integer(snd_ctl_element_t *obj, unsigned int idx, long val)
void snd_ctl_elem_set_integer(snd_ctl_elem_t *obj, unsigned int idx, long val)
{
assert(obj);
obj->value.integer.value[idx] = val;
}
void snd_ctl_element_set_enumerated(snd_ctl_element_t *obj, unsigned int idx, unsigned int val)
void snd_ctl_elem_set_enumerated(snd_ctl_elem_t *obj, unsigned int idx, unsigned int val)
{
assert(obj);
obj->value.enumerated.item[idx] = val;
}
void snd_ctl_element_set_byte(snd_ctl_element_t *obj, unsigned int idx, unsigned char val)
void snd_ctl_elem_set_byte(snd_ctl_elem_t *obj, unsigned int idx, unsigned char val)
{
assert(obj);
obj->value.bytes.data[idx] = val;
}
const void * snd_ctl_element_get_bytes(const snd_ctl_element_t *obj)
const void * snd_ctl_elem_get_bytes(const snd_ctl_elem_t *obj)
{
assert(obj);
return obj->value.bytes.data;
}
void snd_ctl_element_get_iec958(const snd_ctl_element_t *obj, snd_aes_iec958_t *ptr)
void snd_ctl_elem_get_iec958(const snd_ctl_elem_t *obj, snd_aes_iec958_t *ptr)
{
assert(obj && ptr);
*ptr = obj->value.iec958;
}
void snd_ctl_element_set_iec958(snd_ctl_element_t *obj, const snd_aes_iec958_t *ptr)
void snd_ctl_elem_set_iec958(snd_ctl_elem_t *obj, const snd_aes_iec958_t *ptr)
{
assert(obj && ptr);
obj->value.iec958 = *ptr;
}
size_t snd_hctl_element_list_sizeof()
size_t snd_hctl_elem_sizeof()
{
return sizeof(snd_hctl_element_list_t);
return sizeof(snd_hctl_elem_t);
}
int snd_hctl_element_list_malloc(snd_hctl_element_list_t **ptr)
int snd_hctl_elem_malloc(snd_hctl_elem_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_hctl_element_list_t));
*ptr = calloc(1, sizeof(snd_hctl_elem_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_hctl_element_list_free(snd_hctl_element_list_t *obj)
void snd_hctl_elem_free(snd_hctl_elem_t *obj)
{
free(obj);
}
void snd_hctl_element_list_copy(snd_hctl_element_list_t *dst, const snd_hctl_element_list_t *src)
void snd_hctl_elem_copy(snd_hctl_elem_t *dst, const snd_hctl_elem_t *src)
{
assert(dst && src);
*dst = *src;
}
void snd_hctl_element_list_set_offset(snd_hctl_element_list_t *obj, unsigned int val)
{
assert(obj);
obj->offset = val;
}
unsigned int snd_hctl_element_list_get_used(const snd_hctl_element_list_t *obj)
{
assert(obj);
return obj->used;
}
unsigned int snd_hctl_element_list_get_count(const snd_hctl_element_list_t *obj)
{
assert(obj);
return obj->count;
}
void snd_hctl_element_list_get_id(const snd_hctl_element_list_t *obj, unsigned int idx, snd_ctl_element_id_t *ptr)
{
assert(obj && ptr);
assert(idx < obj->used);
*ptr = obj->pids[idx];
}
unsigned int snd_hctl_element_list_get_numid(const snd_hctl_element_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].numid;
}
snd_ctl_element_iface_t snd_hctl_element_list_get_interface(const snd_hctl_element_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return snd_int_to_enum(obj->pids[idx].iface);
}
unsigned int snd_hctl_element_list_get_device(const snd_hctl_element_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].device;
}
unsigned int snd_hctl_element_list_get_subdevice(const snd_hctl_element_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].subdevice;
}
const char *snd_hctl_element_list_get_name(const snd_hctl_element_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].name;
}
unsigned int snd_hctl_element_list_get_index(const snd_hctl_element_list_t *obj, unsigned int idx)
{
assert(obj);
assert(idx < obj->used);
return obj->pids[idx].index;
}
size_t snd_hctl_element_sizeof()
{
return sizeof(snd_hctl_element_t);
}
int snd_hctl_element_malloc(snd_hctl_element_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_hctl_element_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_hctl_element_free(snd_hctl_element_t *obj)
{
free(obj);
}
void snd_hctl_element_copy(snd_hctl_element_t *dst, const snd_hctl_element_t *src)
{
assert(dst && src);
*dst = *src;
}
void snd_hctl_element_get_id(const snd_hctl_element_t *obj, snd_ctl_element_id_t *ptr)
void snd_hctl_elem_get_id(const snd_hctl_elem_t *obj, snd_ctl_elem_id_t *ptr)
{
assert(obj && ptr);
*ptr = obj->id;
}
unsigned int snd_hctl_element_get_numid(const snd_hctl_element_t *obj)
unsigned int snd_hctl_elem_get_numid(const snd_hctl_elem_t *obj)
{
assert(obj);
return obj->id.numid;
}
snd_ctl_element_iface_t snd_hctl_element_get_interface(const snd_hctl_element_t *obj)
snd_ctl_elem_iface_t snd_hctl_elem_get_interface(const snd_hctl_elem_t *obj)
{
assert(obj);
return snd_int_to_enum(obj->id.iface);
}
unsigned int snd_hctl_element_get_device(const snd_hctl_element_t *obj)
unsigned int snd_hctl_elem_get_device(const snd_hctl_elem_t *obj)
{
assert(obj);
return obj->id.device;
}
unsigned int snd_hctl_element_get_subdevice(const snd_hctl_element_t *obj)
unsigned int snd_hctl_elem_get_subdevice(const snd_hctl_elem_t *obj)
{
assert(obj);
return obj->id.subdevice;
}
const char *snd_hctl_element_get_name(const snd_hctl_element_t *obj)
const char *snd_hctl_elem_get_name(const snd_hctl_elem_t *obj)
{
assert(obj);
return obj->id.name;
}
unsigned int snd_hctl_element_get_index(const snd_hctl_element_t *obj)
unsigned int snd_hctl_elem_get_index(const snd_hctl_elem_t *obj)
{
assert(obj);
return obj->id.index;
}
void snd_hctl_element_set_callback_change(snd_hctl_element_t *obj, snd_hctl_element_callback_t val)
void snd_hctl_elem_set_callback(snd_hctl_elem_t *obj, snd_hctl_elem_callback_t val)
{
assert(obj);
obj->callback_change = val;
obj->callback = val;
}
void snd_hctl_element_set_callback_value(snd_hctl_element_t *obj, snd_hctl_element_callback_t val)
void * snd_hctl_elem_get_callback_private(const snd_hctl_elem_t *obj)
{
assert(obj);
obj->callback_value = val;
return obj->callback_private;
}
void snd_hctl_element_set_callback_remove(snd_hctl_element_t *obj, snd_hctl_element_callback_t val)
void snd_hctl_elem_set_callback_private(snd_hctl_elem_t *obj, void * val)
{
assert(obj);
obj->callback_remove = val;
}
void * snd_hctl_element_get_private_data(const snd_hctl_element_t *obj)
{
assert(obj);
return obj->private_data;
}
void snd_hctl_element_set_private_data(snd_hctl_element_t *obj, void * val)
{
assert(obj);
obj->private_data = val;
}
void snd_hctl_element_set_private_free(snd_hctl_element_t *obj, snd_hctl_element_private_free_t val)
{
assert(obj);
obj->private_free = val;
obj->callback_private = val;
}

View file

@ -94,6 +94,23 @@ static int snd_ctl_shm_close(snd_ctl_t *ctl)
return result;
}
static int snd_ctl_shm_nonblock(snd_ctl_t *handle ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
{
return 0;
}
static int snd_ctl_shm_async(snd_ctl_t *ctl, int sig, pid_t pid)
{
snd_ctl_shm_t *shm = ctl->private;
volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
ctrl->cmd = SND_CTL_IOCTL_ASYNC;
ctrl->u.async.sig = sig;
if (pid == 0)
pid = getpid();
ctrl->u.async.pid = pid;
return snd_ctl_shm_action(ctl);
}
static int snd_ctl_shm_poll_descriptor(snd_ctl_t *ctl)
{
snd_ctl_shm_t *shm = ctl->private;
@ -120,67 +137,67 @@ static int snd_ctl_shm_hw_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
return err;
}
static int snd_ctl_shm_clist(snd_ctl_t *ctl, snd_ctl_element_list_t *list)
static int snd_ctl_shm_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list)
{
snd_ctl_shm_t *shm = ctl->private;
volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
size_t maxsize = CTL_SHM_DATA_MAXLEN;
size_t bytes = list->space * sizeof(*list->pids);
int err;
snd_ctl_element_id_t *pids = list->pids;
snd_ctl_elem_id_t *pids = list->pids;
if (bytes > maxsize)
return -EINVAL;
ctrl->u.clist = *list;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEMENT_LIST;
ctrl->u.element_list = *list;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEM_LIST;
err = snd_ctl_shm_action(ctl);
if (err < 0)
return err;
*list = ctrl->u.clist;
*list = ctrl->u.element_list;
list->pids = pids;
bytes = list->used * sizeof(*list->pids);
memcpy(pids, (void *)ctrl->data, bytes);
return err;
}
static int snd_ctl_shm_cinfo(snd_ctl_t *ctl, snd_ctl_element_info_t *info)
static int snd_ctl_shm_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info)
{
snd_ctl_shm_t *shm = ctl->private;
volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
int err;
ctrl->u.cinfo = *info;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEMENT_INFO;
ctrl->u.element_info = *info;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEM_INFO;
err = snd_ctl_shm_action(ctl);
if (err < 0)
return err;
*info = ctrl->u.cinfo;
*info = ctrl->u.element_info;
return err;
}
static int snd_ctl_shm_cread(snd_ctl_t *ctl, snd_ctl_element_t *control)
static int snd_ctl_shm_elem_read(snd_ctl_t *ctl, snd_ctl_elem_t *control)
{
snd_ctl_shm_t *shm = ctl->private;
volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
int err;
ctrl->u.cread = *control;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEMENT_READ;
ctrl->u.element_read = *control;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEM_READ;
err = snd_ctl_shm_action(ctl);
if (err < 0)
return err;
*control = ctrl->u.cread;
*control = ctrl->u.element_read;
return err;
}
static int snd_ctl_shm_cwrite(snd_ctl_t *ctl, snd_ctl_element_t *control)
static int snd_ctl_shm_elem_write(snd_ctl_t *ctl, snd_ctl_elem_t *control)
{
snd_ctl_shm_t *shm = ctl->private;
volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
int err;
ctrl->u.cwrite = *control;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEMENT_WRITE;
ctrl->u.element_write = *control;
ctrl->cmd = SNDRV_CTL_IOCTL_ELEM_WRITE;
err = snd_ctl_shm_action(ctl);
if (err < 0)
return err;
*control = ctrl->u.cwrite;
*control = ctrl->u.element_write;
return err;
}
@ -296,9 +313,14 @@ static int snd_ctl_shm_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
static int snd_ctl_shm_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
{
snd_ctl_shm_t *shm = ctl->private;
volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
snd_ctl_shm_t *shm;
volatile snd_ctl_shm_ctrl_t *ctrl;
int err;
err = snd_ctl_wait(ctl, -1);
if (err < 0)
return 0;
shm = ctl->private;
ctrl = shm->ctrl;
ctrl->u.read = *event;
ctrl->cmd = SND_CTL_IOCTL_READ;
err = snd_ctl_shm_action(ctl);
@ -310,12 +332,14 @@ static int snd_ctl_shm_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
snd_ctl_ops_t snd_ctl_shm_ops = {
close: snd_ctl_shm_close,
nonblock: snd_ctl_shm_nonblock,
async: snd_ctl_shm_async,
poll_descriptor: snd_ctl_shm_poll_descriptor,
hw_info: snd_ctl_shm_hw_info,
clist: snd_ctl_shm_clist,
cinfo: snd_ctl_shm_cinfo,
cread: snd_ctl_shm_cread,
cwrite: snd_ctl_shm_cwrite,
element_list: snd_ctl_shm_elem_list,
element_info: snd_ctl_shm_elem_info,
element_read: snd_ctl_shm_elem_read,
element_write: snd_ctl_shm_elem_write,
hwdep_next_device: snd_ctl_shm_hwdep_next_device,
hwdep_info: snd_ctl_shm_hwdep_info,
pcm_next_device: snd_ctl_shm_pcm_next_device,

View file

@ -29,12 +29,12 @@
#include <search.h>
#include "control_local.h"
static void snd_ctl_hfree1(snd_hctl_element_t *helem);
static void snd_ctl_hfree1(snd_hctl_elem_t *helem);
int snd_ctl_hbuild(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
{
snd_ctl_element_list_t list;
snd_hctl_element_t *helem, *prev;
snd_ctl_elem_list_t list;
snd_hctl_elem_t *helem, *prev;
int err;
unsigned int idx;
@ -53,7 +53,7 @@ int snd_ctl_hbuild(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
return err;
if (list.count == 0)
break;
list.pids = (snd_ctl_element_id_t *)calloc(list.count, sizeof(snd_ctl_element_id_t));
list.pids = (snd_ctl_elem_id_t *)calloc(list.count, sizeof(snd_ctl_elem_id_t));
if (list.pids == NULL)
return -ENOMEM;
list.space = list.count;
@ -61,7 +61,7 @@ int snd_ctl_hbuild(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
return err;
} while (list.count != list.used);
for (idx = 0, prev = NULL; idx < list.count; idx++) {
helem = (snd_hctl_element_t *)calloc(1, sizeof(snd_hctl_element_t));
helem = (snd_hctl_elem_t *)calloc(1, sizeof(snd_hctl_elem_t));
if (helem == NULL)
goto __nomem;
helem->id = list.pids[idx];
@ -90,7 +90,7 @@ int snd_ctl_hbuild(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
return 0;
}
static void snd_ctl_hfree1(snd_hctl_element_t *helem)
static void snd_ctl_hfree1(snd_hctl_elem_t *helem)
{
snd_ctl_t *handle;
@ -202,7 +202,7 @@ static int snd_ctl_hsort_mixer_priority(const char *name)
return res + res1;
}
int snd_ctl_hsort(const snd_hctl_element_t *c1, const snd_hctl_element_t *c2)
int snd_ctl_hsort(const snd_hctl_elem_t *c1, const snd_hctl_elem_t *c2)
{
int res, p1, p2;
@ -211,7 +211,7 @@ int snd_ctl_hsort(const snd_hctl_element_t *c1, const snd_hctl_element_t *c2)
if (c1->id.iface > c2->id.iface)
return 1;
if ((res = strcmp(c1->id.name, c2->id.name)) != 0) {
if (c1->id.iface != SNDRV_CTL_ELEMENT_IFACE_MIXER)
if (c1->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
return res;
p1 = snd_ctl_hsort_mixer_priority(c1->id.name);
p2 = snd_ctl_hsort_mixer_priority(c2->id.name);
@ -228,7 +228,7 @@ int snd_ctl_hsort(const snd_hctl_element_t *c1, const snd_hctl_element_t *c2)
return 0;
}
static void snd_ctl_hresort_free(snd_hctl_element_t *helem ATTRIBUTE_UNUSED)
static void snd_ctl_hresort_free(snd_hctl_elem_t *helem ATTRIBUTE_UNUSED)
{
/* nothing */
}
@ -236,8 +236,8 @@ static void snd_ctl_hresort_free(snd_hctl_element_t *helem ATTRIBUTE_UNUSED)
int snd_ctl_hresort(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
{
struct list_head *list;
snd_hctl_element_t *helem;
snd_ctl_element_id_t *ids, *pids;
snd_hctl_elem_t *helem;
snd_ctl_elem_id_t *ids, *pids;
int idx;
assert(handle != NULL && hsort != NULL);
@ -246,12 +246,12 @@ int snd_ctl_hresort(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
if (handle->herr < 0)
return handle->herr;
assert(handle->hroot_new == NULL);
ids = pids = (snd_ctl_element_id_t *)malloc(sizeof(snd_ctl_element_id_t) * handle->hcount);
ids = pids = (snd_ctl_elem_id_t *)malloc(sizeof(snd_ctl_elem_id_t) * handle->hcount);
if (ids == NULL)
return -ENOMEM;
/* first step - update search engine */
list_for_each(list, &handle->hlist) {
helem = list_entry(list, snd_hctl_element_t, list);
helem = list_entry(list, snd_hctl_elem_t, list);
*pids++ = helem->id;
if (tsearch(helem, &handle->hroot_new, (__compar_fn_t)hsort) == NULL) {
if (handle->hroot_new != NULL)
@ -267,7 +267,7 @@ int snd_ctl_hresort(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
handle->hroot = handle->hroot_new;
handle->hroot_new = NULL;
/* second step - perform qsort and save results */
qsort(ids, handle->hcount, sizeof(snd_ctl_element_id_t), (int (*)(const void *, const void *))hsort);
qsort(ids, handle->hcount, sizeof(snd_ctl_elem_id_t), (int (*)(const void *, const void *))hsort);
INIT_LIST_HEAD(&handle->hlist);
for (idx = 0; idx < handle->hcount; idx++) {
helem = snd_ctl_hfind(handle, ids + idx);
@ -277,36 +277,36 @@ int snd_ctl_hresort(snd_ctl_t *handle, snd_ctl_hsort_t hsort)
return 0;
}
snd_hctl_element_t *snd_ctl_hfirst(snd_ctl_t *handle)
snd_hctl_elem_t *snd_ctl_hfirst(snd_ctl_t *handle)
{
assert(handle != NULL);
if (list_empty(&handle->hlist))
return NULL;
return (snd_hctl_element_t *)list_entry(handle->hlist.next, snd_hctl_element_t, list);
return (snd_hctl_elem_t *)list_entry(handle->hlist.next, snd_hctl_elem_t, list);
}
snd_hctl_element_t *snd_ctl_hlast(snd_ctl_t *handle)
snd_hctl_elem_t *snd_ctl_hlast(snd_ctl_t *handle)
{
assert(handle != NULL);
if (list_empty(&handle->hlist))
return NULL;
return (snd_hctl_element_t *)list_entry(handle->hlist.prev, snd_hctl_element_t, list);
return (snd_hctl_elem_t *)list_entry(handle->hlist.prev, snd_hctl_elem_t, list);
}
snd_hctl_element_t *snd_ctl_hnext(snd_ctl_t *handle, snd_hctl_element_t *helem)
snd_hctl_elem_t *snd_ctl_hnext(snd_ctl_t *handle, snd_hctl_elem_t *helem)
{
assert(handle != NULL && helem != NULL);
if (helem->list.next == &handle->hlist)
return NULL;
return (snd_hctl_element_t *)list_entry(helem->list.next, snd_hctl_element_t, list);
return (snd_hctl_elem_t *)list_entry(helem->list.next, snd_hctl_elem_t, list);
}
snd_hctl_element_t *snd_ctl_hprev(snd_ctl_t *handle, snd_hctl_element_t *helem)
snd_hctl_elem_t *snd_ctl_hprev(snd_ctl_t *handle, snd_hctl_elem_t *helem)
{
assert(handle != NULL && helem != NULL);
if (helem->list.prev == &handle->hlist)
return NULL;
return (snd_hctl_element_t *)list_entry(helem->list.prev, snd_hctl_element_t, list);
return (snd_hctl_elem_t *)list_entry(helem->list.prev, snd_hctl_elem_t, list);
}
int snd_ctl_hcount(snd_ctl_t *handle)
@ -315,7 +315,7 @@ int snd_ctl_hcount(snd_ctl_t *handle)
return handle->hcount;
}
snd_hctl_element_t *snd_ctl_hfind(snd_ctl_t *handle, snd_ctl_element_id_t *id)
snd_hctl_elem_t *snd_ctl_hfind(snd_ctl_t *handle, snd_ctl_elem_id_t *id)
{
void *res;
@ -323,13 +323,13 @@ snd_hctl_element_t *snd_ctl_hfind(snd_ctl_t *handle, snd_ctl_element_id_t *id)
if (handle->hroot == NULL)
return NULL;
res = tfind(id, &handle->hroot, (__compar_fn_t)handle->hsort);
return res == NULL ? NULL : *(snd_hctl_element_t **)res;
return res == NULL ? NULL : *(snd_hctl_elem_t **)res;
}
int snd_ctl_hlist(snd_ctl_t *handle, snd_hctl_element_list_t *hlist)
int snd_ctl_hlist(snd_ctl_t *handle, snd_hctl_elem_list_t *hlist)
{
struct list_head *list;
snd_hctl_element_t *helem;
snd_hctl_elem_t *helem;
unsigned int idx;
assert(hlist != NULL);
@ -342,7 +342,7 @@ int snd_ctl_hlist(snd_ctl_t *handle, snd_hctl_element_list_t *hlist)
return -EINVAL;
idx = 0;
list_for_each(list, &handle->hlist) {
helem = list_entry(list, snd_hctl_element_t, list);
helem = list_entry(list, snd_hctl_elem_t, list);
if (idx >= hlist->offset + hlist->space)
break;
if (idx >= hlist->offset) {
@ -378,9 +378,9 @@ static void callback_rebuild(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNU
handle->callback_rebuild(handle, handle->callback_rebuild_private_data);
}
static void callback_change(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_element_id_t *id)
static void callback_change(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_elem_id_t *id)
{
snd_hctl_element_t *helem;
snd_hctl_elem_t *helem;
if (handle->herr < 0)
return;
@ -392,9 +392,9 @@ static void callback_change(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUS
helem->change = 1;
}
static void callback_value(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_element_id_t *id)
static void callback_value(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_elem_id_t *id)
{
snd_hctl_element_t *helem;
snd_hctl_elem_t *helem;
if (handle->herr < 0)
return;
@ -406,13 +406,13 @@ static void callback_value(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSE
helem->value = 1;
}
static void callback_add(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_element_id_t *id)
static void callback_add(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_elem_id_t *id)
{
snd_hctl_element_t *helem, *icontrol;
snd_hctl_elem_t *helem, *icontrol;
if (handle->herr < 0)
return;
helem = (snd_hctl_element_t *)calloc(1, sizeof(snd_hctl_element_t));
helem = (snd_hctl_elem_t *)calloc(1, sizeof(snd_hctl_elem_t));
if (helem == NULL) {
handle->herr = -ENOMEM;
return;
@ -434,9 +434,9 @@ static void callback_add(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED,
handle->callback_add(handle, handle->callback_add_private_data, helem);
}
static void callback_remove(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_element_id_t *id)
static void callback_remove(snd_ctl_t *handle, void *private_data ATTRIBUTE_UNUSED, snd_ctl_elem_id_t *id)
{
snd_hctl_element_t *helem;
snd_hctl_elem_t *helem;
if (handle->herr < 0)
return;
@ -461,7 +461,7 @@ int snd_ctl_hevent(snd_ctl_t *handle)
reserved: { NULL, }
};
struct list_head *list;
snd_hctl_element_t *helem;
snd_hctl_elem_t *helem;
int res;
assert(handle != NULL);
@ -472,7 +472,7 @@ int snd_ctl_hevent(snd_ctl_t *handle)
if (handle->herr < 0)
return handle->herr;
list_for_each(list, &handle->hlist) {
helem = list_entry(list, snd_hctl_element_t, list);
helem = list_entry(list, snd_hctl_elem_t, list);
if (helem->change && helem->callback_change) {
helem->callback_change(helem->handle, helem);
helem->change = 0;
@ -485,7 +485,7 @@ int snd_ctl_hevent(snd_ctl_t *handle)
return res;
}
int snd_hctl_element_list_alloc_space(snd_hctl_element_list_t *obj, unsigned int entries)
int snd_hctl_elem_list_alloc_space(snd_hctl_elem_list_t *obj, unsigned int entries)
{
obj->pids = calloc(entries, sizeof(*obj->pids));
if (!obj->pids) {
@ -496,7 +496,7 @@ int snd_hctl_element_list_alloc_space(snd_hctl_element_list_t *obj, unsigned int
return 0;
}
void snd_hctl_element_list_free_space(snd_hctl_element_list_t *obj)
void snd_hctl_elem_list_free_space(snd_hctl_elem_list_t *obj)
{
free(obj->pids);
obj->pids = NULL;

458
src/control/hcontrol.c Normal file
View file

@ -0,0 +1,458 @@
/*
* Control Interface - highlevel API
* Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
* Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
*
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define __USE_GNU
#include "control_local.h"
static int _snd_hctl_find_elem(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, int *dir)
{
unsigned int l, u;
int c = 0;
int idx = -1;
assert(ctl && id);
assert(ctl->hcompare);
l = 0;
u = ctl->hcount;
while (l < u) {
idx = (l + u) / 2;
c = ctl->hcompare((snd_hctl_elem_t *) id, ctl->helems[idx]);
if (c < 0)
u = idx;
else if (c > 0)
l = idx + 1;
else
break;
}
*dir = c;
return idx;
}
static int snd_hctl_elem_add(snd_ctl_t *ctl, snd_hctl_elem_t *elem)
{
int dir;
int idx;
if (ctl->hcount == ctl->halloc) {
snd_hctl_elem_t **h;
ctl->halloc += 32;
h = realloc(ctl->helems, sizeof(*h) * ctl->halloc);
if (!h)
return -ENOMEM;
ctl->helems = h;
}
if (ctl->hcount == 0) {
list_add_tail(&elem->list, &ctl->hlist);
ctl->helems[0] = elem;
} else {
idx = _snd_hctl_find_elem(ctl, &elem->id, &dir);
assert(dir != 0);
if (dir > 0) {
list_add(&elem->list, &ctl->helems[idx]->list);
} else {
list_add_tail(&elem->list, &ctl->helems[idx]->list);
idx++;
}
memmove(ctl->helems + idx + 1,
ctl->helems + idx,
ctl->hcount - idx);
}
ctl->hcount++;
if (ctl->callback) {
int res = ctl->callback(ctl, SND_CTL_EVENT_ADD, elem);
if (res < 0)
return res;
}
return 0;
}
static void snd_hctl_elem_remove(snd_ctl_t *ctl, unsigned int idx)
{
snd_hctl_elem_t *elem = ctl->helems[idx];
unsigned int m;
if (elem->callback)
elem->callback(elem, SND_CTL_EVENT_REMOVE);
list_del(&elem->list);
free(elem);
ctl->hcount--;
m = ctl->hcount - idx;
if (m > 0)
memmove(ctl->helems + idx, ctl->helems + idx + 1, m);
}
int snd_hctl_free(snd_ctl_t *ctl)
{
while (ctl->hcount > 0)
snd_hctl_elem_remove(ctl, ctl->hcount - 1);
free(ctl->helems);
ctl->helems = 0;
ctl->halloc = 0;
INIT_LIST_HEAD(&ctl->hlist);
return 0;
}
static void snd_hctl_sort(snd_ctl_t *ctl)
{
unsigned int k;
int compar(const void *a, const void *b) {
return ctl->hcompare(*(const snd_hctl_elem_t **) a,
*(const snd_hctl_elem_t **) b);
}
assert(ctl);
assert(ctl->hcompare);
INIT_LIST_HEAD(&ctl->hlist);
qsort(ctl->helems, ctl->hcount, sizeof(*ctl->helems), compar);
for (k = 0; k < ctl->hcount; k++)
list_add_tail(&ctl->helems[k]->list, &ctl->hlist);
}
void snd_hctl_set_compare(snd_ctl_t *ctl, snd_hctl_compare_t hsort)
{
assert(ctl);
ctl->hcompare = hsort;
snd_hctl_sort(ctl);
}
#define NOT_FOUND 1000000000
static int snd_hctl_compare_mixer_priority_lookup(char **name, char * const *names, int coef)
{
int res;
for (res = 0; *names; names++, res += coef) {
if (!strncmp(*name, *names, strlen(*names))) {
*name += strlen(*names);
if (**name == ' ')
(*name)++;
return res;
}
}
return NOT_FOUND;
}
static int snd_hctl_compare_mixer_priority(const char *name)
{
static char *names[] = {
"Master",
"Master Digital",
"Master Mono",
"Hardware Master",
"Headphone",
"Tone Control",
"3D Control",
"PCM",
"PCM Front",
"PCM Rear",
"PCM Pan",
"Synth",
"FM",
"Wave",
"Music",
"DSP",
"Line",
"CD",
"Mic",
"Phone",
"Video",
"PC Speaker",
"Aux",
"Mono",
"Mono Output",
"ADC",
"Capture Source",
"Capture",
"Playback",
"Loopback",
"Analog Loopback",
"Digital Loopback",
"S/PDIF Input",
"S/PDIF Output",
NULL
};
static char *names1[] = {
"Switch",
"Volume",
"Playback",
"Capture",
"Bypass",
NULL
};
static char *names2[] = {
"Switch",
"Volume",
"Bypass",
NULL
};
int res, res1;
if ((res = snd_hctl_compare_mixer_priority_lookup((char **)&name, names, 1000000)) == NOT_FOUND)
return NOT_FOUND;
if ((res1 = snd_hctl_compare_mixer_priority_lookup((char **)&name, names1, 1000)) == NOT_FOUND)
return res;
res += res1;
if ((res1 = snd_hctl_compare_mixer_priority_lookup((char **)&name, names2, 1)) == NOT_FOUND)
return res;
return res + res1;
}
int snd_hctl_compare_fast(const snd_hctl_elem_t *c1,
const snd_hctl_elem_t *c2)
{
return c1->id.numid - c2->id.numid;
}
int snd_hctl_compare_default(const snd_hctl_elem_t *c1,
const snd_hctl_elem_t *c2)
{
int res, p1, p2;
int d = c1->id.iface - c2->id.iface;
if (d != 0)
return d;
if ((res = strcmp(c1->id.name, c2->id.name)) != 0) {
if (c1->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
return res;
p1 = snd_hctl_compare_mixer_priority(c1->id.name);
p2 = snd_hctl_compare_mixer_priority(c2->id.name);
d = p1 - p2;
if (d != 0)
return d;
return res;
}
d = c1->id.index - c2->id.index;
return d;
}
snd_hctl_elem_t *snd_hctl_first_elem(snd_ctl_t *ctl)
{
assert(ctl);
if (list_empty(&ctl->hlist))
return NULL;
return list_entry(ctl->hlist.next, snd_hctl_elem_t, list);
}
snd_hctl_elem_t *snd_hctl_last_elem(snd_ctl_t *ctl)
{
assert(ctl);
if (list_empty(&ctl->hlist))
return NULL;
return list_entry(ctl->hlist.prev, snd_hctl_elem_t, list);
}
snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem)
{
assert(elem);
if (elem->list.next == &elem->ctl->hlist)
return NULL;
return list_entry(elem->list.next, snd_hctl_elem_t, list);
}
snd_hctl_elem_t *snd_hctl_elem_prev(snd_hctl_elem_t *elem)
{
assert(elem);
if (elem->list.prev == &elem->ctl->hlist)
return NULL;
return list_entry(elem->list.prev, snd_hctl_elem_t, list);
}
snd_hctl_elem_t *snd_hctl_find_elem(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id)
{
int dir;
int res = _snd_hctl_find_elem(ctl, id, &dir);
if (res < 0 || dir != 0)
return NULL;
return ctl->helems[res];
}
int snd_hctl_build(snd_ctl_t *ctl)
{
snd_ctl_elem_list_t list;
int err = 0;
unsigned int idx;
assert(ctl);
assert(ctl->hcount == 0);
assert(list_empty(&ctl->hlist));
memset(&list, 0, sizeof(list));
if ((err = snd_ctl_elem_list(ctl, &list)) < 0)
goto _end;
while (list.count != list.used) {
err = snd_ctl_elem_list_alloc_space(&list, list.count);
if (err < 0)
goto _end;
if ((err = snd_ctl_elem_list(ctl, &list)) < 0)
goto _end;
}
if (ctl->halloc < list.count) {
ctl->halloc = list.count;
free(ctl->helems);
ctl->helems = malloc(ctl->halloc * sizeof(*ctl->helems));
if (!ctl->helems) {
err = -ENOMEM;
goto _end;
}
}
for (idx = 0; idx < list.count; idx++) {
snd_hctl_elem_t *elem;
elem = calloc(1, sizeof(snd_hctl_elem_t));
if (elem == NULL) {
snd_hctl_free(ctl);
err = -ENOMEM;
goto _end;
}
elem->id = list.pids[idx];
elem->ctl = ctl;
ctl->helems[idx] = elem;
list_add_tail(&elem->list, &ctl->hlist);
ctl->hcount++;
}
if (!ctl->hcompare)
ctl->hcompare = snd_hctl_compare_default;
snd_hctl_sort(ctl);
if (ctl->callback) {
for (idx = 0; idx < ctl->hcount; idx++) {
int res = ctl->callback(ctl, SND_CTL_EVENT_ADD,
ctl->helems[idx]);
if (res < 0)
return res;
}
}
_end:
if (list.pids)
free(list.pids);
return err;
}
void snd_hctl_set_callback(snd_ctl_t *ctl, snd_hctl_callback_t callback)
{
assert(ctl);
ctl->callback = callback;
}
void snd_hctl_set_callback_private(snd_ctl_t *ctl, void *callback_private)
{
assert(ctl);
ctl->callback_private = callback_private;
}
void *snd_hctl_get_callback_private(snd_ctl_t *ctl)
{
assert(ctl);
return ctl->callback_private;
}
unsigned int snd_hctl_get_count(snd_ctl_t *ctl)
{
return ctl->hcount;
}
int snd_hctl_event(snd_ctl_t *ctl, snd_ctl_event_t *event)
{
snd_hctl_elem_t *elem;
int res;
assert(ctl);
switch (event->type) {
case SND_CTL_EVENT_REMOVE:
{
int dir;
res = _snd_hctl_find_elem(ctl, &event->data.id, &dir);
assert(res >= 0 && dir == 0);
if (res < 0 || dir != 0)
return -ENOENT;
snd_hctl_elem_remove(ctl, res);
break;
}
case SND_CTL_EVENT_VALUE:
case SND_CTL_EVENT_CHANGE:
elem = snd_hctl_find_elem(ctl, &event->data.id);
assert(elem);
if (!elem)
return -ENOENT;
if (elem->callback) {
res = elem->callback(elem, event->type);
if (res < 0)
return res;
}
break;
case SND_CTL_EVENT_ADD:
elem = calloc(1, sizeof(snd_hctl_elem_t));
if (elem == NULL)
return -ENOMEM;
elem->id = event->data.id;
elem->ctl = ctl;
res = snd_hctl_elem_add(ctl, elem);
if (res < 0)
return res;
break;
case SND_CTL_EVENT_REBUILD:
snd_hctl_free(ctl);
res = snd_hctl_build(ctl);
if (ctl->callback) {
res = ctl->callback(ctl, event->type, NULL);
if (res < 0)
return res;
}
break;
default:
assert(0);
break;
}
return 0;
}
int snd_hctl_events(snd_ctl_t *ctl)
{
snd_ctl_event_t event;
int res;
while ((res = snd_ctl_read(ctl, &event)) != 0) {
if (res < 0)
return res;
res = snd_hctl_event(ctl, &event);
if (res < 0)
return res;
}
return 0;
}
int snd_hctl_elem_info(snd_hctl_elem_t *elem, snd_ctl_elem_info_t *info)
{
info->id = elem->id;
return snd_ctl_elem_info(elem->ctl, info);
}
int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_t * value)
{
value->id = elem->id;
return snd_ctl_elem_read(elem->ctl, value);
}
int snd_hctl_elem_write(snd_hctl_elem_t *elem, snd_ctl_elem_t * value)
{
value->id = elem->id;
return snd_ctl_elem_write(elem->ctl, value);
}

View file

@ -1,6 +1,6 @@
EXTRA_LTLIBRARIES=libmixer.la
libmixer_la_SOURCES = mixer.c simple.c
libmixer_la_SOURCES = bag.c mixer.c mixer_m4.c simple.c
all: libmixer.la

View file

@ -1,6 +1,7 @@
/*
* Control Interface - highlevel API - helem bag operations
* Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
* Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
*
*
* This library is free software; you can redistribute it and/or modify
@ -27,58 +28,53 @@
#include <sys/ioctl.h>
#define __USE_GNU
#include <search.h>
#include "control_local.h"
#include "mixer_local.h"
int snd_ctl_hbag_create(void **bag)
int snd_hctl_compare_fast(const snd_hctl_elem_t *c1,
const snd_hctl_elem_t *c2);
static void _free(void *ptr ATTRIBUTE_UNUSED) { };
int snd_hctl_bag_destroy(snd_hctl_bag_t *bag)
{
assert(bag != NULL);
*bag = NULL;
tdestroy(bag->root, _free);
bag->root = NULL;
return 0;
}
static void snd_ctl_hbag_free_private(snd_hctl_element_t *helem ATTRIBUTE_UNUSED)
{
/* nothing */
}
int snd_ctl_hbag_destroy(void **bag, void (*hctl_element_free)(snd_hctl_element_t *helem))
{
assert(bag != NULL);
if (hctl_element_free == NULL)
hctl_element_free = snd_ctl_hbag_free_private;
tdestroy(*bag, (__free_fn_t)hctl_element_free);
*bag = NULL;
return 0;
}
int snd_ctl_hbag_add(void **bag, snd_hctl_element_t *helem)
int snd_hctl_bag_add(snd_hctl_bag_t *bag, snd_hctl_elem_t *helem)
{
void *res;
assert(bag != NULL && helem != NULL);
res = tsearch(helem, bag, (__compar_fn_t)snd_ctl_hsort);
res = tsearch(helem, &bag->root, (__compar_fn_t)snd_hctl_compare_fast);
if (res == NULL)
return -ENOMEM;
if ((snd_hctl_element_t *)res == helem)
if ((snd_hctl_elem_t *)res == helem)
return -EALREADY;
return 0;
}
int snd_ctl_hbag_del(void **bag, snd_hctl_element_t *helem)
int snd_hctl_bag_del(snd_hctl_bag_t *bag, snd_hctl_elem_t *helem)
{
assert(bag != NULL && helem != NULL);
if (tdelete(helem, bag, (__compar_fn_t)snd_ctl_hsort) == NULL)
if (tdelete(helem, &bag->root, (__compar_fn_t)snd_hctl_compare_fast) == NULL)
return -ENOENT;
return 0;
}
snd_hctl_element_t *snd_ctl_hbag_find(void **bag, snd_ctl_element_id_t *id)
snd_hctl_elem_t *snd_hctl_bag_find(snd_hctl_bag_t *bag, snd_ctl_elem_id_t *id)
{
void *res;
assert(bag != NULL && id != NULL);
if (*bag == NULL)
if (bag->root == NULL)
return NULL;
res = tfind(id, bag, (__compar_fn_t)snd_ctl_hsort);
return res == NULL ? NULL : *(snd_hctl_element_t **)res;
res = tfind(id, &bag->root, (__compar_fn_t)snd_hctl_compare_fast);
return res == NULL ? NULL : *(snd_hctl_elem_t **)res;
}
int snd_hctl_bag_empty(snd_hctl_bag_t *bag)
{
assert(bag != NULL);
return bag->root == NULL;
}

View file

@ -1,6 +1,7 @@
/*
* Mixer Interface - main file
* Copyright (c) 1998/1999/2000 by Jaroslav Kysela <perex@suse.cz>
* Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
*
*
* This library is free software; you can redistribute it and/or modify
@ -27,202 +28,103 @@
#include <sys/ioctl.h>
#include "mixer_local.h"
static void snd_mixer_simple_read_rebuild(snd_ctl_t *ctl_handle, void *private_data);
static void snd_mixer_simple_read_add(snd_ctl_t *ctl_handle, void *private_data, snd_hctl_element_t *helem);
int snd_mixer_open(snd_mixer_t **r_handle, char *name)
int snd_mixer_open(snd_mixer_t **mixerp, char *name)
{
snd_mixer_t *handle;
snd_ctl_t *ctl_handle;
snd_mixer_t *mixer;
snd_ctl_t *ctl;
int err;
if (r_handle == NULL)
return -EINVAL;
*r_handle = NULL;
if ((err = snd_ctl_open(&ctl_handle, name)) < 0)
assert(mixerp);
if ((err = snd_ctl_open(&ctl, name)) < 0)
return err;
handle = (snd_mixer_t *) calloc(1, sizeof(snd_mixer_t));
if (handle == NULL) {
snd_ctl_close(ctl_handle);
mixer = calloc(1, sizeof(snd_mixer_t));
if (mixer == NULL) {
snd_ctl_close(ctl);
return -ENOMEM;
}
if ((err = snd_ctl_hcallback_rebuild(ctl_handle, snd_mixer_simple_read_rebuild, handle)) < 0) {
snd_ctl_close(ctl_handle);
free(handle);
return err;
}
if ((err = snd_ctl_hcallback_add(ctl_handle, snd_mixer_simple_read_add, handle)) < 0) {
snd_ctl_close(ctl_handle);
free(handle);
return err;
}
handle->ctl_handle = ctl_handle;
INIT_LIST_HEAD(&handle->simples);
*r_handle = handle;
mixer->ctl = ctl;
INIT_LIST_HEAD(&mixer->elems);
*mixerp = mixer;
return 0;
}
int snd_mixer_close(snd_mixer_t *handle)
snd_mixer_elem_t *snd_mixer_elem_add(snd_mixer_t *mixer)
{
int err = 0;
if (handle == NULL)
return -EINVAL;
if (handle->simple_valid)
snd_mixer_simple_destroy(handle);
if (handle->ctl_handle)
err = snd_ctl_close(handle->ctl_handle);
return err;
snd_mixer_elem_t *elem;
elem = calloc(1, sizeof(*elem));
if (!elem)
return NULL;
elem->mixer = mixer;
list_add_tail(&elem->list, &mixer->elems);
mixer->count++;
return elem;
}
int snd_mixer_poll_descriptor(snd_mixer_t *handle)
void snd_mixer_elem_remove(snd_mixer_elem_t *elem)
{
if (handle == NULL || handle->ctl_handle == NULL)
snd_mixer_t *mixer = elem->mixer;
if (elem->private_free)
elem->private_free(elem);
if (elem->callback)
elem->callback(elem, SND_CTL_EVENT_REMOVE);
list_del(&elem->list);
free(elem);
mixer->count--;
}
void snd_mixer_free(snd_mixer_t *mixer)
{
while (!list_empty(&mixer->elems))
snd_mixer_elem_remove(list_entry(mixer->elems.next, snd_mixer_elem_t, list));
}
int snd_mixer_close(snd_mixer_t *mixer)
{
assert(mixer);
snd_mixer_free(mixer);
return snd_ctl_close(mixer->ctl);
}
int snd_mixer_poll_descriptor(snd_mixer_t *mixer)
{
if (mixer == NULL || mixer->ctl == NULL)
return -EIO;
return snd_ctl_poll_descriptor(handle->ctl_handle);
return snd_ctl_poll_descriptor(mixer->ctl);
}
const char *snd_mixer_simple_channel_name(snd_mixer_channel_id_t channel)
snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer)
{
static char *array[snd_enum_to_int(SND_MIXER_CHN_LAST) + 1] = {
[SND_MIXER_CHN_FRONT_LEFT] = "Front Left",
[SND_MIXER_CHN_FRONT_RIGHT] = "Front Right",
[SND_MIXER_CHN_FRONT_CENTER] = "Front Center",
[SND_MIXER_CHN_REAR_LEFT] = "Rear Left",
[SND_MIXER_CHN_REAR_RIGHT] = "Rear Right",
[SND_MIXER_CHN_WOOFER] = "Woofer"
};
char *p;
assert(channel <= SND_MIXER_CHN_LAST);
p = array[snd_enum_to_int(channel)];
if (!p)
return "?";
return p;
assert(mixer);
if (list_empty(&mixer->elems))
return NULL;
return list_entry(mixer->elems.next, snd_mixer_elem_t, list);
}
int snd_mixer_simple_element_list(snd_mixer_t *handle, snd_mixer_simple_element_list_t *list)
snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer)
{
struct list_head *lh;
mixer_simple_t *s;
snd_mixer_sid_t *p;
int err;
unsigned int idx;
if (handle == NULL || list == NULL)
return -EINVAL;
if (!handle->simple_valid)
if ((err = snd_mixer_simple_build(handle)) < 0)
return err;
list->controls_count = 0;
p = list->pids;
if (list->controls_request > 0 && p == NULL)
return -EINVAL;
idx = 0;
list_for_each(lh, &handle->simples) {
if (idx >= list->controls_offset + list->controls_request)
break;
if (idx >= list->controls_offset) {
s = list_entry(lh, mixer_simple_t, list);
memcpy(p, &s->sid, sizeof(*p)); p++;
list->controls_count++;
}
idx++;
}
list->controls = handle->simple_count;
return 0;
assert(mixer);
if (list_empty(&mixer->elems))
return NULL;
return list_entry(mixer->elems.prev, snd_mixer_elem_t, list);
}
static mixer_simple_t *look_for_simple(snd_mixer_t *handle, snd_mixer_sid_t *sid)
snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem)
{
struct list_head *list;
mixer_simple_t *s;
list_for_each(list, &handle->simples) {
s = list_entry(list, mixer_simple_t, list);
if (!strcmp(s->sid.name, sid->name) && s->sid.index == sid->index)
return s;
}
return NULL;
assert(elem);
if (elem->list.next == &elem->mixer->elems)
return NULL;
return list_entry(elem->list.next, snd_mixer_elem_t, list);
}
int snd_mixer_simple_element_read(snd_mixer_t *handle, snd_mixer_simple_element_t *control)
snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem)
{
mixer_simple_t *s;
if (handle == NULL || control == NULL)
return -EINVAL;
if (!handle->simple_valid)
snd_mixer_simple_build(handle);
s = look_for_simple(handle, &control->sid);
if (s == NULL)
return -ENOENT;
if (s->get == NULL)
return -EIO;
return s->get(handle, s, control);
assert(elem);
if (elem->list.prev == &elem->mixer->elems)
return NULL;
return list_entry(elem->list.prev, snd_mixer_elem_t, list);
}
int snd_mixer_simple_element_write(snd_mixer_t *handle, snd_mixer_simple_element_t *control)
int snd_mixer_events(snd_mixer_t *mixer)
{
mixer_simple_t *s;
if (handle == NULL || control == NULL)
return -EINVAL;
if (!handle->simple_valid)
snd_mixer_simple_build(handle);
s = look_for_simple(handle, &control->sid);
if (s == NULL)
return -ENOENT;
if (s->put == NULL)
return -EIO;
return s->put(handle, s, control);
return snd_hctl_events(mixer->ctl);
}
static void snd_mixer_simple_read_rebuild(snd_ctl_t *ctl_handle, void *private_data)
{
snd_mixer_t *handle = (snd_mixer_t *)private_data;
if (handle->ctl_handle != ctl_handle)
return;
handle->callbacks->rebuild(handle, handle->callbacks->private_data);
handle->simple_changes++;
}
static void snd_mixer_simple_read_add(snd_ctl_t *ctl_handle ATTRIBUTE_UNUSED, void *private_data, snd_hctl_element_t *helem)
{
snd_mixer_t *handle = (snd_mixer_t *)private_data;
mixer_simple_t *s;
struct list_head *list;
list_for_each(list, &handle->simples) {
s = list_entry(list, mixer_simple_t, list);
if (s->event_add)
s->event_add(handle, helem);
}
}
int snd_mixer_simple_read(snd_mixer_t *handle, snd_mixer_simple_callbacks_t *callbacks)
{
mixer_simple_t *s;
struct list_head *list;
int err;
if (handle == NULL || callbacks == NULL)
return -EINVAL;
if (!handle->simple_valid)
snd_mixer_simple_build(handle);
handle->callbacks = callbacks;
handle->simple_changes = 0;
if ((err = snd_ctl_hevent(handle->ctl_handle)) <= 0) {
handle->callbacks = NULL;
return err;
}
handle->callbacks = NULL;
list_for_each(list, &handle->simples) {
s = list_entry(list, mixer_simple_t, list);
if (s->change > 0) {
s->change = 0;
if (callbacks->value)
callbacks->value(handle, callbacks->private_data, &s->sid);
}
}
return handle->simple_changes;
}

View file

@ -1,6 +1,7 @@
/*
* Mixer Interface - local header file
* Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
* Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
*
*
* This library is free software; you can redistribute it and/or modify
@ -19,72 +20,62 @@
*
*/
#include "local.h"
//#include "../control/control_local.h"
#include "list.h"
#include "local.h"
typedef struct _mixer_simple mixer_simple_t;
typedef struct _mixer_simple_hctl_element_private mixer_simple_hctl_element_private_t;
typedef struct _snd_hctl_bag {
void *root;
void *private;
} snd_hctl_bag_t;
typedef int (mixer_simple_get_t) (snd_mixer_t *handle, mixer_simple_t *simple, snd_mixer_simple_element_t *control);
typedef int (mixer_simple_put_t) (snd_mixer_t *handle, mixer_simple_t *simple, snd_mixer_simple_element_t *control);
typedef int (mixer_simple_event_add_t) (snd_mixer_t *handle, snd_hctl_element_t *helem);
int snd_hctl_bag_destroy(snd_hctl_bag_t *bag);
int snd_hctl_bag_add(snd_hctl_bag_t *bag, snd_hctl_elem_t *helem);
int snd_hctl_bag_del(snd_hctl_bag_t *bag, snd_hctl_elem_t *helem);
snd_hctl_elem_t *snd_hctl_bag_find(snd_hctl_bag_t *bag, snd_ctl_elem_id_t *id);
int snd_hctl_bag_empty(snd_hctl_bag_t *bag);
#define MIXER_PRESENT_SINGLE_SWITCH (1<<0)
#define MIXER_PRESENT_SINGLE_VOLUME (1<<1)
#define MIXER_PRESENT_GLOBAL_SWITCH (1<<2)
#define MIXER_PRESENT_GLOBAL_VOLUME (1<<3)
#define MIXER_PRESENT_GLOBAL_ROUTE (1<<4)
#define MIXER_PRESENT_PLAYBACK_SWITCH (1<<5)
#define MIXER_PRESENT_PLAYBACK_VOLUME (1<<6)
#define MIXER_PRESENT_PLAYBACK_ROUTE (1<<7)
#define MIXER_PRESENT_CAPTURE_SWITCH (1<<8)
#define MIXER_PRESENT_CAPTURE_VOLUME (1<<9)
#define MIXER_PRESENT_CAPTURE_ROUTE (1<<10)
#define MIXER_PRESENT_CAPTURE_SOURCE (1<<11)
struct _mixer_simple {
/* this may be moved to a private area */
unsigned int present; /* present controls */
unsigned int global_values;
unsigned int gswitch_values;
unsigned int pswitch_values;
unsigned int cswitch_values;
unsigned int gvolume_values;
unsigned int pvolume_values;
unsigned int cvolume_values;
unsigned int groute_values;
unsigned int proute_values;
unsigned int croute_values;
unsigned int ccapture_values;
unsigned int capture_item;
unsigned int caps;
long min;
long max;
int voices;
/* -- */
int refs; /* number of references */
int change; /* simple control was changed */
snd_mixer_sid_t sid;
mixer_simple_get_t *get;
mixer_simple_put_t *put;
mixer_simple_event_add_t *event_add;
struct list_head list;
void *helems; /* bag of associated helems */
unsigned long private_value;
struct _snd_mixer_elem {
snd_mixer_elem_type_t type;
struct list_head list; /* links for list of all elems */
void *private;
void (*private_free)(snd_mixer_elem_t *elem);
snd_mixer_elem_callback_t callback;
void *callback_private;
snd_mixer_t *mixer;
};
struct _mixer_simple_hctl_element_private {
void *simples; /* list of associated helems */
};
struct _snd_mixer {
snd_ctl_t *ctl_handle;
int simple_valid;
int simple_changes; /* total number of changes */
int simple_count;
struct list_head simples; /* list of all simple controls */
snd_mixer_simple_callbacks_t *callbacks;
snd_ctl_t *ctl;
struct list_head elems; /* list of all elemss */
unsigned int count;
snd_mixer_callback_t callback;
void *callback_private;
};
int snd_mixer_simple_build(snd_mixer_t *handle);
int snd_mixer_simple_destroy(snd_mixer_t *handle);
#define SND_MIXER_SCTCAP_VOLUME (1<<0)
#define SND_MIXER_SCTCAP_JOIN_VOLUME (1<<1)
#define SND_MIXER_SCTCAP_MUTE (1<<2)
#define SND_MIXER_SCTCAP_JOIN_MUTE (1<<3)
#define SND_MIXER_SCTCAP_CAPTURE (1<<4)
#define SND_MIXER_SCTCAP_JOIN_CAPTURE (1<<5)
#define SND_MIXER_SCTCAP_EXCL_CAPTURE (1<<6)
struct _snd_mixer_selem_id {
unsigned char name[60];
unsigned int index;
};
struct _snd_mixer_selem {
unsigned int caps; /* RO: capabilities */
unsigned int channels; /* RO: bitmap of active channels */
unsigned int mute; /* RW: bitmap of muted channels */
unsigned int capture; /* RW: bitmap of capture channels */
int capture_group; /* RO: capture group (for exclusive capture) */
long min; /* RO: minimum value */
long max; /* RO: maximum value */
long volume[32];
};
snd_mixer_elem_t *snd_mixer_elem_add(snd_mixer_t *mixer);
void snd_mixer_free(snd_mixer_t *mixer);

205
src/mixer/mixer_m4.c Normal file
View file

@ -0,0 +1,205 @@
/*
* Mixer - Automatically generated functions
* Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
*
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "mixer_local.h"
size_t snd_mixer_selem_id_sizeof()
{
return sizeof(snd_mixer_selem_id_t);
}
int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_mixer_selem_id_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj)
{
free(obj);
}
void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src)
{
assert(dst && src);
*dst = *src;
}
const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj)
{
assert(obj);
return obj->name;
}
unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj)
{
assert(obj);
return obj->index;
}
void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val)
{
assert(obj);
strncpy(obj->name, val, sizeof(obj->name));
}
void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val)
{
assert(obj);
obj->index = val;
}
void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val)
{
assert(obj);
obj->callback = val;
}
void * snd_mixer_get_callback_private(const snd_mixer_t *obj)
{
assert(obj);
return obj->callback_private;
}
void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val)
{
assert(obj);
obj->callback_private = val;
}
unsigned int snd_mixer_get_count(const snd_mixer_t *obj)
{
assert(obj);
return obj->count;
}
void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val)
{
assert(obj);
obj->callback = val;
}
void * snd_mixer_elem_get_callback_private(const snd_mixer_elem_t *obj)
{
assert(obj);
return obj->callback_private;
}
void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val)
{
assert(obj);
obj->callback_private = val;
}
snd_mixer_elem_type_t snd_mixer_elem_get_type(const snd_mixer_elem_t *obj)
{
assert(obj);
return obj->type;
}
size_t snd_mixer_selem_sizeof()
{
return sizeof(snd_mixer_selem_t);
}
int snd_mixer_selem_malloc(snd_mixer_selem_t **ptr)
{
assert(ptr);
*ptr = calloc(1, sizeof(snd_mixer_selem_t));
if (!*ptr)
return -ENOMEM;
return 0;
}
void snd_mixer_selem_free(snd_mixer_selem_t *obj)
{
free(obj);
}
void snd_mixer_selem_copy(snd_mixer_selem_t *dst, const snd_mixer_selem_t *src)
{
assert(dst && src);
*dst = *src;
}
long snd_mixer_selem_get_min(const snd_mixer_selem_t *obj)
{
assert(obj);
return obj->min;
}
long snd_mixer_selem_get_max(const snd_mixer_selem_t *obj)
{
assert(obj);
return obj->max;
}
int snd_mixer_selem_get_capture_group(const snd_mixer_selem_t *obj)
{
assert(obj);
return obj->capture_group;
}
int snd_mixer_selem_has_volume(const snd_mixer_selem_t *obj)
{
assert(obj);
return !!(obj->caps & SND_MIXER_SCTCAP_VOLUME);
}
int snd_mixer_selem_has_joined_volume(const snd_mixer_selem_t *obj)
{
assert(obj);
return !!(obj->caps & SND_MIXER_SCTCAP_JOIN_VOLUME);
}
int snd_mixer_selem_has_mute(const snd_mixer_selem_t *obj)
{
assert(obj);
return !!(obj->caps & SND_MIXER_SCTCAP_MUTE);
}
int snd_mixer_selem_has_joined_mute(const snd_mixer_selem_t *obj)
{
assert(obj);
return !!(obj->caps & SND_MIXER_SCTCAP_JOIN_MUTE);
}
int snd_mixer_selem_has_capture(const snd_mixer_selem_t *obj)
{
assert(obj);
return !!(obj->caps & SND_MIXER_SCTCAP_CAPTURE);
}
int snd_mixer_selem_has_joined_capture(const snd_mixer_selem_t *obj)
{
assert(obj);
return !!(obj->caps & SND_MIXER_SCTCAP_JOIN_CAPTURE);
}
int snd_mixer_selem_has_exclusive_capture(const snd_mixer_selem_t *obj)
{
assert(obj);
return !!(obj->caps & SND_MIXER_SCTCAP_EXCL_CAPTURE);
}

File diff suppressed because it is too large Load diff