summaryrefslogtreecommitdiff
path: root/src/mixer
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo@alsa-project.org>2001-03-30 09:43:29 +0000
committerAbramo Bagnara <abramo@alsa-project.org>2001-03-30 09:43:29 +0000
commitb4ac62f3dd2eddb2aed9ab0d2a901653c8e77a38 (patch)
tree02ce2d05b9c44333ee6a382aaaa92f2fed8196ed /src/mixer
parent5b50ec848a65396d5e8be32290c4431485001ed5 (diff)
More documentation. Tiny change for simple mixer element API (get_range)
Diffstat (limited to 'src/mixer')
-rw-r--r--src/mixer/Makefile.am2
-rw-r--r--src/mixer/mixer.c262
-rw-r--r--src/mixer/mixer_local.h1
-rw-r--r--src/mixer/mixer_m4.c120
-rw-r--r--src/mixer/simple.c750
5 files changed, 779 insertions, 356 deletions
diff --git a/src/mixer/Makefile.am b/src/mixer/Makefile.am
index bcdb109e..115c4077 100644
--- a/src/mixer/Makefile.am
+++ b/src/mixer/Makefile.am
@@ -1,6 +1,6 @@
EXTRA_LTLIBRARIES=libmixer.la
-libmixer_la_SOURCES = bag.c mixer.c mixer_m4.c simple.c
+libmixer_la_SOURCES = bag.c mixer.c simple.c
noinst_HEADERS = mixer_local.h
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c
index 471911e4..9efbaa49 100644
--- a/src/mixer/mixer.c
+++ b/src/mixer/mixer.c
@@ -1,3 +1,12 @@
+/**
+ * \file mixer/mixer.c
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \date 2001
+ *
+ * Mixer interface is designed to access mixer elements.
+ * Callbacks may be used for event handling.
+ */
/*
* Mixer Interface - main file
* Copyright (c) 1998/1999/2000 by Jaroslav Kysela <perex@suse.cz>
@@ -20,6 +29,7 @@
*
*/
+#ifndef DOC_HIDDEN
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -33,16 +43,18 @@ typedef struct _snd_mixer_slave {
struct list_head list;
} snd_mixer_slave_t;
-
-typedef struct _snd_mixer_elem_bag {
-
-} snd_mixer_elem_bag_t;
-
+#endif
static int snd_mixer_compare_default(const snd_mixer_elem_t *c1,
const snd_mixer_elem_t *c2);
+/**
+ * \brief Opens an empty mixer
+ * \param mixerp Returned mixer handle
+ * \param mode Open mode
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_open(snd_mixer_t **mixerp, int mode ATTRIBUTE_UNUSED)
{
snd_mixer_t *mixer;
@@ -58,6 +70,14 @@ int snd_mixer_open(snd_mixer_t **mixerp, int mode ATTRIBUTE_UNUSED)
return 0;
}
+/**
+ * \brief Attach an HCTL element to a mixer element
+ * \param melem Mixer element
+ * \param helem HCTL element
+ * \return 0 on success otherwise a negative error code
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_elem_attach(snd_mixer_elem_t *melem,
snd_hctl_elem_t *helem)
{
@@ -69,6 +89,14 @@ int snd_mixer_elem_attach(snd_mixer_elem_t *melem,
return bag_add(&melem->helems, helem);
}
+/**
+ * \brief Detach an HCTL element from a mixer element
+ * \param melem Mixer element
+ * \param helem HCTL element
+ * \return 0 on success otherwise a negative error code
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_elem_detach(snd_mixer_elem_t *melem,
snd_hctl_elem_t *helem)
{
@@ -81,6 +109,13 @@ int snd_mixer_elem_detach(snd_mixer_elem_t *melem,
return 0;
}
+/**
+ * \brief Return true if a mixer element does not contain any HCTL elements
+ * \param melem Mixer element
+ * \return 0 if not empty, 1 if empty
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_elem_empty(snd_mixer_elem_t *melem)
{
return bag_empty(&melem->helems);
@@ -144,6 +179,12 @@ static int hctl_event_handler(snd_hctl_t *hctl, unsigned int mask,
}
+/**
+ * \brief Attach an HCTL to an opened mixer
+ * \param mixer Mixer handle
+ * \param name HCTL name (see #snd_hctl_open)
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_attach(snd_mixer_t *mixer, const char *name)
{
snd_mixer_slave_t *slave;
@@ -170,6 +211,12 @@ int snd_mixer_attach(snd_mixer_t *mixer, const char *name)
return 0;
}
+/**
+ * \brief Detach a previously attached HCTL to an opened mixer freeing all related resources
+ * \param mixer Mixer handle
+ * \param name HCTL previously attached
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_detach(snd_mixer_t *mixer, const char *name)
{
struct list_head *pos;
@@ -195,7 +242,7 @@ static int snd_mixer_throw_event(snd_mixer_t *mixer, unsigned int mask,
return 0;
}
-int snd_mixer_elem_throw_event(snd_mixer_elem_t *elem, unsigned int mask)
+static int snd_mixer_elem_throw_event(snd_mixer_elem_t *elem, unsigned int mask)
{
elem->class->mixer->events++;
if (elem->callback)
@@ -226,6 +273,14 @@ static int _snd_mixer_find_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem, int
return idx;
}
+/**
+ * \brief Add an element for a registered mixer element class
+ * \param elem Mixer element
+ * \param class Mixer element class
+ * \return 0 on success otherwise a negative error code
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class)
{
int dir, idx;
@@ -263,6 +318,13 @@ int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class)
return snd_mixer_throw_event(mixer, SND_CTL_EVENT_MASK_ADD, elem);
}
+/**
+ * \brief Remove a mixer element
+ * \param elem Mixer element
+ * \return 0 on success otherwise a negative error code
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_elem_remove(snd_mixer_elem_t *elem)
{
snd_mixer_t *mixer = elem->class->mixer;
@@ -292,16 +354,38 @@ int snd_mixer_elem_remove(snd_mixer_elem_t *elem)
return err;
}
+/**
+ * \brief Mixer element informations are changed
+ * \param elem Mixer element
+ * \return 0 on success otherwise a negative error code
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_elem_info(snd_mixer_elem_t *elem)
{
return snd_mixer_elem_throw_event(elem, SND_CTL_EVENT_MASK_INFO);
}
+/**
+ * \brief Mixer element values is changed
+ * \param elem Mixer element
+ * \return 0 on success otherwise a negative error code
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_elem_value(snd_mixer_elem_t *elem)
{
return snd_mixer_elem_throw_event(elem, SND_CTL_EVENT_MASK_VALUE);
}
+/**
+ * \brief Register mixer element class
+ * \param class Mixer element class
+ * \param mixer Mixer handle
+ * \return 0 on success otherwise a negative error code
+ *
+ * For use by mixer element class specific code.
+ */
int snd_mixer_class_register(snd_mixer_class_t *class, snd_mixer_t *mixer)
{
struct list_head *pos;
@@ -325,6 +409,11 @@ int snd_mixer_class_register(snd_mixer_class_t *class, snd_mixer_t *mixer)
return 0;
}
+/**
+ * \brief Unregister mixer element class and remove all its elements
+ * \param class Mixer element class
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_class_unregister(snd_mixer_class_t *class)
{
unsigned int k;
@@ -342,6 +431,11 @@ int snd_mixer_class_unregister(snd_mixer_class_t *class)
return 0;
}
+/**
+ * \brief Load a mixer elements
+ * \param mixer Mixer handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_load(snd_mixer_t *mixer)
{
struct list_head *pos;
@@ -356,6 +450,10 @@ int snd_mixer_load(snd_mixer_t *mixer)
return 0;
}
+/**
+ * \brief Unload all mixer elements and free all related resources
+ * \param mixer Mixer handle
+ */
void snd_mixer_free(snd_mixer_t *mixer)
{
struct list_head *pos;
@@ -366,6 +464,11 @@ void snd_mixer_free(snd_mixer_t *mixer)
}
}
+/**
+ * \brief Close a mixer and free all related resources
+ * \param mixer Mixer handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_close(snd_mixer_t *mixer)
{
int res = 0;
@@ -423,21 +526,32 @@ static int snd_mixer_sort(snd_mixer_t *mixer)
return 0;
}
-int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t msort)
+/**
+ * \brief Change mixer compare function and reorder elements
+ * \param mixer Mixer handle
+ * \param compare Element compare function
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t compare)
{
- snd_mixer_compare_t msort_old;
+ snd_mixer_compare_t compare_old;
int err;
assert(mixer);
- msort_old = mixer->compare;
- mixer->compare = msort == NULL ? snd_mixer_compare_default : msort;
+ compare_old = mixer->compare;
+ mixer->compare = compare == NULL ? snd_mixer_compare_default : compare;
if ((err = snd_mixer_sort(mixer)) < 0) {
- mixer->compare = msort_old;
+ mixer->compare = compare_old;
return err;
}
return 0;
}
+/**
+ * \brief get count of poll descriptors for mixer handle
+ * \param mixer Mixer handle
+ * \return count of poll descriptors
+ */
int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer)
{
struct list_head *pos;
@@ -455,6 +569,13 @@ int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer)
return c;
}
+/**
+ * \brief get poll descriptors
+ * \param mixer Mixer handle
+ * \param pfds array of poll descriptors
+ * \param space space in the poll descriptor array
+ * \return count of filled descriptors
+ */
int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space)
{
struct list_head *pos;
@@ -477,6 +598,12 @@ int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned
return count;
}
+/**
+ * \brief Wait for a mixer to become ready (i.e. at least one event pending)
+ * \param mixer Mixer handle
+ * \param timeout maximum time in milliseconds to wait
+ * \return 0 otherwise a negative error code on failure
+ */
int snd_mixer_wait(snd_mixer_t *mixer, int timeout)
{
struct pollfd spfds[16];
@@ -500,6 +627,11 @@ int snd_mixer_wait(snd_mixer_t *mixer, int timeout)
return 0;
}
+/**
+ * \brief get first element for a mixer
+ * \param mixer Mixer handle
+ * \return pointer to first element
+ */
snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer)
{
assert(mixer);
@@ -508,6 +640,11 @@ snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer)
return list_entry(mixer->elems.next, snd_mixer_elem_t, list);
}
+/**
+ * \brief get last element for a mixer
+ * \param mixer Mixer handle
+ * \return pointer to last element
+ */
snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer)
{
assert(mixer);
@@ -516,6 +653,11 @@ snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer)
return list_entry(mixer->elems.prev, snd_mixer_elem_t, list);
}
+/**
+ * \brief get next mixer element
+ * \param elem mixer element
+ * \return pointer to next element
+ */
snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem)
{
assert(elem);
@@ -524,6 +666,11 @@ snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem)
return list_entry(elem->list.next, snd_mixer_elem_t, list);
}
+/**
+ * \brief get previous mixer element
+ * \param elem mixer element
+ * \return pointer to previous element
+ */
snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem)
{
assert(elem);
@@ -532,6 +679,11 @@ snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem)
return list_entry(elem->list.prev, snd_mixer_elem_t, list);
}
+/**
+ * \brief Handle pending mixer events invoking callbacks
+ * \param mixer Mixer handle
+ * \return 0 otherwise a negative error code on failure
+ */
int snd_mixer_handle_events(snd_mixer_t *mixer)
{
struct list_head *pos;
@@ -548,3 +700,91 @@ int snd_mixer_handle_events(snd_mixer_t *mixer)
return mixer->events;
}
+/**
+ * \brief Set callback function for a mixer
+ * \param mixer mixer handle
+ * \param callback callback function
+ */
+void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val)
+{
+ assert(obj);
+ obj->callback = val;
+}
+
+/**
+ * \brief Set callback private value for a mixer
+ * \param mixer mixer handle
+ * \param callback_private callback private value
+ */
+void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val)
+{
+ assert(obj);
+ obj->callback_private = val;
+}
+
+/**
+ * \brief Get callback private value for a mixer
+ * \param mixer mixer handle
+ * \return callback private value
+ */
+void * snd_mixer_get_callback_private(const snd_mixer_t *obj)
+{
+ assert(obj);
+ return obj->callback_private;
+}
+
+/**
+ * \brief Get elements count for a mixer
+ * \param mixer mixer handle
+ * \return elements count
+ */
+unsigned int snd_mixer_get_count(const snd_mixer_t *obj)
+{
+ assert(obj);
+ return obj->count;
+}
+
+/**
+ * \brief Set callback function for a mixer element
+ * \param obj mixer element
+ * \param val callback function
+ */
+void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val)
+{
+ assert(obj);
+ obj->callback = val;
+}
+
+/**
+ * \brief Set callback private value for a mixer element
+ * \param obj mixer element
+ * \param val callback private value
+ */
+void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val)
+{
+ assert(obj);
+ obj->callback_private = val;
+}
+
+/**
+ * \brief Get callback private value for a mixer element
+ * \param obj mixer element
+ * \return callback private value
+ */
+void * snd_mixer_elem_get_callback_private(const snd_mixer_elem_t *obj)
+{
+ assert(obj);
+ return obj->callback_private;
+}
+
+/**
+ * \brief Get type for a mixer element
+ * \param obj mixer element
+ * \return mixer element type
+ */
+snd_mixer_elem_type_t snd_mixer_elem_get_type(const snd_mixer_elem_t *obj)
+{
+ assert(obj);
+ return obj->type;
+}
+
diff --git a/src/mixer/mixer_local.h b/src/mixer/mixer_local.h
index e41b6a0c..266b11fc 100644
--- a/src/mixer/mixer_local.h
+++ b/src/mixer/mixer_local.h
@@ -90,7 +90,6 @@ struct _snd_mixer_selem_id {
int snd_mixer_class_register(snd_mixer_class_t *class, snd_mixer_t *mixer);
int snd_mixer_add_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem);
int snd_mixer_remove_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem);
-int snd_mixer_elem_throw_event(snd_mixer_elem_t *elem, unsigned int mask);
int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class);
int snd_mixer_elem_remove(snd_mixer_elem_t *elem);
int snd_mixer_elem_info(snd_mixer_elem_t *elem);
diff --git a/src/mixer/mixer_m4.c b/src/mixer/mixer_m4.c
deleted file mode 100644
index 73148818..00000000
--- a/src/mixer/mixer_m4.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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;
-}
-
diff --git a/src/mixer/simple.c b/src/mixer/simple.c
index 34888eda..d3e3f932 100644
--- a/src/mixer/simple.c
+++ b/src/mixer/simple.c
@@ -1,3 +1,11 @@
+/**
+ * \file mixer/simple.c
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \date 2001
+ *
+ * Mixer simple elements class interface.
+ */
/*
* Mixer Interface - simple controls
* Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
@@ -20,6 +28,7 @@
*
*/
+#ifndef DOC_HIDDEN
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -83,6 +92,8 @@ typedef struct _selem {
} str[2];
} selem_t;
+#endif
+
static struct mixer_name_table {
const char *longname;
const char *shortname;
@@ -869,7 +880,15 @@ static int simple_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2
return s1->id.index - s2->id.index;
}
-int snd_mixer_selem_register(snd_mixer_t *mixer, void *arg ATTRIBUTE_UNUSED,
+
+/**
+ * \brief Register mixer simple element class
+ * \param mixer Mixer handle
+ * \param options Options container (not used now)
+ * \param classp Pointer to returned mixer simple element class handle (or NULL)
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_register(snd_mixer_t *mixer, void *options ATTRIBUTE_UNUSED,
snd_mixer_class_t **classp)
{
snd_mixer_class_t *class = calloc(1, sizeof(*class));
@@ -888,6 +907,12 @@ int snd_mixer_selem_register(snd_mixer_t *mixer, void *arg ATTRIBUTE_UNUSED,
return 0;
}
+/**
+ * \brief Find a mixer simple element
+ * \param mixer Mixer handle
+ * \param id Mixer simple element identificator
+ * \return mixer simple element handle or NULL if not found
+ */
snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer,
const snd_mixer_selem_id_t *id)
{
@@ -905,6 +930,11 @@ snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer,
return NULL;
}
+/**
+ * \brief Get mixer simple element identificator
+ * \param elem Mixer simple element handle
+ * \param id returned mixer simple element identificator
+ */
void snd_mixer_selem_get_id(snd_mixer_elem_t *elem,
snd_mixer_selem_id_t *id)
{
@@ -915,6 +945,11 @@ void snd_mixer_selem_get_id(snd_mixer_elem_t *elem,
*id = s->id;
}
+/**
+ * \brief Get name part of mixer simple element identificator
+ * \param elem Mixer simple element handle
+ * \return name part of simple element identificator
+ */
const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem)
{
selem_t *s;
@@ -924,6 +959,11 @@ const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem)
return s->id.name;
}
+/**
+ * \brief Get index part of mixer simple element identificator
+ * \param elem Mixer simple element handle
+ * \return index part of simple element identificator
+ */
unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem)
{
selem_t *s;
@@ -933,6 +973,130 @@ unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem)
return s->id.index;
}
+/**
+ * \brief Return true if mixer simple element has only one volume control for both playback and capture
+ * \param elem Mixer simple element handle
+ * \return 0 separated control, 1 common control
+ */
+int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem)
+{
+ selem_t *s;
+ assert(elem);
+ assert(elem->type == SND_MIXER_ELEM_SIMPLE);
+ s = elem->private_data;
+ return !!(s->caps & CAP_GVOLUME);
+}
+
+/**
+ * \brief Return true if mixer simple element has only one switch control for both playback and capture
+ * \param elem Mixer simple element handle
+ * \return 0 separated control, 1 common control
+ */
+int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem)
+{
+ selem_t *s;
+ assert(elem);
+ assert(elem->type == SND_MIXER_ELEM_SIMPLE);
+ s = elem->private_data;
+ return !!(s->caps & CAP_GSWITCH);
+}
+
+static int _snd_mixer_selem_set_volume(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value)
+{
+ selem_t *s = elem->private_data;
+ assert((unsigned int) channel < s->str[dir].channels);
+ assert(value >= s->str[dir].min && value <= s->str[dir].max);
+ if (s->caps &
+ (dir == PLAY ? CAP_PVOLUME_JOIN : CAP_CVOLUME_JOIN))
+ channel = 0;
+ if (value != s->str[dir].vol[channel]) {
+ s->str[dir].vol[channel] = value;
+ return 1;
+ }
+ return 0;
+}
+
+static int _snd_mixer_selem_set_volume_all(snd_mixer_elem_t *elem, int dir, long value)
+{
+ int changed = 0;
+ snd_mixer_selem_channel_id_t channel;
+ selem_t *s = elem->private_data;
+ assert(value >= s->str[dir].min && value <= s->str[dir].max);
+ for (channel = 0; (unsigned int) channel < s->str[dir].channels; channel++) {
+ if (value != s->str[dir].vol[channel]) {
+ s->str[dir].vol[channel] = value;
+ changed = 1;
+ }
+ }
+ return changed;
+}
+
+static int _snd_mixer_selem_set_switch(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value)
+{
+ selem_t *s = elem->private_data;
+ assert((unsigned int) channel < s->str[dir].channels);
+ if (s->caps &
+ (dir == PLAY ? CAP_PSWITCH_JOIN : CAP_CSWITCH_JOIN))
+ channel = 0;
+ if (value) {
+ if (!(s->str[dir].sw & (1 << channel))) {
+ s->str[dir].sw |= 1 << channel;
+ return 1;
+ }
+ } else {
+ if (s->str[dir].sw & (1 << channel)) {
+ s->str[dir].sw &= ~(1 << channel);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int _snd_mixer_selem_set_switch_all(snd_mixer_elem_t *elem, int dir, int value)
+{
+ selem_t *s = elem->private_data;
+ if (value) {
+ if (s->str[dir].sw != ~0U) {
+ s->str[dir].sw = ~0U;
+ return 1;
+ }
+ } else {
+ if (s->str[dir].sw != 0U) {
+ s->str[dir].sw = 0U;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * \brief Return name of mixer simple element channel
+ * \param channel mixer simple element channel identificator
+ * \return channel name
+ */
+const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel)
+{
+ static const char *array[snd_enum_to_int(SND_MIXER_SCHN_LAST) + 1] = {
+ [SND_MIXER_SCHN_FRONT_LEFT] = "Front Left",
+ [SND_MIXER_SCHN_FRONT_RIGHT] = "Front Right",
+ [SND_MIXER_SCHN_FRONT_CENTER] = "Front Center",
+ [SND_MIXER_SCHN_REAR_LEFT] = "Rear Left",
+ [SND_MIXER_SCHN_REAR_RIGHT] = "Rear Right",
+ [SND_MIXER_SCHN_WOOFER] = "Woofer"
+ };
+ const char *p;
+ assert(channel <= SND_MIXER_SCHN_LAST);
+ p = array[snd_enum_to_int(channel)];
+ if (!p)
+ return "?";
+ return p;
+}
+
+/**
+ * \brief Get info about channels of playback stream of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if not mono, 1 if mono
+ */
int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem)
{
selem_t *s;
@@ -942,6 +1106,12 @@ int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem)
return s->str[PLAY].channels == 1;
}
+/**
+ * \brief Get info about channels of playback stream of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel Mixer simple element channel identificator
+ * \return 0 if channel is not present, 1 if present
+ */
int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
{
selem_t *s;
@@ -951,142 +1121,336 @@ int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *elem, snd_mixer_selem
return (unsigned int) channel < s->str[PLAY].channels;
}
-int snd_mixer_selem_get_playback_min(snd_mixer_elem_t *elem)
+/**
+ * \brief Get range for playback volume of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param min Pointer to returned minimum
+ * \param max Pointer to returned maximum
+ */
+void snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem,
+ long *min, long *max)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return s->str[PLAY].min;
+ *min = s->str[PLAY].min;
+ *max = s->str[PLAY].max;
}
-int snd_mixer_selem_get_playback_max(snd_mixer_elem_t *elem)
+/**
+ * \brief Set range for playback volume of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param min minimum volume value
+ * \param max maximum volume value
+ */
+void snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem,
+ long min, long max)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return s->str[PLAY].max;
+ assert(min != max);
+ s->str[PLAY].range = 1;
+ s->str[PLAY].min = min;
+ s->str[PLAY].max = max;
}
-int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem)
+/**
+ * \brief Return info about playback volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if no control is present, 1 if it's present
+ */
+int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return s->str[CAPT].channels == 1;
+ return !!(s->caps & CAP_PVOLUME);
}
-int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
+/**
+ * \brief Return info about playback volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if control is separated per channel, 1 if control acts on all channels together
+ */
+int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return (unsigned int) channel < s->str[CAPT].channels;
+ return !!(s->caps & CAP_PVOLUME_JOIN);
}
-int snd_mixer_selem_get_capture_min(snd_mixer_elem_t *elem)
+/**
+ * \brief Return info about playback switch control existence of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if no control is present, 1 if it's present
+ */
+int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return s->str[CAPT].min;
+ return !!(s->caps & CAP_PSWITCH);
}
-int snd_mixer_selem_get_capture_max(snd_mixer_elem_t *elem)
+/**
+ * \brief Return info about playback switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if control is separated per channel, 1 if control acts on all channels together
+ */
+int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return s->str[CAPT].max;
+ return !!(s->caps & CAP_PSWITCH_JOIN);
}
-int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem)
+/**
+ * \brief Return value of playback volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value pointer to returned value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
{
+ int err;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- assert(s->caps & CAP_CSWITCH_EXCL);
- return s->capture_group;
+ assert((unsigned int) channel < s->str[PLAY].channels);
+ assert(s->caps & CAP_PVOLUME);
+ err = snd_mixer_handle_events(elem->class->mixer);
+ if (err < 0)
+ return err;
+ if (s->caps & CAP_PVOLUME_JOIN)
+ channel = 0;
+ *value = s->str[PLAY].vol[channel];
+ return 0;
}
-int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem)
+/**
+ * \brief Return value of playback switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value pointer to returned value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
{
+ int err;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_GVOLUME);
+ assert((unsigned int) channel < s->str[PLAY].channels);
+ assert(s->caps & CAP_PSWITCH);
+ err = snd_mixer_handle_events(elem->class->mixer);
+ if (err < 0)
+ return err;
+ if (s->caps & CAP_PSWITCH_JOIN)
+ channel = 0;
+ *value = !!(s->str[PLAY].sw & (1 << channel));
+ return 0;
}
-int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem)
+/**
+ * \brief Set value of playback volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
{
+ int changed;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_PVOLUME);
+ assert(s->caps & CAP_PVOLUME);
+ changed = _snd_mixer_selem_set_volume(elem, PLAY, channel, value);
+ if (changed < 0)
+ return changed;
+ if (changed)
+ return selem_write(elem);
+ return 0;
}
-int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem)
+/**
+ * \brief Set value of playback volume control for all channels of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value)
{
+ int changed;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_PVOLUME_JOIN);
+ assert(s->caps & CAP_PVOLUME);
+ changed = _snd_mixer_selem_set_volume_all(elem, PLAY, value);
+ if (changed < 0)
+ return changed;
+ if (changed)
+ return selem_write(elem);
+ return 0;
}
-int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem)
+/**
+ * \brief Set value of playback switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
{
+ int changed;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_CVOLUME);
+ assert(s->caps & CAP_PSWITCH);
+ changed = _snd_mixer_selem_set_switch(elem, PLAY, channel, value);
+ if (changed < 0)
+ return changed;
+ if (changed)
+ return selem_write(elem);
+ return 0;
}
-int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem)
+/**
+ * \brief Set value of playback switch control for all channels of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value)
{
+ int changed;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_CVOLUME_JOIN);
+ assert(s->caps & CAP_PSWITCH);
+ changed = _snd_mixer_selem_set_switch_all(elem, PLAY, value);
+ if (changed < 0)
+ return changed;
+ if (changed)
+ return selem_write(elem);
+ return 0;
}
-int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem)
+/**
+ * \brief Get info about channels of capture stream of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if not mono, 1 if mono
+ */
+int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_GSWITCH);
+ return s->str[CAPT].channels == 1;
}
-int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem)
+/**
+ * \brief Get info about channels of capture stream of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel Mixer simple element channel identificator
+ * \return 0 if channel is not present, 1 if present
+ */
+int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_PSWITCH);
+ return (unsigned int) channel < s->str[CAPT].channels;
}
-int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem)
+/**
+ * \brief Get range for capture volume of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param min Pointer to returned minimum
+ * \param max Pointer to returned maximum
+ */
+void snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem,
+ long *min, long *max)
{
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- return !!(s->caps & CAP_PSWITCH_JOIN);
+ *min = s->str[CAPT].min;
+ *max = s->str[CAPT].max;
+}
+
+/**
+ * \brief Set range for capture volume of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param min minimum volume value
+ * \param max maximum volume value
+ */
+void snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem,
+ long min, long max)
+{
+ selem_t *s;
+ assert(elem);
+ assert(elem->type == SND_MIXER_ELEM_SIMPLE);
+ s = elem->private_data;
+ assert(min != max);
+ s->str[CAPT].range = 1;
+ s->str[CAPT].min = min;
+ s->str[CAPT].max = max;
+}
+
+/**
+ * \brief Return info about capture volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if no control is present, 1 if it's present
+ */
+int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem)
+{
+ selem_t *s;
+ assert(elem);
+ assert(elem->type == SND_MIXER_ELEM_SIMPLE);
+ s = elem->private_data;
+ return !!(s->caps & CAP_CVOLUME);
}
+/**
+ * \brief Return info about capture volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if control is separated per channel, 1 if control acts on all channels together
+ */
+int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem)
+{
+ selem_t *s;
+ assert(elem);
+ assert(elem->type == SND_MIXER_ELEM_SIMPLE);
+ s = elem->private_data;
+ return !!(s->caps & CAP_CVOLUME_JOIN);
+}
+
+/**
+ * \brief Return info about capture switch control existence of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if no control is present, 1 if it's present
+ */
int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem)
{
selem_t *s;
@@ -1096,6 +1460,11 @@ int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem)
return !!(s->caps & CAP_CSWITCH);
}
+/**
+ * \brief Return info about capture switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if control is separated per channel, 1 if control acts on all channels together
+ */
int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem)
{
selem_t *s;
@@ -1105,6 +1474,11 @@ int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem)
return !!(s->caps & CAP_CSWITCH_JOIN);
}
+/**
+ * \brief Return info about capture switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return 0 if control is separated per element, 1 if control acts on other elements too (i.e. only one active at a time inside a group)
+ */
int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem)
{
selem_t *s;
@@ -1114,24 +1488,28 @@ int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem)
return !!(s->caps & CAP_CSWITCH_EXCL);
}
-int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
+/**
+ * \brief Return info about capture switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \return group for switch exclusivity (see #snd_mixer_selem_has_capture_switch_exclusive)
+ */
+int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem)
{
- int err;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- assert((unsigned int) channel < s->str[PLAY].channels);
- assert(s->caps & CAP_PVOLUME);
- err = snd_mixer_handle_events(elem->class->mixer);
- if (err < 0)
- return err;
- if (s->caps & CAP_PVOLUME_JOIN)
- channel = 0;
- *value = s->str[PLAY].vol[channel];
- return 0;
+ assert(s->caps & CAP_CSWITCH_EXCL);
+ return s->capture_group;
}
+/**
+ * \brief Return value of capture volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value pointer to returned value
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
{
int err;
@@ -1150,24 +1528,13 @@ int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_c
return 0;
}
-int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
-{
- int err;
- selem_t *s;
- assert(elem);
- assert(elem->type == SND_MIXER_ELEM_SIMPLE);
- s = elem->private_data;
- assert((unsigned int) channel < s->str[PLAY].channels);
- assert(s->caps & CAP_PSWITCH);
- err = snd_mixer_handle_events(elem->class->mixer);
- if (err < 0)
- return err;
- if (s->caps & CAP_PSWITCH_JOIN)
- channel = 0;
- *value = !!(s->str[PLAY].sw & (1 << channel));
- return 0;
-}
-
+/**
+ * \brief Return value of capture switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value pointer to returned value
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
{
int err;
@@ -1186,37 +1553,13 @@ int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_c
return 0;
}
-static int _snd_mixer_selem_set_volume(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value)
-{
- selem_t *s = elem->private_data;
- assert((unsigned int) channel < s->str[dir].channels);
- assert(value >= s->str[dir].min && value <= s->str[dir].max);
- if (s->caps &
- (dir == PLAY ? CAP_PVOLUME_JOIN : CAP_CVOLUME_JOIN))
- channel = 0;
- if (value != s->str[dir].vol[channel]) {
- s->str[dir].vol[channel] = value;
- return 1;
- }
- return 0;
-}
-
-int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
-{
- int changed;
- selem_t *s;
- assert(elem);
- assert(elem->type == SND_MIXER_ELEM_SIMPLE);
- s = elem->private_data;
- assert(s->caps & CAP_PVOLUME);
- changed = _snd_mixer_selem_set_volume(elem, PLAY, channel, value);
- if (changed < 0)
- return changed;
- if (changed)
- return selem_write(elem);
- return 0;
-}
-
+/**
+ * \brief Set value of capture volume control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
{
int changed;
@@ -1233,37 +1576,12 @@ int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_c
return 0;
}
-static int _snd_mixer_selem_set_volume_all(snd_mixer_elem_t *elem, int dir, long value)
-{
- int changed = 0;
- snd_mixer_selem_channel_id_t channel;
- selem_t *s = elem->private_data;
- assert(value >= s->str[dir].min && value <= s->str[dir].max);
- for (channel = 0; (unsigned int) channel < s->str[dir].channels; channel++) {
- if (value != s->str[dir].vol[channel]) {
- s->str[dir].vol[channel] = value;
- changed = 1;
- }
- }
- return changed;
-}
-
-int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value)
-{
- int changed;
- selem_t *s;
- assert(elem);
- assert(elem->type == SND_MIXER_ELEM_SIMPLE);
- s = elem->private_data;
- assert(s->caps & CAP_PVOLUME);
- changed = _snd_mixer_selem_set_volume_all(elem, PLAY, value);
- if (changed < 0)
- return changed;
- if (changed)
- return selem_write(elem);
- return 0;
-}
-
+/**
+ * \brief Set value of capture volume control for all channels of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value)
{
int changed;
@@ -1280,36 +1598,22 @@ int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value)
return 0;
}
-static int _snd_mixer_selem_set_switch(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value)
-{
- selem_t *s = elem->private_data;
- assert((unsigned int) channel < s->str[dir].channels);
- if (s->caps &
- (dir == PLAY ? CAP_PSWITCH_JOIN : CAP_CSWITCH_JOIN))
- channel = 0;
- if (value) {
- if (!(s->str[dir].sw & (1 << channel))) {
- s->str[dir].sw |= 1 << channel;
- return 1;
- }
- } else {
- if (s->str[dir].sw & (1 << channel)) {
- s->str[dir].sw &= ~(1 << channel);
- return 1;
- }
- }
- return 0;
-}
-
-int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
+/**
+ * \brief Set value of capture switch control of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param channel mixer simple element channel identificator
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
{
int changed;
selem_t *s;
assert(elem);
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
- assert(s->caps & CAP_PSWITCH);
- changed = _snd_mixer_selem_set_switch(elem, PLAY, channel, value);
+ assert(s->caps & CAP_CSWITCH);
+ changed = _snd_mixer_selem_set_switch(elem, CAPT, channel, value);
if (changed < 0)
return changed;
if (changed)
@@ -1317,7 +1621,13 @@ int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_
return 0;
}
-int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
+/**
+ * \brief Set value of capture switch control for all channels of a mixer simple element
+ * \param elem Mixer simple element handle
+ * \param value control value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value)
{
int changed;
selem_t *s;
@@ -1325,7 +1635,7 @@ int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_c
assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private_data;
assert(s->caps & CAP_CSWITCH);
- changed = _snd_mixer_selem_set_switch(elem, CAPT, channel, value);
+ changed = _snd_mixer_selem_set_switch_all(elem, CAPT, value);
if (changed < 0)
return changed;
if (changed)
@@ -1333,96 +1643,90 @@ int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_c
return 0;
}
-static int _snd_mixer_selem_set_switch_all(snd_mixer_elem_t *elem, int dir, int value)
+/**
+ * \brief get size of #snd_mixer_selem_id_t
+ * \return size in bytes
+ */
+size_t snd_mixer_selem_id_sizeof()
{
- selem_t *s = elem->private_data;
- if (value) {
- if (s->str[dir].sw != ~0U) {
- s->str[dir].sw = ~0U;
- return 1;
- }
- } else {
- if (s->str[dir].sw != 0U) {
- s->str[dir].sw = 0U;
- return 1;
- }
- }
- return 0;
+ return sizeof(snd_mixer_selem_id_t);
}
-int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value)
+/**
+ * \brief allocate an invalid #snd_mixer_selem_id_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr)
{
- int changed;
- selem_t *s;
- assert(elem);
- assert(elem->type == SND_MIXER_ELEM_SIMPLE);
- s = elem->private_data;
- assert(s->caps & CAP_PSWITCH);
- changed = _snd_mixer_selem_set_switch_all(elem, PLAY, value);
- if (changed < 0)
- return changed;
- if (changed)
- return selem_write(elem);
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_mixer_selem_id_t));
+ if (!*ptr)
+ return -ENOMEM;
return 0;
}
-int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value)
+/**
+ * \brief frees a previously allocated #snd_mixer_selem_id_t
+ * \param pointer to object to free
+ */
+void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj)
{
- int changed;
- selem_t *s;
- assert(elem);
- assert(elem->type == SND_MIXER_ELEM_SIMPLE);
- s = elem->private_data;
- assert(s->caps & CAP_CSWITCH);
- changed = _snd_mixer_selem_set_switch_all(elem, CAPT, value);
- if (changed < 0)
- return changed;
- if (changed)
- return selem_write(elem);
- return 0;
+ free(obj);
}
-const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel)
+/**
+ * \brief copy one #snd_mixer_selem_id_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src)
{
- static const char *array[snd_enum_to_int(SND_MIXER_SCHN_LAST) + 1] = {
- [SND_MIXER_SCHN_FRONT_LEFT] = "Front Left",
- [SND_MIXER_SCHN_FRONT_RIGHT] = "Front Right",
- [SND_MIXER_SCHN_FRONT_CENTER] = "Front Center",
- [SND_MIXER_SCHN_REAR_LEFT] = "Rear Left",
- [SND_MIXER_SCHN_REAR_RIGHT] = "Rear Right",
- [SND_MIXER_SCHN_WOOFER] = "Woofer"
- };
- const char *p;
- assert(channel <= SND_MIXER_SCHN_LAST);
- p = array[snd_enum_to_int(channel)];
- if (!p)
- return "?";
- return p;
+ assert(dst && src);
+ *dst = *src;
}
-void snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem,
- long min, long max)
+/**
+ * \brief Get name part of a mixer simple element identificator
+ * \param obj Mixer simple element identificator
+ * \return name part
+ */
+const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj)
{
- selem_t *s;
- assert(elem);
- assert(elem->type == SND_MIXER_ELEM_SIMPLE);
- s = elem->private_data;
- assert(min != max);
- s->str[PLAY].range = 1;
- s->str[PLAY].min = min;
- s->str[PLAY].max = max;
+ assert(obj);
+ return obj->name;
}
-void snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem,
- long min, long max)
+/**
+ * \brief Get index part of a mixer simple element identificator
+ * \param obj Mixer simple element identificator
+ * \return index part
+ */
+unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj)
{
- selem_t *s;
- assert(elem);
- assert(elem->type == SND_MIXER_ELEM_SIMPLE);
- s = elem->private_data;
- assert(min != max);
- s->str[CAPT].range = 1;
- s->str[CAPT].min = min;
- s->str[CAPT].max = max;
+ assert(obj);
+ return obj->index;
+}
+
+/**
+ * \brief Set name part of a mixer simple element identificator
+ * \param obj Mixer simple element identificator
+ * \param val name part
+ */
+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));
+}
+
+/**
+ * \brief Set index part of a mixer simple element identificator
+ * \param obj Mixer simple element identificator
+ * \param val index part
+ */
+void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val)
+{
+ assert(obj);
+ obj->index = val;
}