@@ -105,6 +105,18 @@ impl Ctl {
105105 acheck ! ( snd_ctl_elem_unlock( self . 0 , elem_id_ptr( id) ) )
106106 }
107107
108+ pub fn elem_list ( & self ) -> Result < ElemList > {
109+ // populate an empty list to get the number of elements
110+ let empty_list = elem_list_new ( 0 ) ?;
111+ acheck ! ( snd_ctl_elem_list( self . 0 , empty_list. 0 ) ) ?;
112+ let required_elements = empty_list. get_count ( ) ;
113+
114+ // obtain the list of all the elements now that we know how many there are
115+ let full_list = elem_list_new ( required_elements) ?;
116+ acheck ! ( snd_ctl_elem_list( self . 0 , full_list. 0 ) ) ?;
117+ Ok ( full_list)
118+ }
119+
108120 /// Note: According to alsa-lib documentation, you're also supposed to have functionality for
109121 /// returning whether or not you are subscribed. This does not work in practice, so I'm not
110122 /// including that here.
@@ -448,6 +460,57 @@ impl fmt::Debug for ElemId {
448460 }
449461}
450462
463+ /// [snd_ctl_elem_list_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper
464+ pub struct ElemList ( * mut alsa:: snd_ctl_elem_list_t ) ;
465+
466+ impl Drop for ElemList {
467+ fn drop ( & mut self ) {
468+ unsafe { alsa:: snd_ctl_elem_list_free_space ( self . 0 ) } ;
469+ unsafe { alsa:: snd_ctl_elem_list_free ( self . 0 ) } ;
470+ }
471+ }
472+
473+ pub fn elem_list_new ( count : u32 ) -> Result < ElemList > {
474+ let mut p = ptr:: null_mut ( ) ;
475+ let list = acheck ! ( snd_ctl_elem_list_malloc( & mut p) ) . map ( |_| ElemList ( p) ) ?;
476+ if count > 0 {
477+ acheck ! ( snd_ctl_elem_list_alloc_space( list. 0 , count) ) ?;
478+ }
479+ Ok ( list)
480+ }
481+
482+ impl ElemList {
483+ #[ inline]
484+ fn ensure_valid_index ( & self , index : u32 ) -> Result < ( ) > {
485+ if index >= self . get_used ( ) {
486+ Err ( Error :: new ( "snd_ctl_elem_list_*" , libc:: EINVAL ) )
487+ } else {
488+ Ok ( ( ) )
489+ }
490+ }
491+
492+ pub ( crate ) fn get_count ( & self ) -> u32 { unsafe { alsa:: snd_ctl_elem_list_get_count ( self . 0 ) } }
493+ pub fn get_used ( & self ) -> u32 { unsafe { alsa:: snd_ctl_elem_list_get_used ( self . 0 ) } }
494+ pub fn get_id ( & self , index : u32 ) -> Result < ElemId > {
495+ self . ensure_valid_index ( index) ?;
496+ let elem_id = elem_id_new ( ) ?;
497+ unsafe { alsa:: snd_ctl_elem_list_get_id ( self . 0 , index, elem_id_ptr ( & elem_id) ) } ;
498+ Ok ( elem_id)
499+ }
500+ pub fn get_numid ( & self , index : u32 ) -> Result < u32 > { self . ensure_valid_index ( index) ?; Ok ( unsafe { alsa:: snd_ctl_elem_list_get_numid ( self . 0 , index) } ) }
501+ pub fn get_interface ( & self , index : u32 ) -> Result < ElemIface > {
502+ self . ensure_valid_index ( index) ?;
503+ ElemIface :: from_c_int ( unsafe { alsa:: snd_ctl_elem_list_get_interface ( self . 0 , index) } as c_int , "snd_ctl_elem_list_get_interface" )
504+ }
505+ pub fn get_device ( & self , index : u32 ) -> Result < u32 > { self . ensure_valid_index ( index) ?; Ok ( unsafe { alsa:: snd_ctl_elem_list_get_device ( self . 0 , index) } ) }
506+ pub fn get_subdevice ( & self , index : u32 ) -> Result < u32 > { self . ensure_valid_index ( index) ?; Ok ( unsafe { alsa:: snd_ctl_elem_list_get_subdevice ( self . 0 , index) } ) }
507+ pub fn get_name ( & self , index : u32 ) -> Result < & str > {
508+ self . ensure_valid_index ( index) ?;
509+ from_const ( "snd_ctl_elem_list_get_name" , unsafe { alsa:: snd_ctl_elem_list_get_name ( self . 0 , index) } )
510+ }
511+ pub fn get_index ( & self , index : u32 ) -> Result < u32 > { self . ensure_valid_index ( index) ?; Ok ( unsafe { alsa:: snd_ctl_elem_list_get_index ( self . 0 , index) } ) }
512+ }
513+
451514/// [snd_ctl_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper
452515pub struct Event ( * mut alsa:: snd_ctl_event_t ) ;
453516
0 commit comments