/* Init the ALSA library: - Open the configured device, if none, use default device. - Search for the routing control - Search for the ringing and incall routes values */ static int utils_alsa_init() { if(utils_alsa_hctl) return 0; debug("utils_alsa_init: start\n"); int i; for(i=0;i<UTILS_AUDIO_ROUTE_COUNT;i++)utils_alsa_routes[i]=-1; char *alsa_control=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_NAME); char *alsa_route_play=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_RINGING); char *alsa_route_incall=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_INCALL); char *alsa_route_speaker=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_SPEAKER); char *alsa_route_handset=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_HANDSET); if(!alsa_control) return 0; char *alsa_device=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_DEVICE); int ret=0; if(alsa_device) ret = snd_hctl_open(&utils_alsa_hctl, alsa_device, 0); else ret = snd_hctl_open(&utils_alsa_hctl, "default", 0); if(ret){ error("utils_alsa_init: Alsa control device open failed: %s\n", snd_strerror(ret)); goto done; } ret = snd_hctl_load(utils_alsa_hctl); if(ret){ error("utils_alsa_init: Alsa control device load failed\n"); goto done; } snd_hctl_elem_t *elem=snd_hctl_first_elem(utils_alsa_hctl); snd_ctl_elem_info_t *info; snd_ctl_elem_info_alloca(&info); while(elem){ const char *name=snd_hctl_elem_get_name(elem); ret=snd_hctl_elem_info(elem, info); if(ret){ error("utils_alsa_init: snd_hctl_elem_info for ctrl %s error %s\n", name, snd_strerror(ret)); continue; } if(!strcmp(name, alsa_control)){ debug("utils_alsa_init: Found element %s\n", name); // Find the values for(i=0; i<snd_ctl_elem_info_get_items(info); i++){ snd_ctl_elem_info_set_item(info, i); snd_hctl_elem_info(elem, info); const char *s=snd_ctl_elem_info_get_item_name(info); debug("utils_alsa_init: check control value %s:%s\n", name, s); if(alsa_route_play && !strcmp(alsa_route_play, s)){ debug("utils_alsa_init: utils_alsa_route_play=%ud\n", i); utils_alsa_route_play=i; } if(alsa_route_incall && !strcmp(alsa_route_incall, s)){ debug("utils_alsa_init: utils_alsa_route_incall=%ud\n", i); utils_alsa_route_incall=i; } if(alsa_route_speaker && !strcmp(alsa_route_speaker, s)){ debug("utils_alsa_init: alsa_route_speaker=%ud\n", i); utils_alsa_routes[UTILS_AUDIO_ROUTE_SPEAKER]=i; } if(alsa_route_handset && !strcmp(alsa_route_handset, s)){ debug("utils_alsa_init: alsa_route_handset=%ud\n", i); utils_alsa_routes[UTILS_AUDIO_ROUTE_HANDSET]=i; } } snd_ctl_elem_id_malloc(&utils_alsa_route_elem_id); snd_ctl_elem_info_get_id(info, utils_alsa_route_elem_id); utils_alsa_route_elem=elem; } elem=snd_hctl_elem_next(elem); } if(utils_alsa_route_play==-1) utils_alsa_route_play=utils_alsa_routes[UTILS_AUDIO_ROUTE_SPEAKER]; if(utils_alsa_route_incall==-1) utils_alsa_route_incall=utils_alsa_routes[UTILS_AUDIO_ROUTE_HANDSET]; debug("utils_alsa_init: ok\n"); done: g_free(alsa_device); return ret; }
int main() { int cardNumber = -1; int errNum; char *controlType; char deviceID[16]; // ------------------------------------------------------------------------ // ALSA control elements. // ------------------------------------------------------------------------ snd_ctl_t *ctl; // Simple control handle. snd_ctl_elem_id_t *id; // Simple control element id. snd_ctl_elem_value_t *control; // Simple control element value. snd_ctl_elem_type_t type; // Simple control element type. snd_ctl_elem_info_t *info; // Simple control element info container. snd_ctl_card_info_t *card; // Simple control card info container. snd_hctl_t *hctl; // High level control handle; snd_hctl_elem_t *elem; // High level control element handle. // ------------------------------------------------------------------------ // Initialise ALSA card and device types. // ------------------------------------------------------------------------ snd_ctl_card_info_alloca( &card ); snd_ctl_elem_value_alloca( &control ); snd_ctl_elem_id_alloca( &id ); snd_ctl_elem_info_alloca( &info ); // ------------------------------------------------------------------------ // Start card section. // ------------------------------------------------------------------------ // For each card. while (1) { // Find next card number. If < 0 then returns 1st card. errNum = snd_card_next( &cardNumber ); if (( errNum < 0 ) || ( cardNumber < 0 )) break; // Concatenate strings to get card's control interface. sprintf( deviceID, "hw:%i", cardNumber ); // Try to open card. if ( snd_ctl_open( &ctl, deviceID, 0 ) < 0 ) { printf( "Error opening card.\n" ); continue; } // Fill control card info element. if ( snd_ctl_card_info( ctl, card ) < 0 ) { printf( "Error getting card info.\n" ); continue; } // -------------------------------------------------------------------- // Print header block. // -------------------------------------------------------------------- printf( "\t+-----------------------------" ); printf( "-----------------------------+\n" ); printf( "\t| Card: %d - %-46s |", cardNumber, snd_ctl_card_info_get_name( card )); printf( "\n" ); printf( "\t+--------+------------" ); printf( "+------------------------------------+\n" ); printf( "\t| Device | Type " ); printf( "| Name |\n" ); printf( "\t+--------+------------" ); printf( "+------------------------------------+\n" ); // -------------------------------------------------------------------- // Start control section. // -------------------------------------------------------------------- // Open an empty high level control. if ( snd_hctl_open( &hctl, deviceID, 0 ) < 0 ) printf( "Error opening high level control.\n" ); // Load high level control element. if ( snd_hctl_load( hctl ) < 0 ) printf( "Error loading high level control.\n" ); // -------------------------------------------------------------------- // For each control element. // -------------------------------------------------------------------- for ( elem = snd_hctl_first_elem( hctl ); elem; elem = snd_hctl_elem_next( elem )) { // Get ID of high level control element. snd_hctl_elem_get_id( elem, id ); // ---------------------------------------------------------------- // Determine control type. // ---------------------------------------------------------------- if ( snd_hctl_elem_info( elem, info ) < 0 ) printf( "Can't get control information.\n" ); type = snd_ctl_elem_info_get_type( info ); switch ( type ) { case SND_CTL_ELEM_TYPE_NONE: controlType = "None"; break; case SND_CTL_ELEM_TYPE_BOOLEAN: controlType = "Boolean"; break; case SND_CTL_ELEM_TYPE_INTEGER: controlType = "Integer"; break; case SND_CTL_ELEM_TYPE_INTEGER64: controlType = "Integer64"; break; case SND_CTL_ELEM_TYPE_ENUMERATED: controlType = "Enumerated"; break; case SND_CTL_ELEM_TYPE_BYTES: controlType = "Bytes"; break; case SND_CTL_ELEM_TYPE_IEC958: controlType = "IEC958"; break; default: controlType = "Not Found"; break; } printf( "\t| %-6i | %-10s | %-34s |\n", snd_hctl_elem_get_numid( elem ), controlType, snd_hctl_elem_get_name( elem )); } printf( "\t+--------+------------" ); printf( "+------------------------------------+\n\n" ); // -------------------------------------------------------------------- // Tidy up. // -------------------------------------------------------------------- snd_hctl_close( hctl ); snd_ctl_close( ctl ); } return 0; }