3 * \brief Mixer Simple Element Class Interface
4 * \author Jaroslav Kysela <perex@perex.cz>
5 * \author Abramo Bagnara <abramo@alsa-project.org>
8 * Mixer simple element class interface.
11 * Mixer Interface - simple controls
12 * Copyright (c) 2000,2004 by Jaroslav Kysela <perex@perex.cz>
13 * Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
16 * This library is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU Lesser General Public License as
18 * published by the Free Software Foundation; either version 2.1 of
19 * the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #include <sys/ioctl.h>
39 #include "mixer_local.h"
40 #include "mixer_simple.h"
43 * \brief Register mixer simple element class
44 * \param mixer Mixer handle
45 * \param options Options container
46 * \param classp Pointer to returned mixer simple element class handle (or NULL)
47 * \return 0 on success otherwise a negative error code
49 int snd_mixer_selem_register(snd_mixer_t *mixer,
50 struct snd_mixer_selem_regopt *options,
51 snd_mixer_class_t **classp)
53 if (options && options->ver == 1) {
54 if (options->device != NULL &&
55 (options->playback_pcm != NULL ||
56 options->capture_pcm != NULL))
58 if (options->device == NULL &&
59 options->playback_pcm == NULL &&
60 options->capture_pcm == NULL)
63 if (options == NULL ||
64 (options->ver == 1 && options->abstract == SND_MIXER_SABSTRACT_NONE)) {
65 int err = snd_mixer_simple_none_register(mixer, options, classp);
68 if (options != NULL) {
69 err = snd_mixer_attach(mixer, options->device);
74 } else if (options->ver == 1) {
75 if (options->abstract == SND_MIXER_SABSTRACT_BASIC)
76 return snd_mixer_simple_basic_register(mixer, options, classp);
83 #define CHECK_BASIC(xelem) \
86 assert((xelem)->type == SND_MIXER_ELEM_SIMPLE); \
89 #define CHECK_DIR(xelem, xwhat) \
91 unsigned int xcaps = ((sm_selem_t *)(elem)->private_data)->caps; \
92 if (! (xcaps & (xwhat))) \
96 #define CHECK_DIR_CHN(xelem, xwhat, xjoin, xchannel) \
98 unsigned int xcaps = ((sm_selem_t *)(elem)->private_data)->caps; \
99 if (! (xcaps & (xwhat))) \
101 if (xcaps & (xjoin)) \
105 #define CHECK_ENUM(xelem) \
106 if (!((sm_selem_t *)(elem)->private_data)->caps & (SM_CAP_PENUM|SM_CAP_CENUM)) \
109 #define COND_CAPS(xelem, what) \
110 !!(((sm_selem_t *)(elem)->private_data)->caps & (what))
112 #endif /* !DOC_HIDDEN */
115 int snd_mixer_selem_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2)
117 sm_selem_t *s1 = c1->private_data;
118 sm_selem_t *s2 = c2->private_data;
119 int res = strcmp(s1->id->name, s2->id->name);
122 return s1->id->index - s2->id->index;
127 * \brief Find a mixer simple element
128 * \param mixer Mixer handle
129 * \param id Mixer simple element identifier
130 * \return mixer simple element handle or NULL if not found
132 snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer,
133 const snd_mixer_selem_id_t *id)
135 struct list_head *list;
139 list_for_each(list, &mixer->elems) {
140 e = list_entry(list, snd_mixer_elem_t, list);
141 if (e->type != SND_MIXER_ELEM_SIMPLE)
144 if (!strcmp(s->id->name, id->name) && s->id->index == id->index)
151 * \brief Get mixer simple element identifier
152 * \param elem Mixer simple element handle
153 * \param id returned mixer simple element identifier
155 void snd_mixer_selem_get_id(snd_mixer_elem_t *elem,
156 snd_mixer_selem_id_t *id)
161 s = elem->private_data;
166 * \brief Get name part of mixer simple element identifier
167 * \param elem Mixer simple element handle
168 * \return name part of simple element identifier
170 const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem)
174 s = elem->private_data;
179 * \brief Get index part of mixer simple element identifier
180 * \param elem Mixer simple element handle
181 * \return index part of simple element identifier
183 unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem)
187 s = elem->private_data;
192 * \brief Return true if mixer simple element has only one volume control for both playback and capture
193 * \param elem Mixer simple element handle
194 * \return 0 separated control, 1 common control
196 int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem)
199 return COND_CAPS(elem, SM_CAP_GVOLUME);
203 * \brief Return true if mixer simple element has only one switch control for both playback and capture
204 * \param elem Mixer simple element handle
205 * \return 0 separated control, 1 common control
207 int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem)
210 return COND_CAPS(elem, SM_CAP_GSWITCH);
214 * \brief Return name of mixer simple element channel
215 * \param channel mixer simple element channel identifier
216 * \return channel name
218 const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel)
220 static const char *array[SND_MIXER_SCHN_LAST + 1] = {
221 [SND_MIXER_SCHN_FRONT_LEFT] = "Front Left",
222 [SND_MIXER_SCHN_FRONT_RIGHT] = "Front Right",
223 [SND_MIXER_SCHN_REAR_LEFT] = "Rear Left",
224 [SND_MIXER_SCHN_REAR_RIGHT] = "Rear Right",
225 [SND_MIXER_SCHN_FRONT_CENTER] = "Front Center",
226 [SND_MIXER_SCHN_WOOFER] = "Woofer",
227 [SND_MIXER_SCHN_SIDE_LEFT] = "Side Left",
228 [SND_MIXER_SCHN_SIDE_RIGHT] = "Side Right",
229 [SND_MIXER_SCHN_REAR_CENTER] = "Rear Center"
232 assert(channel <= SND_MIXER_SCHN_LAST);
240 * \brief Get info about the active state of a mixer simple element
241 * \param elem Mixer simple element handle
242 * \return 0 if not active, 1 if active
244 int snd_mixer_selem_is_active(snd_mixer_elem_t *elem)
247 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ACTIVE, 0);
251 * \brief Get info about channels of playback stream of a mixer simple element
252 * \param elem Mixer simple element handle
253 * \return 0 if not mono, 1 if mono
255 int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem)
258 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_MONO, 0);
262 * \brief Get info about channels of playback stream of a mixer simple element
263 * \param elem Mixer simple element handle
264 * \param channel Mixer simple element channel identifier
265 * \return 0 if channel is not present, 1 if present
267 int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
270 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_CHANNEL, (int)channel);
274 * \brief Get range for playback volume of a mixer simple element
275 * \param elem Mixer simple element handle
276 * \param min Pointer to returned minimum
277 * \param max Pointer to returned maximum
279 int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem,
280 long *min, long *max)
283 CHECK_DIR(elem, SM_CAP_PVOLUME);
284 return sm_selem_ops(elem)->get_range(elem, SM_PLAY, min, max);
288 * \brief Get range in dB for playback volume of a mixer simple element
289 * \param elem Mixer simple element handle
290 * \param min Pointer to returned minimum (dB * 100)
291 * \param max Pointer to returned maximum (dB * 100)
293 int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem,
294 long *min, long *max)
297 CHECK_DIR(elem, SM_CAP_PVOLUME);
298 return sm_selem_ops(elem)->get_dB_range(elem, SM_PLAY, min, max);
302 * \brief Set range for playback volume of a mixer simple element
303 * \param elem Mixer simple element handle
304 * \param min minimum volume value
305 * \param max maximum volume value
307 int snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem,
312 CHECK_DIR(elem, SM_CAP_PVOLUME);
313 return sm_selem_ops(elem)->set_range(elem, SM_PLAY, min, max);
317 * \brief Return info about playback volume control of a mixer simple element
318 * \param elem Mixer simple element handle
319 * \return 0 if no control is present, 1 if it's present
321 int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem)
324 return COND_CAPS(elem, SM_CAP_PVOLUME);
328 * \brief Return info about playback volume control of a mixer simple element
329 * \param elem Mixer simple element handle
330 * \return 0 if control is separated per channel, 1 if control acts on all channels together
332 int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem)
335 return COND_CAPS(elem, SM_CAP_PVOLUME_JOIN);
339 * \brief Return info about playback switch control existence of a mixer simple element
340 * \param elem Mixer simple element handle
341 * \return 0 if no control is present, 1 if it's present
343 int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem)
346 return COND_CAPS(elem, SM_CAP_PSWITCH);
350 * \brief Return info about playback switch control of a mixer simple element
351 * \param elem Mixer simple element handle
352 * \return 0 if control is separated per channel, 1 if control acts on all channels together
354 int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem)
357 return COND_CAPS(elem, SM_CAP_PSWITCH_JOIN);
361 * \brief Return value of playback volume control of a mixer simple element
362 * \param elem Mixer simple element handle
363 * \param channel mixer simple element channel identifier
364 * \param value pointer to returned value
365 * \return 0 on success otherwise a negative error code
367 int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
370 CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
371 return sm_selem_ops(elem)->get_volume(elem, SM_PLAY, channel, value);
375 * \brief Return value of playback volume in dB control of a mixer simple element
376 * \param elem Mixer simple element handle
377 * \param channel mixer simple element channel identifier
378 * \param value pointer to returned value (dB * 100)
379 * \return 0 on success otherwise a negative error code
381 int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
386 caps = ((sm_selem_t *)elem->private_data)->caps;
387 if (!(caps & SM_CAP_PVOLUME))
389 if (caps & SM_CAP_PVOLUME_JOIN)
391 return sm_selem_ops(elem)->get_dB(elem, SM_PLAY, channel, value);
395 * \brief Return value of playback switch control of a mixer simple element
396 * \param elem Mixer simple element handle
397 * \param channel mixer simple element channel identifier
398 * \param value pointer to returned value
399 * \return 0 on success otherwise a negative error code
401 int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
404 CHECK_DIR_CHN(elem, SM_CAP_PSWITCH, SM_CAP_PSWITCH_JOIN, channel);
405 return sm_selem_ops(elem)->get_switch(elem, SM_PLAY, channel, value);
409 * \brief Set value of playback volume control of a mixer simple element
410 * \param elem Mixer simple element handle
411 * \param channel mixer simple element channel identifier
412 * \param value control value
413 * \return 0 on success otherwise a negative error code
415 int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
418 CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
419 return sm_selem_ops(elem)->set_volume(elem, SM_PLAY, channel, value);
423 * \brief Set value in dB of playback volume control of a mixer simple element
424 * \param elem Mixer simple element handle
425 * \param channel mixer simple element channel identifier
426 * \param value control value in dB * 100
427 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
428 * \return 0 on success otherwise a negative error code
430 int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
433 CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
434 return sm_selem_ops(elem)->set_dB(elem, SM_PLAY, channel, value, dir);
438 * \brief Set value of playback volume control for all channels of a mixer simple element
439 * \param elem Mixer simple element handle
440 * \param value control value
441 * \return 0 on success otherwise a negative error code
443 int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value)
445 snd_mixer_selem_channel_id_t chn;
448 for (chn = 0; chn < 32; chn++) {
449 if (!snd_mixer_selem_has_playback_channel(elem, chn))
451 err = snd_mixer_selem_set_playback_volume(elem, chn, value);
454 if (chn == 0 && snd_mixer_selem_has_playback_volume_joined(elem))
461 * \brief Set value in dB of playback volume control for all channels of a mixer simple element
462 * \param elem Mixer simple element handle
463 * \param value control value in dB * 100
464 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
465 * \return 0 on success otherwise a negative error code
467 int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir)
469 snd_mixer_selem_channel_id_t chn;
472 for (chn = 0; chn < 32; chn++) {
473 if (!snd_mixer_selem_has_playback_channel(elem, chn))
475 err = snd_mixer_selem_set_playback_dB(elem, chn, value, dir);
478 if (chn == 0 && snd_mixer_selem_has_playback_volume_joined(elem))
485 * \brief Set value of playback switch control of a mixer simple element
486 * \param elem Mixer simple element handle
487 * \param channel mixer simple element channel identifier
488 * \param value control value
489 * \return 0 on success otherwise a negative error code
491 int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
494 CHECK_DIR_CHN(elem, SM_CAP_PSWITCH, SM_CAP_PSWITCH_JOIN, channel);
495 return sm_selem_ops(elem)->set_switch(elem, SM_PLAY, channel, value);
499 * \brief Set value of playback switch control for all channels of a mixer simple element
500 * \param elem Mixer simple element handle
501 * \param value control value
502 * \return 0 on success otherwise a negative error code
504 int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value)
506 snd_mixer_selem_channel_id_t chn;
510 for (chn = 0; chn < 32; chn++) {
511 if (!snd_mixer_selem_has_playback_channel(elem, chn))
513 err = snd_mixer_selem_set_playback_switch(elem, chn, value);
516 if (chn == 0 && snd_mixer_selem_has_playback_switch_joined(elem))
523 * \brief Get info about channels of capture stream of a mixer simple element
524 * \param elem Mixer simple element handle
525 * \return 0 if not mono, 1 if mono
527 int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem)
530 CHECK_DIR(elem, SM_CAP_CVOLUME|SM_CAP_CSWITCH);
531 return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_MONO, 0);
535 * \brief Get info about channels of capture stream of a mixer simple element
536 * \param elem Mixer simple element handle
537 * \param channel Mixer simple element channel identifier
538 * \return 0 if channel is not present, 1 if present
540 int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
543 CHECK_DIR(elem, SM_CAP_CVOLUME|SM_CAP_CSWITCH);
544 return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_CHANNEL, channel);
548 * \brief Get range for capture volume of a mixer simple element
549 * \param elem Mixer simple element handle
550 * \param min Pointer to returned minimum
551 * \param max Pointer to returned maximum
553 int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem,
554 long *min, long *max)
557 CHECK_DIR(elem, SM_CAP_CVOLUME);
558 return sm_selem_ops(elem)->get_range(elem, SM_CAPT, min, max);
562 * \brief Get range in dB for capture volume of a mixer simple element
563 * \param elem Mixer simple element handle
564 * \param min Pointer to returned minimum (dB * 100)
565 * \param max Pointer to returned maximum (dB * 100)
567 int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem,
568 long *min, long *max)
571 CHECK_DIR(elem, SM_CAP_CVOLUME);
572 return sm_selem_ops(elem)->get_dB_range(elem, SM_CAPT, min, max);
576 * \brief Set range for capture volume of a mixer simple element
577 * \param elem Mixer simple element handle
578 * \param min minimum volume value
579 * \param max maximum volume value
581 int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem,
586 CHECK_DIR(elem, SM_CAP_CVOLUME);
587 return sm_selem_ops(elem)->set_range(elem, SM_CAPT, min, max);
591 * \brief Return info about capture volume control of a mixer simple element
592 * \param elem Mixer simple element handle
593 * \return 0 if no control is present, 1 if it's present
595 int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem)
598 return COND_CAPS(elem, SM_CAP_CVOLUME);
602 * \brief Return info about capture volume control of a mixer simple element
603 * \param elem Mixer simple element handle
604 * \return 0 if control is separated per channel, 1 if control acts on all channels together
606 int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem)
609 return COND_CAPS(elem, SM_CAP_CVOLUME_JOIN);
613 * \brief Return info about capture switch control existence of a mixer simple element
614 * \param elem Mixer simple element handle
615 * \return 0 if no control is present, 1 if it's present
617 int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem)
620 return COND_CAPS(elem, SM_CAP_CSWITCH);
624 * \brief Return info about capture switch control of a mixer simple element
625 * \param elem Mixer simple element handle
626 * \return 0 if control is separated per channel, 1 if control acts on all channels together
628 int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem)
631 return COND_CAPS(elem, SM_CAP_CSWITCH_JOIN);
635 * \brief Return info about capture switch control of a mixer simple element
636 * \param elem Mixer simple element handle
637 * \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)
639 int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem)
642 return COND_CAPS(elem, SM_CAP_CSWITCH_EXCL);
646 * \brief Return info about capture switch control of a mixer simple element
647 * \param elem Mixer simple element handle
648 * \return group for switch exclusivity (see #snd_mixer_selem_has_capture_switch_exclusive)
650 int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem)
654 s = elem->private_data;
655 if (! (s->caps & SM_CAP_CSWITCH_EXCL))
657 return s->capture_group;
661 * \brief Return value of capture volume control of a mixer simple element
662 * \param elem Mixer simple element handle
663 * \param channel mixer simple element channel identifier
664 * \param value pointer to returned value
665 * \return 0 on success otherwise a negative error code
667 int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
670 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
671 return sm_selem_ops(elem)->get_volume(elem, SM_CAPT, channel, value);
675 * \brief Return value of capture volume in dB control of a mixer simple element
676 * \param elem Mixer simple element handle
677 * \param channel mixer simple element channel identifier
678 * \param value pointer to returned value (dB * 100)
679 * \return 0 on success otherwise a negative error code
681 int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
684 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
685 return sm_selem_ops(elem)->get_dB(elem, SM_CAPT, channel, value);
689 * \brief Return value of capture switch control of a mixer simple element
690 * \param elem Mixer simple element handle
691 * \param channel mixer simple element channel identifier
692 * \param value pointer to returned value
693 * \return 0 on success otherwise a negative error code
695 int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
698 CHECK_DIR_CHN(elem, SM_CAP_CSWITCH, SM_CAP_CSWITCH_JOIN, channel);
699 return sm_selem_ops(elem)->get_switch(elem, SM_CAPT, channel, value);
703 * \brief Set value of capture volume control of a mixer simple element
704 * \param elem Mixer simple element handle
705 * \param channel mixer simple element channel identifier
706 * \param value control value
707 * \return 0 on success otherwise a negative error code
709 int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
712 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
713 return sm_selem_ops(elem)->set_volume(elem, SM_CAPT, channel, value);
717 * \brief Set value in dB of capture volume control of a mixer simple element
718 * \param elem Mixer simple element handle
719 * \param channel mixer simple element channel identifier
720 * \param value control value in dB * 100
721 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
722 * \return 0 on success otherwise a negative error code
724 int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
727 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
728 return sm_selem_ops(elem)->set_dB(elem, SM_CAPT, channel, value, dir);
732 * \brief Set value of capture volume control for all channels of a mixer simple element
733 * \param elem Mixer simple element handle
734 * \param value control value
735 * \return 0 on success otherwise a negative error code
737 int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value)
739 snd_mixer_selem_channel_id_t chn;
742 for (chn = 0; chn < 32; chn++) {
743 if (!snd_mixer_selem_has_capture_channel(elem, chn))
745 err = snd_mixer_selem_set_capture_volume(elem, chn, value);
748 if (chn == 0 && snd_mixer_selem_has_capture_volume_joined(elem))
755 * \brief Set value in dB of capture volume control for all channels of a mixer simple element
756 * \param elem Mixer simple element handle
757 * \param value control value in dB * 100
758 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
759 * \return 0 on success otherwise a negative error code
761 int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir)
763 snd_mixer_selem_channel_id_t chn;
766 for (chn = 0; chn < 32; chn++) {
767 if (!snd_mixer_selem_has_capture_channel(elem, chn))
769 err = snd_mixer_selem_set_capture_dB(elem, chn, value, dir);
772 if (chn == 0 && snd_mixer_selem_has_capture_volume_joined(elem))
779 * \brief Set value of capture switch control of a mixer simple element
780 * \param elem Mixer simple element handle
781 * \param channel mixer simple element channel identifier
782 * \param value control value
783 * \return 0 on success otherwise a negative error code
785 int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
788 CHECK_DIR_CHN(elem, SM_CAP_CSWITCH, SM_CAP_CSWITCH_JOIN, channel);
789 return sm_selem_ops(elem)->set_switch(elem, SM_CAPT, channel, value);
793 * \brief Set value of capture switch control for all channels of a mixer simple element
794 * \param elem Mixer simple element handle
795 * \param value control value
796 * \return 0 on success otherwise a negative error code
798 int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value)
800 snd_mixer_selem_channel_id_t chn;
803 for (chn = 0; chn < 32; chn++) {
804 if (!snd_mixer_selem_has_capture_channel(elem, chn))
806 err = snd_mixer_selem_set_capture_switch(elem, chn, value);
809 if (chn == 0 && snd_mixer_selem_has_capture_switch_joined(elem))
816 * \brief Return true if mixer simple element is an enumerated control
817 * \param elem Mixer simple element handle
818 * \return 0 normal volume/switch control, 1 enumerated control
820 int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem)
824 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMERATED, 0);
828 * \brief Return true if mixer simple enumerated element belongs to the playback direction
829 * \param elem Mixer simple element handle
830 * \return 0 no playback direction, 1 playback direction
832 int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem)
836 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMERATED, 1);
840 * \brief Return true if mixer simple enumerated element belongs to the capture direction
841 * \param elem Mixer simple element handle
842 * \return 0 no capture direction, 1 capture direction
844 int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem)
848 return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_ENUMERATED, 1);
852 * \brief Return the number of enumerated items of the given mixer simple element
853 * \param elem Mixer simple element handle
854 * \return the number of enumerated items, otherwise a negative error code
856 int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem)
860 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMCNT, 0);
864 * \brief get the enumerated item string for the given mixer simple element
865 * \param elem Mixer simple element handle
866 * \param item the index of the enumerated item to query
867 * \param maxlen the maximal length to be stored
868 * \param buf the buffer to store the name string
869 * \return 0 if successful, otherwise a negative error code
871 int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem,
873 size_t maxlen, char *buf)
877 return sm_selem_ops(elem)->enum_item_name(elem, item, maxlen, buf);
881 * \brief get the current selected enumerated item for the given mixer simple element
882 * \param elem Mixer simple element handle
883 * \param channel mixer simple element channel identifier
884 * \param itemp the pointer to store the index of the enumerated item
885 * \return 0 if successful, otherwise a negative error code
887 int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem,
888 snd_mixer_selem_channel_id_t channel,
893 return sm_selem_ops(elem)->get_enum_item(elem, channel, itemp);
897 * \brief set the current selected enumerated item for the given mixer simple element
898 * \param elem Mixer simple element handle
899 * \param channel mixer simple element channel identifier
900 * \param item the enumerated item index
901 * \return 0 if successful, otherwise a negative error code
903 int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem,
904 snd_mixer_selem_channel_id_t channel,
909 return sm_selem_ops(elem)->set_enum_item(elem, channel, item);
913 * \brief get size of #snd_mixer_selem_id_t
914 * \return size in bytes
916 size_t snd_mixer_selem_id_sizeof()
918 return sizeof(snd_mixer_selem_id_t);
922 * \brief allocate an invalid #snd_mixer_selem_id_t using standard malloc
923 * \param ptr returned pointer
924 * \return 0 on success otherwise negative error code
926 int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr)
929 *ptr = calloc(1, sizeof(snd_mixer_selem_id_t));
936 * \brief frees a previously allocated #snd_mixer_selem_id_t
937 * \param obj pointer to object to free
939 void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj)
945 * \brief copy one #snd_mixer_selem_id_t to another
946 * \param dst pointer to destination
947 * \param src pointer to source
949 void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src)
956 * \brief Get name part of a mixer simple element identifier
957 * \param obj Mixer simple element identifier
960 const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj)
967 * \brief Get index part of a mixer simple element identifier
968 * \param obj Mixer simple element identifier
971 unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj)
978 * \brief Set name part of a mixer simple element identifier
979 * \param obj Mixer simple element identifier
980 * \param val name part
982 void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val)
985 strncpy(obj->name, val, sizeof(obj->name));
986 obj->name[sizeof(obj->name)-1] = '\0';
990 * \brief Set index part of a mixer simple element identifier
991 * \param obj Mixer simple element identifier
992 * \param val index part
994 void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val)