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 *const 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 corresponding dB value to an integer playback volume for a mixer simple element
362 * \param elem Mixer simple element handle
363 * \param value value to be converted to dB range
364 * \param dBvalue pointer to returned dB value
365 * \return 0 on success otherwise a negative error code
367 int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
370 CHECK_DIR(elem, SM_CAP_PVOLUME);
371 return sm_selem_ops(elem)->ask_vol_dB(elem, SM_PLAY, value, dBvalue);
375 * \brief Return corresponding integer playback volume for given dB value for a mixer simple element
376 * \param elem Mixer simple element handle
377 * \param value value to be converted to dB range
378 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
379 * \param dBvalue pointer to returned dB value
380 * \return 0 on success otherwise a negative error code
382 int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
385 CHECK_DIR(elem, SM_CAP_PVOLUME);
386 return sm_selem_ops(elem)->ask_dB_vol(elem, SM_PLAY, dBvalue, value, dir);
390 * \brief Return value of playback volume control of a mixer simple element
391 * \param elem Mixer simple element handle
392 * \param channel mixer simple element channel identifier
393 * \param value pointer to returned value
394 * \return 0 on success otherwise a negative error code
396 int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
399 CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
400 return sm_selem_ops(elem)->get_volume(elem, SM_PLAY, channel, value);
404 * \brief Return value of playback volume in dB control of a mixer simple element
405 * \param elem Mixer simple element handle
406 * \param channel mixer simple element channel identifier
407 * \param value pointer to returned value (dB * 100)
408 * \return 0 on success otherwise a negative error code
410 int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
415 caps = ((sm_selem_t *)elem->private_data)->caps;
416 if (!(caps & SM_CAP_PVOLUME))
418 if (caps & SM_CAP_PVOLUME_JOIN)
420 return sm_selem_ops(elem)->get_dB(elem, SM_PLAY, channel, value);
424 * \brief Return value of playback switch control of a mixer simple element
425 * \param elem Mixer simple element handle
426 * \param channel mixer simple element channel identifier
427 * \param value pointer to returned value
428 * \return 0 on success otherwise a negative error code
430 int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
433 CHECK_DIR_CHN(elem, SM_CAP_PSWITCH, SM_CAP_PSWITCH_JOIN, channel);
434 return sm_selem_ops(elem)->get_switch(elem, SM_PLAY, channel, value);
438 * \brief Set value of playback volume control of a mixer simple element
439 * \param elem Mixer simple element handle
440 * \param channel mixer simple element channel identifier
441 * \param value control value
442 * \return 0 on success otherwise a negative error code
444 int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
447 CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
448 return sm_selem_ops(elem)->set_volume(elem, SM_PLAY, channel, value);
452 * \brief Set value in dB of playback volume control of a mixer simple element
453 * \param elem Mixer simple element handle
454 * \param channel mixer simple element channel identifier
455 * \param value control value in dB * 100
456 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
457 * \return 0 on success otherwise a negative error code
459 int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
462 CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
463 return sm_selem_ops(elem)->set_dB(elem, SM_PLAY, channel, value, dir);
467 * \brief Set value of playback volume control for all channels of a mixer simple element
468 * \param elem Mixer simple element handle
469 * \param value control value
470 * \return 0 on success otherwise a negative error code
472 int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value)
474 snd_mixer_selem_channel_id_t chn;
477 for (chn = 0; chn < 32; chn++) {
478 if (!snd_mixer_selem_has_playback_channel(elem, chn))
480 err = snd_mixer_selem_set_playback_volume(elem, chn, value);
483 if (chn == 0 && snd_mixer_selem_has_playback_volume_joined(elem))
490 * \brief Set value in dB of playback volume control for all channels of a mixer simple element
491 * \param elem Mixer simple element handle
492 * \param value control value in dB * 100
493 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
494 * \return 0 on success otherwise a negative error code
496 int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir)
498 snd_mixer_selem_channel_id_t chn;
501 for (chn = 0; chn < 32; chn++) {
502 if (!snd_mixer_selem_has_playback_channel(elem, chn))
504 err = snd_mixer_selem_set_playback_dB(elem, chn, value, dir);
507 if (chn == 0 && snd_mixer_selem_has_playback_volume_joined(elem))
514 * \brief Set value of playback switch control of a mixer simple element
515 * \param elem Mixer simple element handle
516 * \param channel mixer simple element channel identifier
517 * \param value control value
518 * \return 0 on success otherwise a negative error code
520 int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
523 CHECK_DIR_CHN(elem, SM_CAP_PSWITCH, SM_CAP_PSWITCH_JOIN, channel);
524 return sm_selem_ops(elem)->set_switch(elem, SM_PLAY, channel, value);
528 * \brief Set value of playback switch control for all channels of a mixer simple element
529 * \param elem Mixer simple element handle
530 * \param value control value
531 * \return 0 on success otherwise a negative error code
533 int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value)
535 snd_mixer_selem_channel_id_t chn;
539 for (chn = 0; chn < 32; chn++) {
540 if (!snd_mixer_selem_has_playback_channel(elem, chn))
542 err = snd_mixer_selem_set_playback_switch(elem, chn, value);
545 if (chn == 0 && snd_mixer_selem_has_playback_switch_joined(elem))
552 * \brief Get info about channels of capture stream of a mixer simple element
553 * \param elem Mixer simple element handle
554 * \return 0 if not mono, 1 if mono
556 int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem)
559 CHECK_DIR(elem, SM_CAP_CVOLUME|SM_CAP_CSWITCH);
560 return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_MONO, 0);
564 * \brief Get info about channels of capture stream of a mixer simple element
565 * \param elem Mixer simple element handle
566 * \param channel Mixer simple element channel identifier
567 * \return 0 if channel is not present, 1 if present
569 int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
572 CHECK_DIR(elem, SM_CAP_CVOLUME|SM_CAP_CSWITCH);
573 return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_CHANNEL, channel);
577 * \brief Get range for capture volume of a mixer simple element
578 * \param elem Mixer simple element handle
579 * \param min Pointer to returned minimum
580 * \param max Pointer to returned maximum
582 int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem,
583 long *min, long *max)
586 CHECK_DIR(elem, SM_CAP_CVOLUME);
587 return sm_selem_ops(elem)->get_range(elem, SM_CAPT, min, max);
591 * \brief Get range in dB for capture volume of a mixer simple element
592 * \param elem Mixer simple element handle
593 * \param min Pointer to returned minimum (dB * 100)
594 * \param max Pointer to returned maximum (dB * 100)
596 int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem,
597 long *min, long *max)
600 CHECK_DIR(elem, SM_CAP_CVOLUME);
601 return sm_selem_ops(elem)->get_dB_range(elem, SM_CAPT, min, max);
605 * \brief Set range for capture volume of a mixer simple element
606 * \param elem Mixer simple element handle
607 * \param min minimum volume value
608 * \param max maximum volume value
610 int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem,
615 CHECK_DIR(elem, SM_CAP_CVOLUME);
616 return sm_selem_ops(elem)->set_range(elem, SM_CAPT, min, max);
620 * \brief Return info about capture volume control of a mixer simple element
621 * \param elem Mixer simple element handle
622 * \return 0 if no control is present, 1 if it's present
624 int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem)
627 return COND_CAPS(elem, SM_CAP_CVOLUME);
631 * \brief Return info about capture volume control of a mixer simple element
632 * \param elem Mixer simple element handle
633 * \return 0 if control is separated per channel, 1 if control acts on all channels together
635 int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem)
638 return COND_CAPS(elem, SM_CAP_CVOLUME_JOIN);
642 * \brief Return info about capture switch control existence of a mixer simple element
643 * \param elem Mixer simple element handle
644 * \return 0 if no control is present, 1 if it's present
646 int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem)
649 return COND_CAPS(elem, SM_CAP_CSWITCH);
653 * \brief Return info about capture switch control of a mixer simple element
654 * \param elem Mixer simple element handle
655 * \return 0 if control is separated per channel, 1 if control acts on all channels together
657 int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem)
660 return COND_CAPS(elem, SM_CAP_CSWITCH_JOIN);
664 * \brief Return info about capture switch control of a mixer simple element
665 * \param elem Mixer simple element handle
666 * \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)
668 int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem)
671 return COND_CAPS(elem, SM_CAP_CSWITCH_EXCL);
675 * \brief Return info about capture switch control of a mixer simple element
676 * \param elem Mixer simple element handle
677 * \return group for switch exclusivity (see #snd_mixer_selem_has_capture_switch_exclusive)
679 int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem)
683 s = elem->private_data;
684 if (! (s->caps & SM_CAP_CSWITCH_EXCL))
686 return s->capture_group;
690 * \brief Return corresponding dB value to an integer capture volume for a mixer simple element
691 * \param elem Mixer simple element handle
692 * \param value value to be converted to dB range
693 * \param dBvalue pointer to returned dB value
694 * \return 0 on success otherwise a negative error code
696 int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
699 CHECK_DIR(elem, SM_CAP_CVOLUME);
700 return sm_selem_ops(elem)->ask_vol_dB(elem, SM_CAPT, value, dBvalue);
704 * \brief Return corresponding integer capture volume for given dB value for a mixer simple element
705 * \param elem Mixer simple element handle
706 * \param dBvalue dB value to be converted to integer range
707 * \param value pointer to returned integer value
708 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
709 * \return 0 on success otherwise a negative error code
711 int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
714 CHECK_DIR(elem, SM_CAP_CVOLUME);
715 return sm_selem_ops(elem)->ask_dB_vol(elem, SM_CAPT, dBvalue, value, dir);
719 * \brief Return value of capture volume control of a mixer simple element
720 * \param elem Mixer simple element handle
721 * \param channel mixer simple element channel identifier
722 * \param value pointer to returned value
723 * \return 0 on success otherwise a negative error code
725 int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
728 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
729 return sm_selem_ops(elem)->get_volume(elem, SM_CAPT, channel, value);
733 * \brief Return value of capture volume in dB control of a mixer simple element
734 * \param elem Mixer simple element handle
735 * \param channel mixer simple element channel identifier
736 * \param value pointer to returned value (dB * 100)
737 * \return 0 on success otherwise a negative error code
739 int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
742 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
743 return sm_selem_ops(elem)->get_dB(elem, SM_CAPT, channel, value);
747 * \brief Return value of capture switch control of a mixer simple element
748 * \param elem Mixer simple element handle
749 * \param channel mixer simple element channel identifier
750 * \param value pointer to returned value
751 * \return 0 on success otherwise a negative error code
753 int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
756 CHECK_DIR_CHN(elem, SM_CAP_CSWITCH, SM_CAP_CSWITCH_JOIN, channel);
757 return sm_selem_ops(elem)->get_switch(elem, SM_CAPT, channel, value);
761 * \brief Set value of capture volume control of a mixer simple element
762 * \param elem Mixer simple element handle
763 * \param channel mixer simple element channel identifier
764 * \param value control value
765 * \return 0 on success otherwise a negative error code
767 int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
770 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
771 return sm_selem_ops(elem)->set_volume(elem, SM_CAPT, channel, value);
775 * \brief Set value in dB of capture volume control of a mixer simple element
776 * \param elem Mixer simple element handle
777 * \param channel mixer simple element channel identifier
778 * \param value control value in dB * 100
779 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
780 * \return 0 on success otherwise a negative error code
782 int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
785 CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
786 return sm_selem_ops(elem)->set_dB(elem, SM_CAPT, channel, value, dir);
790 * \brief Set value of capture volume control for all channels of a mixer simple element
791 * \param elem Mixer simple element handle
792 * \param value control value
793 * \return 0 on success otherwise a negative error code
795 int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value)
797 snd_mixer_selem_channel_id_t chn;
800 for (chn = 0; chn < 32; chn++) {
801 if (!snd_mixer_selem_has_capture_channel(elem, chn))
803 err = snd_mixer_selem_set_capture_volume(elem, chn, value);
806 if (chn == 0 && snd_mixer_selem_has_capture_volume_joined(elem))
813 * \brief Set value in dB of capture volume control for all channels of a mixer simple element
814 * \param elem Mixer simple element handle
815 * \param value control value in dB * 100
816 * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above)
817 * \return 0 on success otherwise a negative error code
819 int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir)
821 snd_mixer_selem_channel_id_t chn;
824 for (chn = 0; chn < 32; chn++) {
825 if (!snd_mixer_selem_has_capture_channel(elem, chn))
827 err = snd_mixer_selem_set_capture_dB(elem, chn, value, dir);
830 if (chn == 0 && snd_mixer_selem_has_capture_volume_joined(elem))
837 * \brief Set value of capture switch control of a mixer simple element
838 * \param elem Mixer simple element handle
839 * \param channel mixer simple element channel identifier
840 * \param value control value
841 * \return 0 on success otherwise a negative error code
843 int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
846 CHECK_DIR_CHN(elem, SM_CAP_CSWITCH, SM_CAP_CSWITCH_JOIN, channel);
847 return sm_selem_ops(elem)->set_switch(elem, SM_CAPT, channel, value);
851 * \brief Set value of capture switch control for all channels of a mixer simple element
852 * \param elem Mixer simple element handle
853 * \param value control value
854 * \return 0 on success otherwise a negative error code
856 int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value)
858 snd_mixer_selem_channel_id_t chn;
861 for (chn = 0; chn < 32; chn++) {
862 if (!snd_mixer_selem_has_capture_channel(elem, chn))
864 err = snd_mixer_selem_set_capture_switch(elem, chn, value);
867 if (chn == 0 && snd_mixer_selem_has_capture_switch_joined(elem))
874 * \brief Return true if mixer simple element is an enumerated control
875 * \param elem Mixer simple element handle
876 * \return 0 normal volume/switch control, 1 enumerated control
878 int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem)
881 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMERATED, 0);
885 * \brief Return true if mixer simple enumerated element belongs to the playback direction
886 * \param elem Mixer simple element handle
887 * \return 0 no playback direction, 1 playback direction
889 int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem)
893 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMERATED, 1);
897 * \brief Return true if mixer simple enumerated element belongs to the capture direction
898 * \param elem Mixer simple element handle
899 * \return 0 no capture direction, 1 capture direction
901 int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem)
905 return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_ENUMERATED, 1);
909 * \brief Return the number of enumerated items of the given mixer simple element
910 * \param elem Mixer simple element handle
911 * \return the number of enumerated items, otherwise a negative error code
913 int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem)
917 return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMCNT, 0);
921 * \brief get the enumerated item string for the given mixer simple element
922 * \param elem Mixer simple element handle
923 * \param item the index of the enumerated item to query
924 * \param maxlen the maximal length to be stored
925 * \param buf the buffer to store the name string
926 * \return 0 if successful, otherwise a negative error code
928 int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem,
930 size_t maxlen, char *buf)
934 return sm_selem_ops(elem)->enum_item_name(elem, item, maxlen, buf);
938 * \brief get the current selected enumerated item for the given mixer simple element
939 * \param elem Mixer simple element handle
940 * \param channel mixer simple element channel identifier
941 * \param itemp the pointer to store the index of the enumerated item
942 * \return 0 if successful, otherwise a negative error code
944 int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem,
945 snd_mixer_selem_channel_id_t channel,
950 return sm_selem_ops(elem)->get_enum_item(elem, channel, itemp);
954 * \brief set the current selected enumerated item for the given mixer simple element
955 * \param elem Mixer simple element handle
956 * \param channel mixer simple element channel identifier
957 * \param item the enumerated item index
958 * \return 0 if successful, otherwise a negative error code
960 int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem,
961 snd_mixer_selem_channel_id_t channel,
966 return sm_selem_ops(elem)->set_enum_item(elem, channel, item);
970 * \brief get size of #snd_mixer_selem_id_t
971 * \return size in bytes
973 size_t snd_mixer_selem_id_sizeof()
975 return sizeof(snd_mixer_selem_id_t);
979 * \brief allocate an invalid #snd_mixer_selem_id_t using standard malloc
980 * \param ptr returned pointer
981 * \return 0 on success otherwise negative error code
983 int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr)
986 *ptr = calloc(1, sizeof(snd_mixer_selem_id_t));
993 * \brief frees a previously allocated #snd_mixer_selem_id_t
994 * \param obj pointer to object to free
996 void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj)
1002 * \brief copy one #snd_mixer_selem_id_t to another
1003 * \param dst pointer to destination
1004 * \param src pointer to source
1006 void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src)
1013 * \brief Get name part of a mixer simple element identifier
1014 * \param obj Mixer simple element identifier
1017 const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj)
1024 * \brief Get index part of a mixer simple element identifier
1025 * \param obj Mixer simple element identifier
1026 * \return index part
1028 unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj)
1035 * \brief Set name part of a mixer simple element identifier
1036 * \param obj Mixer simple element identifier
1037 * \param val name part
1039 void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val)
1042 strncpy(obj->name, val, sizeof(obj->name));
1043 obj->name[sizeof(obj->name)-1] = '\0';
1047 * \brief Set index part of a mixer simple element identifier
1048 * \param obj Mixer simple element identifier
1049 * \param val index part
1051 void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val)