int V4LRadioControl::vol(snd_hctl_elem_t *elem) const { const QString card("hw:0"); int err; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *control; snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_value_alloca(&control); if ((err = snd_hctl_elem_info(elem, info)) < 0) { return 0; } snd_hctl_elem_get_id(elem, id); snd_hctl_elem_read(elem, control); return snd_ctl_elem_value_get_integer(control, 0); }
static int findSoundCards(char **cardname) { int idx, dev, err; snd_ctl_t *handle; snd_hctl_t *hctlhandle; snd_ctl_card_info_t *cardinfo; snd_pcm_info_t *pcminfo; char str[32]; snd_ctl_card_info_alloca(&cardinfo); snd_pcm_info_alloca(&pcminfo); snd_hctl_elem_t *elem; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); idx = -1; while (1) { if ((err = snd_card_next(&idx)) < 0) { LOGE("Card next error: %s\n", snd_strerror(err)); break; } if (idx < 0) break; sprintf(str, "hw:CARD=%i", idx); if ((err = snd_ctl_open(&handle, str, 0)) < 0) { LOGE("Open error: %s\n", snd_strerror(err)); continue; } if ((err = snd_ctl_card_info(handle, cardinfo)) < 0) { LOGE("HW info error: %s\n", snd_strerror(err)); continue; } LOGD("Soundcard #%i:\n", idx + 1); LOGD(" card - %i\n", snd_ctl_card_info_get_card(cardinfo)); LOGD(" id - '%s'\n", snd_ctl_card_info_get_id(cardinfo)); LOGD(" driver - '%s'\n", snd_ctl_card_info_get_driver(cardinfo)); LOGD(" name - '%s'\n", snd_ctl_card_info_get_name(cardinfo)); LOGD(" longname - '%s'\n", snd_ctl_card_info_get_longname(cardinfo)); LOGD(" mixername - '%s'\n", snd_ctl_card_info_get_mixername(cardinfo)); LOGD(" components - '%s'\n", snd_ctl_card_info_get_components(cardinfo)); strcpy(cardname[idx], snd_ctl_card_info_get_name(cardinfo)); LOGD("\n\n-----get cart name and id: %s : %d",cardname[idx],idx); snd_ctl_close(handle); if ((err = snd_hctl_open(&hctlhandle, str, 0)) < 0) { LOGE("Control %s open error: %s", str, snd_strerror(err)); return err; } if ((err = snd_hctl_load(hctlhandle)) < 0) { LOGE("Control %s local error: %s\n", str, snd_strerror(err)); return err; } for (elem = snd_hctl_first_elem(hctlhandle); elem; elem = snd_hctl_elem_next(elem)) { if ((err = snd_hctl_elem_info(elem, info)) < 0) { LOGE("Control %s snd_hctl_elem_info error: %s\n", str, snd_strerror(err)); return err; } snd_hctl_elem_get_id(elem, id); show_control_id(id); } snd_hctl_close(hctlhandle); } snd_config_update_free_global(); return 0; }
static int show_control(const char* card, const char *space, snd_hctl_elem_t *elem, int level) { int err; unsigned int item, idx; unsigned int count; snd_ctl_elem_type_t type; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *control; snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_value_alloca(&control); if ((err = snd_hctl_elem_info(elem, info)) < 0) { error("Control %s snd_hctl_elem_info error: %s\n", card, snd_strerror(err)); return err; } if (level & LEVEL_ID) { snd_hctl_elem_get_id(elem, id); show_control_id(id); printf("\n"); } count = snd_ctl_elem_info_get_count(info); type = snd_ctl_elem_info_get_type(info); printf("%s; type=%s,access=%s,values=%i", space, control_type(info), control_access(info), count); switch (type) { case SND_CTL_ELEM_TYPE_INTEGER: printf(",min=%li,max=%li,step=%li\n", snd_ctl_elem_info_get_min(info), snd_ctl_elem_info_get_max(info), snd_ctl_elem_info_get_step(info)); break; case SND_CTL_ELEM_TYPE_INTEGER64: printf(",min=%Li,max=%Li,step=%Li\n", snd_ctl_elem_info_get_min64(info), snd_ctl_elem_info_get_max64(info), snd_ctl_elem_info_get_step64(info)); break; case SND_CTL_ELEM_TYPE_ENUMERATED: { unsigned int items = snd_ctl_elem_info_get_items(info); printf(",items=%u\n", items); for (item = 0; item < items; item++) { snd_ctl_elem_info_set_item(info, item); if ((err = snd_hctl_elem_info(elem, info)) < 0) { error("Control %s element info error: %s\n", card, snd_strerror(err)); return err; } printf("%s; Item #%u '%s'\n", space, item, snd_ctl_elem_info_get_item_name(info)); } break; } default: printf("\n"); break; } if (level & LEVEL_BASIC) { if ((err = snd_hctl_elem_read(elem, control)) < 0) { error("Control %s element read error: %s\n", card, snd_strerror(err)); return err; } printf("%s: values=", space); for (idx = 0; idx < count; idx++) { if (idx > 0) printf(","); switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: printf("%s", snd_ctl_elem_value_get_boolean(control, idx) ? "on" : "off"); break; case SND_CTL_ELEM_TYPE_INTEGER: printf("%li", snd_ctl_elem_value_get_integer(control, idx)); break; case SND_CTL_ELEM_TYPE_INTEGER64: printf("%Li", snd_ctl_elem_value_get_integer64(control, idx)); break; case SND_CTL_ELEM_TYPE_ENUMERATED: printf("%u", snd_ctl_elem_value_get_enumerated(control, idx)); break; case SND_CTL_ELEM_TYPE_BYTES: printf("0x%02x", snd_ctl_elem_value_get_byte(control, idx)); break; default: printf("?"); break; } } printf("\n"); } return 0; }
static int show_control(const char *space, snd_hctl_elem_t *elem, int level) { int err; unsigned int item, idx, count, *tlv; snd_ctl_elem_type_t type; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *control; snd_aes_iec958_t iec958; snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_value_alloca(&control); if ((err = snd_hctl_elem_info(elem, info)) < 0) { error("Control %s snd_hctl_elem_info error: %s\n", card, snd_strerror(err)); return err; } if (level & LEVEL_ID) { snd_hctl_elem_get_id(elem, id); show_control_id(id); printf("\n"); } count = snd_ctl_elem_info_get_count(info); type = snd_ctl_elem_info_get_type(info); printf("%s; type=%s,access=%s,values=%i", space, control_type(info), control_access(info), count); switch (type) { case SND_CTL_ELEM_TYPE_INTEGER: printf(",min=%li,max=%li,step=%li\n", snd_ctl_elem_info_get_min(info), snd_ctl_elem_info_get_max(info), snd_ctl_elem_info_get_step(info)); break; case SND_CTL_ELEM_TYPE_INTEGER64: printf(",min=%Li,max=%Li,step=%Li\n", snd_ctl_elem_info_get_min64(info), snd_ctl_elem_info_get_max64(info), snd_ctl_elem_info_get_step64(info)); break; case SND_CTL_ELEM_TYPE_ENUMERATED: { unsigned int items = snd_ctl_elem_info_get_items(info); printf(",items=%u\n", items); for (item = 0; item < items; item++) { snd_ctl_elem_info_set_item(info, item); if ((err = snd_hctl_elem_info(elem, info)) < 0) { error("Control %s element info error: %s\n", card, snd_strerror(err)); return err; } printf("%s; Item #%u '%s'\n", space, item, snd_ctl_elem_info_get_item_name(info)); } break; } default: printf("\n"); break; } if (level & LEVEL_BASIC) { if (!snd_ctl_elem_info_is_readable(info)) goto __skip_read; if ((err = snd_hctl_elem_read(elem, control)) < 0) { error("Control %s element read error: %s\n", card, snd_strerror(err)); return err; } printf("%s: values=", space); for (idx = 0; idx < count; idx++) { if (idx > 0) printf(","); switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: printf("%s", snd_ctl_elem_value_get_boolean(control, idx) ? "on" : "off"); break; case SND_CTL_ELEM_TYPE_INTEGER: printf("%li", snd_ctl_elem_value_get_integer(control, idx)); break; case SND_CTL_ELEM_TYPE_INTEGER64: printf("%Li", snd_ctl_elem_value_get_integer64(control, idx)); break; case SND_CTL_ELEM_TYPE_ENUMERATED: printf("%u", snd_ctl_elem_value_get_enumerated(control, idx)); break; case SND_CTL_ELEM_TYPE_BYTES: printf("0x%02x", snd_ctl_elem_value_get_byte(control, idx)); break; case SND_CTL_ELEM_TYPE_IEC958: snd_ctl_elem_value_get_iec958(control, &iec958); printf("[AES0=0x%02x AES1=0x%02x AES2=0x%02x AES3=0x%02x]", iec958.status[0], iec958.status[1], iec958.status[2], iec958.status[3]); break; default: printf("?"); break; } } printf("\n"); __skip_read: if (!snd_ctl_elem_info_is_tlv_readable(info)) goto __skip_tlv; tlv = malloc(4096); if ((err = snd_hctl_elem_tlv_read(elem, tlv, 4096)) < 0) { error("Control %s element TLV read error: %s\n", card, snd_strerror(err)); free(tlv); return err; } decode_tlv(strlen(space), tlv, 4096); free(tlv); } __skip_tlv: return 0; }
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; }