Lines Matching defs:mixer
2 * \file mixer/mixer.c
8 * Mixer interface is designed to access mixer elements.
33 /*! \page mixer Mixer interface
35 <P>Mixer interface is designed to access the abstracted mixer controls.
63 * \brief Opens an empty mixer
64 * \param mixerp Returned mixer handle
70 snd_mixer_t *mixer;
72 mixer = calloc(1, sizeof(*mixer));
73 if (mixer == NULL)
75 INIT_LIST_HEAD(&mixer->slaves);
76 INIT_LIST_HEAD(&mixer->classes);
77 INIT_LIST_HEAD(&mixer->elems);
78 mixer->compare = snd_mixer_compare_default;
79 *mixerp = mixer;
84 * \brief Attach an HCTL element to a mixer element
89 * For use by mixer element class specific code.
91 * The implementation of mixer class typically calls it at #SND_CTL_EVENT_MASK_ADD event. Once
93 * at #SND_CTL_EVENT_MASK_REMOVE event. Unless detaching, mixer API internal hits assertion due
108 * \brief Detach an HCTL element from a mixer element
113 * For use by mixer element class specific code.
115 * The implementation of mixer class typically calls it at #SND_CTL_EVENT_MASK_REMOVE event for
116 * attached mixer element at #SND_CTL_EVENT_MASK_ADD. Unless detaching, mixer API internal hits
132 * \brief Return true if a mixer element does not contain any HCTL elements
136 * For use by mixer element class specific code.
159 // mixer class forget to detach mixer element from hcontrol element which has been
182 snd_mixer_t *mixer = snd_hctl_get_callback_private(hctl);
192 list_for_each(pos, &mixer->classes) {
205 * \brief Attach an HCTL specified with the CTL device name to an opened mixer
206 * \param mixer Mixer handle
210 int snd_mixer_attach(snd_mixer_t *mixer, const char *name)
218 err = snd_mixer_attach_hctl(mixer, hctl);
225 * \brief Attach an HCTL to an opened mixer
226 * \param mixer Mixer handle
232 int snd_mixer_attach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl)
250 snd_hctl_set_callback_private(hctl, mixer);
252 list_add_tail(&slave->list, &mixer->slaves);
257 * \brief Detach a previously attached HCTL to an opened mixer freeing all related resources
258 * \param mixer Mixer handle
262 int snd_mixer_detach(snd_mixer_t *mixer, const char *name)
265 list_for_each(pos, &mixer->slaves) {
279 * \brief Detach a previously attached HCTL to an opened mixer freeing all related resources
280 * \param mixer Mixer handle
286 int snd_mixer_detach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl)
289 list_for_each(pos, &mixer->slaves) {
303 * \param mixer Mixer handle
308 int snd_mixer_get_hctl(snd_mixer_t *mixer, const char *name, snd_hctl_t **hctl)
311 list_for_each(pos, &mixer->slaves) {
322 static int snd_mixer_throw_event(snd_mixer_t *mixer, unsigned int mask,
325 mixer->events++;
326 if (mixer->callback)
327 return mixer->callback(mixer, mask, elem);
333 elem->class->mixer->events++;
339 static int _snd_mixer_find_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem, int *dir)
344 assert(mixer && elem);
345 assert(mixer->compare);
347 u = mixer->count;
350 c = mixer->compare(elem, mixer->pelems[idx]);
363 * \brief Get private data associated to give mixer element
367 * For use by mixer element class specific code.
375 * \brief Allocate a new mixer element
376 * \param elem Returned mixer element
383 * For use by mixer element class specific code.
404 * \brief Add an element for a registered mixer element class
409 * For use by mixer element class specific code.
414 snd_mixer_t *mixer = class->mixer;
417 if (mixer->count == mixer->alloc) {
419 mixer->alloc += 32;
420 m = realloc(mixer->pelems, sizeof(*m) * mixer->alloc);
422 mixer->alloc -= 32;
425 mixer->pelems = m;
427 if (mixer->count == 0) {
428 list_add_tail(&elem->list, &mixer->elems);
429 mixer->pelems[0] = elem;
431 idx = _snd_mixer_find_elem(mixer, elem, &dir);
434 list_add(&elem->list, &mixer->pelems[idx]->list);
437 list_add_tail(&elem->list, &mixer->pelems[idx]->list);
439 memmove(mixer->pelems + idx + 1,
440 mixer->pelems + idx,
441 (mixer->count - idx) * sizeof(snd_mixer_elem_t *));
442 mixer->pelems[idx] = elem;
444 mixer->count++;
445 return snd_mixer_throw_event(mixer, SND_CTL_EVENT_MASK_ADD, elem);
449 * \brief Remove a mixer element
453 * For use by mixer element class specific code.
457 snd_mixer_t *mixer = elem->class->mixer;
462 assert(mixer->count);
463 idx = _snd_mixer_find_elem(mixer, elem, &dir);
473 mixer->count--;
474 m = mixer->count - idx;
476 memmove(mixer->pelems + idx,
477 mixer->pelems + idx + 1,
483 * \brief Free a mixer element
486 * For use by mixer element class specific code.
500 * For use by mixer element class specific code.
512 * For use by mixer element class specific code.
520 * \brief Register mixer element class
522 * \param mixer Mixer handle
525 * For use by mixer element class specific code.
527 int snd_mixer_class_register(snd_mixer_class_t *class, snd_mixer_t *mixer)
530 class->mixer = mixer;
531 list_add_tail(&class->list, &mixer->classes);
534 list_for_each(pos, &mixer->slaves) {
551 * \brief Unregister mixer element class and remove all its elements
561 snd_mixer_t *mixer = class->mixer;
562 for (k = mixer->count; k > 0; k--) {
563 e = mixer->pelems[k-1];
575 * \brief Load a mixer elements
576 * \param mixer Mixer handle
579 int snd_mixer_load(snd_mixer_t *mixer)
582 list_for_each(pos, &mixer->slaves) {
594 * \brief Unload all mixer elements and free all related resources
595 * \param mixer Mixer handle
597 void snd_mixer_free(snd_mixer_t *mixer)
600 list_for_each(pos, &mixer->slaves) {
608 * \brief Close a mixer and free all related resources
609 * \param mixer Mixer handle
612 int snd_mixer_close(snd_mixer_t *mixer)
615 assert(mixer);
616 while (!list_empty(&mixer->classes)) {
618 c = list_entry(mixer->classes.next, snd_mixer_class_t, list);
621 assert(list_empty(&mixer->elems));
622 assert(mixer->count == 0);
623 free(mixer->pelems);
624 mixer->pelems = NULL;
625 while (!list_empty(&mixer->slaves)) {
628 s = list_entry(mixer->slaves.next, snd_mixer_slave_t, list);
635 free(mixer);
653 snd_mixer_t *mixer;
655 mixer = (*((const snd_mixer_elem_t * const *)a))->class->mixer;
656 return mixer->compare(*(const snd_mixer_elem_t * const *)a, *(const snd_mixer_elem_t * const *)b);
659 static int snd_mixer_sort(snd_mixer_t *mixer)
662 assert(mixer);
663 assert(mixer->compare);
664 INIT_LIST_HEAD(&mixer->elems);
665 qsort(mixer->pelems, mixer->count, sizeof(snd_mixer_elem_t *), mixer_compare);
666 for (k = 0; k < mixer->count; k++)
667 list_add_tail(&mixer->pelems[k]->list, &mixer->elems);
672 * \brief Change mixer compare function and reorder elements
673 * \param mixer Mixer handle
677 int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t compare)
682 assert(mixer);
683 compare_old = mixer->compare;
684 mixer->compare = compare == NULL ? snd_mixer_compare_default : compare;
685 if ((err = snd_mixer_sort(mixer)) < 0) {
686 mixer->compare = compare_old;
693 * \brief get count of poll descriptors for mixer handle
694 * \param mixer Mixer handle
697 int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer)
701 assert(mixer);
702 list_for_each(pos, &mixer->slaves) {
716 * \param mixer Mixer handle
721 int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space)
725 assert(mixer);
726 list_for_each(pos, &mixer->slaves) {
745 * \param mixer Mixer handle
751 int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
755 assert(mixer && pfds && revents);
766 * \brief Wait for a mixer to become ready (i.e. at least one event pending)
767 * \param mixer Mixer handle
771 int snd_mixer_wait(snd_mixer_t *mixer, int timeout)
777 count = snd_mixer_poll_descriptors(mixer, pfds, sizeof(spfds) / sizeof(spfds[0]));
784 err = snd_mixer_poll_descriptors(mixer, pfds,
795 * \brief get first element for a mixer
796 * \param mixer Mixer handle
799 snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer)
801 assert(mixer);
802 if (list_empty(&mixer->elems))
804 return list_entry(mixer->elems.next, snd_mixer_elem_t, list);
808 * \brief get last element for a mixer
809 * \param mixer Mixer handle
812 snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer)
814 assert(mixer);
815 if (list_empty(&mixer->elems))
817 return list_entry(mixer->elems.prev, snd_mixer_elem_t, list);
821 * \brief get next mixer element
822 * \param elem mixer element
828 if (elem->list.next == &elem->class->mixer->elems)
834 * \brief get previous mixer element
835 * \param elem mixer element
841 if (elem->list.prev == &elem->class->mixer->elems)
847 * \brief Handle pending mixer events invoking callbacks
848 * \param mixer Mixer handle
851 int snd_mixer_handle_events(snd_mixer_t *mixer)
854 assert(mixer);
855 mixer->events = 0;
856 list_for_each(pos, &mixer->slaves) {
864 return mixer->events;
868 * \brief Set callback function for a mixer
869 * \param obj mixer handle
879 * \brief Set callback private value for a mixer
880 * \param mixer mixer handle
883 void snd_mixer_set_callback_private(snd_mixer_t *mixer, void * val)
885 assert(mixer);
886 mixer->callback_private = val;
890 * \brief Get callback private value for a mixer
891 * \param mixer mixer handle
894 void * snd_mixer_get_callback_private(const snd_mixer_t *mixer)
896 assert(mixer);
897 return mixer->callback_private;
901 * \brief Get elements count for a mixer
902 * \param mixer mixer handle
905 unsigned int snd_mixer_get_count(const snd_mixer_t *mixer)
907 assert(mixer);
908 return mixer->count;
912 * \brief Set callback function for a mixer element
913 * \param mixer mixer element
916 void snd_mixer_elem_set_callback(snd_mixer_elem_t *mixer, snd_mixer_elem_callback_t val)
918 assert(mixer);
919 mixer->callback = val;
923 * \brief Set callback private value for a mixer element
924 * \param mixer mixer element
927 void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *mixer, void * val)
929 assert(mixer);
930 mixer->callback_private = val;
934 * \brief Get callback private value for a mixer element
935 * \param mixer mixer element
938 void * snd_mixer_elem_get_callback_private(const snd_mixer_elem_t *mixer)
940 assert(mixer);
941 return mixer->callback_private;
945 * \brief Get type for a mixer element
946 * \param mixer mixer element
947 * \return mixer element type
949 snd_mixer_elem_type_t snd_mixer_elem_get_type(const snd_mixer_elem_t *mixer)
951 assert(mixer);
952 return mixer->type;
1002 * \brief Get a mixer associated to given mixer class
1004 * \return mixer pointer
1009 return obj->mixer;
1013 * \brief Get mixer event callback associated to given mixer class
1024 * \brief Get mixer private data associated to given mixer class
1036 * \brief Get mixer compare callback associated to given mixer class
1047 * \brief Set mixer event callback to given mixer class
1060 * \brief Set mixer private data to given mixer class
1073 * \brief Set mixer private data free callback to given mixer class
1086 * \brief Set mixer compare callback to given mixer class