void patchbay_init(void) { int i; int nb_active_channels; snd_ctl_elem_value_t *val; snd_ctl_elem_value_alloca(&val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, ANALOG_PLAYBACK_ROUTE_NAME); memset (stream_active, 0, (MAX_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS) * sizeof(int)); nb_active_channels = 0; for (i = 0; i < output_channels; i++) { snd_ctl_elem_value_set_numid(val, 0); snd_ctl_elem_value_set_index(val, i); if (snd_ctl_elem_read(ctl, val) < 0) continue; stream_active[i] = 1; nb_active_channels++; } output_channels = nb_active_channels; snd_ctl_elem_value_set_name(val, SPDIF_PLAYBACK_ROUTE_NAME); nb_active_channels = 0; for (i = 0; i < spdif_channels; i++) { snd_ctl_elem_value_set_numid(val, 0); snd_ctl_elem_value_set_index(val, i); if (snd_ctl_elem_read(ctl, val) < 0) continue; stream_active[i + MAX_OUTPUT_CHANNELS] = 1; nb_active_channels++; } spdif_channels = nb_active_channels; }
void ipga_volume_update(int idx) { snd_ctl_elem_value_t *val; int err, ipga_vol; snd_ctl_elem_value_alloca(&val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, IPGA_VOLUME_NAME); snd_ctl_elem_value_set_index(val, idx); if ((err = snd_ctl_elem_read(ctl, val)) < 0) { g_print("Unable to read ipga volume: %s\n", snd_strerror(err)); return; } gtk_adjustment_set_value(GTK_ADJUSTMENT(av_ipga_volume_adj[idx]), -(ipga_vol = snd_ctl_elem_value_get_integer(val, 0))); snd_ctl_elem_value_set_name(val, ADC_VOLUME_NAME); snd_ctl_elem_value_set_index(val, idx); if ((err = snd_ctl_elem_read(ctl, val)) < 0) { g_print("Unable to read adc volume: %s\n", snd_strerror(err)); return; } // set ADC volume to max if IPGA volume greater 0 if (ipga_vol) gtk_adjustment_set_value(GTK_ADJUSTMENT(av_adc_volume_adj[idx]), -adc_max); }
static void * hammerfall_monitor_controls (void *arg) { jack_hardware_t *hw = (jack_hardware_t *) arg; hammerfall_t *h = (hammerfall_t *) hw->private_hw; snd_ctl_elem_id_t *switch_id[3]; snd_ctl_elem_value_t *sw[3]; pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); snd_ctl_elem_id_malloc (&switch_id[0]); snd_ctl_elem_id_malloc (&switch_id[1]); snd_ctl_elem_id_malloc (&switch_id[2]); snd_ctl_elem_value_malloc (&sw[0]); snd_ctl_elem_value_malloc (&sw[1]); snd_ctl_elem_value_malloc (&sw[2]); set_control_id (switch_id[0], "ADAT1 Sync Check"); set_control_id (switch_id[1], "ADAT2 Sync Check"); set_control_id (switch_id[2], "ADAT3 Sync Check"); snd_ctl_elem_value_set_id (sw[0], switch_id[0]); snd_ctl_elem_value_set_id (sw[1], switch_id[1]); snd_ctl_elem_value_set_id (sw[2], switch_id[2]); while (1) { if (snd_ctl_elem_read (h->driver->ctl_handle, sw[0])) { jack_error ("cannot read control switch 0 ..."); } hammerfall_check_sync (h, sw[0]); if (snd_ctl_elem_read (h->driver->ctl_handle, sw[1])) { jack_error ("cannot read control switch 0 ..."); } hammerfall_check_sync (h, sw[1]); if (snd_ctl_elem_read (h->driver->ctl_handle, sw[2])) { jack_error ("cannot read control switch 0 ..."); } hammerfall_check_sync (h, sw[2]); if (nanosleep (&h->monitor_interval, 0)) { break; } } pthread_exit (0); }
static int get_toggle_index(int stream) { int err, out; snd_ctl_elem_value_t *val; stream--; if (stream < 0 || stream > 9) { g_print("get_toggle_index (1)\n"); return 0; } snd_ctl_elem_value_alloca(&val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); if (stream >= MAX_OUTPUT_CHANNELS) { snd_ctl_elem_value_set_name(val, SPDIF_PLAYBACK_ROUTE_NAME); snd_ctl_elem_value_set_index(val, stream - MAX_OUTPUT_CHANNELS); } else { snd_ctl_elem_value_set_name(val, ANALOG_PLAYBACK_ROUTE_NAME); snd_ctl_elem_value_set_index(val, stream); } if ((err = snd_ctl_elem_read(ctl, val)) < 0) return 0; out = snd_ctl_elem_value_get_enumerated(val, 0); if (out >= MAX_INPUT_CHANNELS + MAX_SPDIF_CHANNELS + 1) { if (stream >= MAX_PCM_OUTPUT_CHANNELS || stream < MAX_SPDIF_CHANNELS) return 1; /* digital mixer */ } else if (out >= MAX_INPUT_CHANNELS + 1) return out - (MAX_INPUT_CHANNELS + 1) + 2; /* spdif left (=2) / right (=3) */ else if (out >= 1) return out + spdif_channels + 1; /* analog (4-) */ return 0; /* pcm */ }
/** * \brief Get value for an HCTL element * \param elem HCTL element * \param value HCTL element value * \return 0 otherwise a negative error code on failure */ int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value) { assert(elem); assert(elem->hctl); assert(value); value->id = elem->id; return snd_ctl_elem_read(elem->hctl->ctl, value); }
void level_meters_init(void) { int err; snd_ctl_elem_value_malloc(&peaks); snd_ctl_elem_value_set_interface(peaks, SND_CTL_ELEM_IFACE_PCM); snd_ctl_elem_value_set_name(peaks, "Multi Track Peak"); if ((err = snd_ctl_elem_read(ctl, peaks)) < 0) /* older ALSA driver, using MIXER type */ snd_ctl_elem_value_set_interface(peaks, SND_CTL_ELEM_IFACE_MIXER); }
int get_gain(int idx, int src, int dst) { int err; int val = HDSPMM_ERROR_NO_CARD; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *ctl; snd_ctl_t *handle; if(idx >= HDSPMM_MAX_CARDS || idx < 0) return HDSPMM_ERROR_WRONG_IDX; snd_ctl_elem_value_alloca(&ctl); snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_set_name(id, "Mixer"); snd_ctl_elem_id_set_numid(id, 0); snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_HWDEP); snd_ctl_elem_id_set_device(id, 0); snd_ctl_elem_id_set_subdevice(id, 0); snd_ctl_elem_id_set_index(id, 0); snd_ctl_elem_value_set_id(ctl, id); if ((err = snd_ctl_open(&handle, card_name[cardid], SND_CTL_NONBLOCK)) < 0) { #ifndef QUIET fprintf(stderr, "Alsa error: %s\n", snd_strerror(err)); #endif return HDSPMM_ERROR_ALSA_OPEN; } snd_ctl_elem_value_set_integer(ctl, 0, src); snd_ctl_elem_value_set_integer(ctl, 1, dst); if ((err = snd_ctl_elem_read(handle, ctl)) < 0) { #ifndef QUIET fprintf(stderr, "Alsa error: %s\n", snd_strerror(err)); #endif return HDSPMM_ERROR_ALSA_READ; } val = snd_ctl_elem_value_get_integer(ctl, 2); snd_ctl_close(handle); return val; SETFLOAT(x->x_at+1, delta); SETFLOAT(x->x_at+2, phi); outlet_list(x->x_out_para, &s_list, 3, x->x_at); outlet_anything(x->x_obj.ob_outlet, s, x->x_size2d+1, x->x_at); }
/* * get the current volume value from driver * * TODO: mmap support? */ static void get_current_volume(snd_pcm_softvol_t *svol) { unsigned int val; unsigned int i; if (snd_ctl_elem_read(svol->ctl, &svol->elem) < 0) return; for (i = 0; i < svol->cchannels; i++) { val = svol->elem.value.integer.value[i]; if (val > svol->max_val) val = svol->max_val; svol->cur_vol[i] = val; } }
void dac_volume_update(int idx) { snd_ctl_elem_value_t *val; int err; snd_ctl_elem_value_alloca(&val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, DAC_VOLUME_NAME); snd_ctl_elem_value_set_index(val, idx); if ((err = snd_ctl_elem_read(ctl, val)) < 0) { g_print("Unable to read dac volume: %s\n", snd_strerror(err)); return; } gtk_adjustment_set_value(GTK_ADJUSTMENT(av_dac_volume_adj[idx]), -snd_ctl_elem_value_get_integer(val, 0)); }
void adc_sense_update(int idx) { snd_ctl_elem_value_t *val; int err; int state; snd_ctl_elem_value_alloca(&val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, ADC_SENSE_NAME); snd_ctl_elem_value_set_index(val, idx); if ((err = snd_ctl_elem_read(ctl, val)) < 0) { g_print("Unable to read adc sense: %s\n", snd_strerror(err)); return; } state = snd_ctl_elem_value_get_enumerated(val, 0); toggle_set(av_adc_sense_radio[idx][state], TRUE); }
static int execute_cset(snd_ctl_t *ctl, const char *cset) { const char *pos; int err; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *value; snd_ctl_elem_info_t *info; snd_ctl_elem_id_malloc(&id); snd_ctl_elem_value_malloc(&value); snd_ctl_elem_info_malloc(&info); err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos); if (err < 0) goto __fail; while (*pos && isspace(*pos)) pos++; if (!*pos) { uc_error("undefined value for cset >%s<", cset); err = -EINVAL; goto __fail; } snd_ctl_elem_value_set_id(value, id); snd_ctl_elem_info_set_id(info, id); err = snd_ctl_elem_read(ctl, value); if (err < 0) goto __fail; err = snd_ctl_elem_info(ctl, info); if (err < 0) goto __fail; err = snd_ctl_ascii_value_parse(ctl, value, info, pos); if (err < 0) goto __fail; err = snd_ctl_elem_write(ctl, value); if (err < 0) goto __fail; err = 0; __fail: if (id != NULL) free(id); if (value != NULL) free(value); if (info != NULL) free(info); return err; }
static int check_elems(struct elem_set_trial *trial) { snd_ctl_elem_value_t *data; unsigned int numid; unsigned int index; unsigned int i; int err; snd_ctl_elem_value_alloca(&data); snd_ctl_elem_value_set_id(data, trial->id); numid = snd_ctl_elem_id_get_numid(trial->id); index = snd_ctl_elem_id_get_index(trial->id); for (i = 0; i < trial->element_count; ++i) { snd_ctl_elem_value_set_index(data, index + i); /* * In Linux 4.0 or former, ioctl(SNDRV_CTL_IOCTL_ELEM_ADD) * doesn't fill all of fields for identification. */ if (numid > 0) snd_ctl_elem_value_set_numid(data, numid + i); err = snd_ctl_elem_read(trial->handle, data); if (err < 0) return err; /* Change members of an element in this element set. */ trial->change_elem_members(trial, data); err = snd_ctl_elem_write(trial->handle, data); if (err < 0) return err; } return 0; }
bool LegacyAmixerControl::accessHW(bool receive, string &error) { CAutoLog autoLog(getConfigurableElement(), "ALSA", isDebugEnabled()); #ifdef SIMULATION if (receive) { memset(getBlackboardLocation(), 0, getSize()); } log_info("%s ALSA Element Instance: %s\t\t(Control Element: %s)", receive ? "Reading" : "Writing", getConfigurableElement()->getPath().c_str(), getControlName().c_str()); return true; #endif int ret; // Mixer handle snd_ctl_t *sndCtrl; uint32_t value; uint32_t index; uint32_t elementCount; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *control; logControlInfo(receive); // Check parameter type is ok (deferred error, no exceptions available :-() if (!isTypeSupported()) { error = "Parameter type not supported."; return false; } int cardNumber = getCardNumber(); if (cardNumber < 0) { error = "Card " + getCardName() + " not found. Error: " + strerror(cardNumber); return false; } #ifdef ANDROID if ((ret = snd_ctl_hw_open(&sndCtrl, NULL, cardNumber, 0)) < 0) { error = snd_strerror(ret); return false; } #else // Create device name ostringstream deviceName; deviceName << "hw:" << cardNumber; // Open sound control if ((ret = snd_ctl_open(&sndCtrl, deviceName.str().c_str(), 0)) < 0) { error = snd_strerror(ret); return false; } #endif // Allocate in stack snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_value_alloca(&control); // Set interface snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); string controlName = getControlName(); // Set name or id if (isdigit(controlName[0])) { snd_ctl_elem_id_set_numid(id, asInteger(controlName)); } else { snd_ctl_elem_id_set_name(id, controlName.c_str()); } // Init info id snd_ctl_elem_info_set_id(info, id); // Get info if ((ret = snd_ctl_elem_info(sndCtrl, info)) < 0) { error = "ALSA: Unable to get element info " + controlName + ": " + snd_strerror(ret); // Close sound control snd_ctl_close(sndCtrl); return false; } // Get type snd_ctl_elem_type_t eType = snd_ctl_elem_info_get_type(info); // Get element count elementCount = snd_ctl_elem_info_get_count(info); uint32_t scalarSize = getScalarSize(); // If size defined in the PFW different from alsa mixer control size, return an error if (elementCount * scalarSize != getSize()) { error = "ALSA: Control element count (" + asString(elementCount) + ") and configurable scalar element count (" + asString(getSize() / scalarSize) + ") mismatch"; // Close sound control snd_ctl_close(sndCtrl); return false; } // Set value id snd_ctl_elem_value_set_id(control, id); if (receive) { // Read element if ((ret = snd_ctl_elem_read(sndCtrl, control)) < 0) { error = "ALSA: Unable to read element " + controlName + ": " + snd_strerror(ret); // Close sound control snd_ctl_close(sndCtrl); return false; } // Go through all indexes for (index = 0; index < elementCount; index++) { switch (eType) { case SND_CTL_ELEM_TYPE_BOOLEAN: value = snd_ctl_elem_value_get_boolean(control, index); break; case SND_CTL_ELEM_TYPE_INTEGER: value = snd_ctl_elem_value_get_integer(control, index); break; case SND_CTL_ELEM_TYPE_INTEGER64: value = snd_ctl_elem_value_get_integer64(control, index); break; case SND_CTL_ELEM_TYPE_ENUMERATED: value = snd_ctl_elem_value_get_enumerated(control, index); break; case SND_CTL_ELEM_TYPE_BYTES: value = snd_ctl_elem_value_get_byte(control, index); break; default: error = "ALSA: Unknown control element type while reading alsa element " + controlName; return false; } if (isDebugEnabled()) { log_info("Reading alsa element %s, index %u with value %u", controlName.c_str(), index, value); } // Write data to blackboard (beware this code is OK on Little Endian machines only) toBlackboard(value); } } else { // Go through all indexes for (index = 0; index < elementCount; index++) { // Read data from blackboard (beware this code is OK on Little Endian machines only) value = fromBlackboard(); if (isDebugEnabled()) { log_info("Writing alsa element %s, index %u with value %u", controlName.c_str(), index, value); } switch (eType) { case SND_CTL_ELEM_TYPE_BOOLEAN: snd_ctl_elem_value_set_boolean(control, index, value); break; case SND_CTL_ELEM_TYPE_INTEGER: snd_ctl_elem_value_set_integer(control, index, value); break; case SND_CTL_ELEM_TYPE_INTEGER64: snd_ctl_elem_value_set_integer64(control, index, value); break; case SND_CTL_ELEM_TYPE_ENUMERATED: snd_ctl_elem_value_set_enumerated(control, index, value); break; case SND_CTL_ELEM_TYPE_BYTES: snd_ctl_elem_value_set_byte(control, index, value); break; default: error = "ALSA: Unknown control element type while writing alsa element " + controlName; return false; } } // Write element if ((ret = snd_ctl_elem_write(sndCtrl, control)) < 0) { error = "ALSA: Unable to write element " + controlName + ": " + snd_strerror(ret); // Close sound control snd_ctl_close(sndCtrl); return false; } } // Close sound control snd_ctl_close(sndCtrl); return true; }
static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *top) { snd_ctl_elem_value_t *ctl; snd_ctl_elem_info_t *info; snd_config_t *control, *comment, *item, *value; const char *s; char buf[256]; unsigned int idx; int err; unsigned int device, subdevice, index; const char *name; snd_ctl_elem_type_t type; unsigned int count; snd_ctl_elem_value_alloca(&ctl); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_info_set_id(info, id); err = snd_ctl_elem_info(handle, info); if (err < 0) { error("Cannot read control info '%s': %s", id_str(id), snd_strerror(err)); return err; } if (snd_ctl_elem_info_is_inactive(info) || !snd_ctl_elem_info_is_readable(info)) return 0; snd_ctl_elem_value_set_id(ctl, id); err = snd_ctl_elem_read(handle, ctl); if (err < 0) { error("Cannot read control '%s': %s", id_str(id), snd_strerror(err)); return err; } err = snd_config_compound_add(top, num_str(snd_ctl_elem_info_get_numid(info)), 0, &control); if (err < 0) { error("snd_config_compound_add: %s", snd_strerror(err)); return err; } err = snd_config_compound_add(control, "comment", 1, &comment); if (err < 0) { error("snd_config_compound_add: %s", snd_strerror(err)); return err; } buf[0] = '\0'; buf[1] = '\0'; if (snd_ctl_elem_info_is_readable(info)) strcat(buf, " read"); if (snd_ctl_elem_info_is_writable(info)) strcat(buf, " write"); if (snd_ctl_elem_info_is_inactive(info)) strcat(buf, " inactive"); if (snd_ctl_elem_info_is_volatile(info)) strcat(buf, " volatile"); if (snd_ctl_elem_info_is_locked(info)) strcat(buf, " locked"); if (snd_ctl_elem_info_is_user(info)) strcat(buf, " user"); err = snd_config_string_add(comment, "access", buf + 1); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } type = snd_ctl_elem_info_get_type(info); device = snd_ctl_elem_info_get_device(info); subdevice = snd_ctl_elem_info_get_subdevice(info); index = snd_ctl_elem_info_get_index(info); name = snd_ctl_elem_info_get_name(info); count = snd_ctl_elem_info_get_count(info); s = snd_ctl_elem_type_name(type); err = snd_config_string_add(comment, "type", s); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } err = snd_config_integer_add(comment, "count", count); if (err < 0) { error("snd_config_integer_add: %s", snd_strerror(err)); return err; } switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: break; case SND_CTL_ELEM_TYPE_INTEGER: { long min = snd_ctl_elem_info_get_min(info); long max = snd_ctl_elem_info_get_max(info); long step = snd_ctl_elem_info_get_step(info); if (step) sprintf(buf, "%li - %li (step %li)", min, max, step); else sprintf(buf, "%li - %li", min, max); err = snd_config_string_add(comment, "range", buf); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } if (snd_ctl_elem_info_is_tlv_readable(info)) { err = add_tlv_comments(handle, id, info, comment); if (err < 0) return err; } break; } case SND_CTL_ELEM_TYPE_INTEGER64: { long long min = snd_ctl_elem_info_get_min64(info); long long max = snd_ctl_elem_info_get_max64(info); long long step = snd_ctl_elem_info_get_step64(info); if (step) sprintf(buf, "%Li - %Li (step %Li)", min, max, step); else sprintf(buf, "%Li - %Li", min, max); err = snd_config_string_add(comment, "range", buf); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } break; } case SND_CTL_ELEM_TYPE_ENUMERATED: { unsigned int items; err = snd_config_compound_add(comment, "item", 1, &item); if (err < 0) { error("snd_config_compound_add: %s", snd_strerror(err)); return err; } items = snd_ctl_elem_info_get_items(info); for (idx = 0; idx < items; idx++) { snd_ctl_elem_info_set_item(info, idx); err = snd_ctl_elem_info(handle, info); if (err < 0) { error("snd_ctl_card_info: %s", snd_strerror(err)); return err; } err = snd_config_string_add(item, num_str(idx), snd_ctl_elem_info_get_item_name(info)); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } } break; } default: break; } s = snd_ctl_elem_iface_name(snd_ctl_elem_info_get_interface(info)); err = snd_config_string_add(control, "iface", s); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } if (device != 0) { err = snd_config_integer_add(control, "device", device); if (err < 0) { error("snd_config_integer_add: %s", snd_strerror(err)); return err; } } if (subdevice != 0) { err = snd_config_integer_add(control, "subdevice", subdevice); if (err < 0) { error("snd_config_integer_add: %s", snd_strerror(err)); return err; } } err = snd_config_string_add(control, "name", name); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } if (index != 0) { err = snd_config_integer_add(control, "index", index); if (err < 0) { error("snd_config_integer_add: %s", snd_strerror(err)); return err; } } switch (type) { case SND_CTL_ELEM_TYPE_BYTES: case SND_CTL_ELEM_TYPE_IEC958: { size_t size = type == SND_CTL_ELEM_TYPE_BYTES ? count : sizeof(snd_aes_iec958_t); char buf[size * 2 + 1]; char *p = buf; char *hex = "0123456789abcdef"; const unsigned char *bytes = (const unsigned char *)snd_ctl_elem_value_get_bytes(ctl); for (idx = 0; idx < size; idx++) { int v = bytes[idx]; *p++ = hex[v >> 4]; *p++ = hex[v & 0x0f]; } *p = '\0'; err = snd_config_string_add(control, "value", buf); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } return 0; } default: break; } if (count == 1) { switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: err = snd_config_string_add(control, "value", snd_ctl_elem_value_get_boolean(ctl, 0) ? "true" : "false"); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } return 0; case SND_CTL_ELEM_TYPE_INTEGER: err = snd_config_integer_add(control, "value", snd_ctl_elem_value_get_integer(ctl, 0)); if (err < 0) { error("snd_config_integer_add: %s", snd_strerror(err)); return err; } return 0; case SND_CTL_ELEM_TYPE_INTEGER64: err = snd_config_integer64_add(control, "value", snd_ctl_elem_value_get_integer64(ctl, 0)); if (err < 0) { error("snd_config_integer64_add: %s", snd_strerror(err)); return err; } return 0; case SND_CTL_ELEM_TYPE_ENUMERATED: { unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, 0); snd_config_t *c; err = snd_config_search(item, num_str(v), &c); if (err == 0) { err = snd_config_get_string(c, &s); assert(err == 0); err = snd_config_string_add(control, "value", s); } else { err = snd_config_integer_add(control, "value", v); } if (err < 0) error("snd_config add: %s", snd_strerror(err)); return 0; } default: error("Unknown control type: %d\n", type); return -EINVAL; } } err = snd_config_compound_add(control, "value", 1, &value); if (err < 0) { error("snd_config_compound_add: %s", snd_strerror(err)); return err; } switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: for (idx = 0; idx < count; idx++) { err = snd_config_string_add(value, num_str(idx), snd_ctl_elem_value_get_boolean(ctl, idx) ? "true" : "false"); if (err < 0) { error("snd_config_string_add: %s", snd_strerror(err)); return err; } } break; case SND_CTL_ELEM_TYPE_INTEGER: for (idx = 0; idx < count; idx++) { err = snd_config_integer_add(value, num_str(idx), snd_ctl_elem_value_get_integer(ctl, idx)); if (err < 0) { error("snd_config_integer_add: %s", snd_strerror(err)); return err; } } break; case SND_CTL_ELEM_TYPE_INTEGER64: for (idx = 0; idx < count; idx++) { err = snd_config_integer64_add(value, num_str(idx), snd_ctl_elem_value_get_integer64(ctl, idx)); if (err < 0) { error("snd_config_integer64_add: %s", snd_strerror(err)); return err; } } break; case SND_CTL_ELEM_TYPE_ENUMERATED: for (idx = 0; idx < count; idx++) { unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, idx); snd_config_t *c; err = snd_config_search(item, num_str(v), &c); if (err == 0) { err = snd_config_get_string(c, &s); assert(err == 0); err = snd_config_string_add(value, num_str(idx), s); } else { err = snd_config_integer_add(value, num_str(idx), v); } if (err < 0) { error("snd_config add: %s", snd_strerror(err)); return err; } } break; default: error("Unknown control type: %d\n", type); return -EINVAL; } return 0; }
static int check_audio_route() { int err, idx, i; snd_ctl_t *handle; const char *route_ctrl_name = "Speaker Function"; snd_ctl_elem_value_t * elem_value; snd_ctl_elem_info_t *info; snd_ctl_elem_list_t elist; snd_ctl_elem_id_t *eid; snd_ctl_elem_value_alloca(&elem_value); snd_ctl_elem_info_alloca(&info); //snd_ctl_elem_value_set_numid(elem_value, 54); if ((err = snd_ctl_open(&handle, "hw:0", 0)) < 0) { db_msg("Open control error: %s\n", snd_strerror(err)); goto check_audio_route_err; } db_msg("card=%d\n", handle->card); memset(&elist, 0, sizeof(elist)); if (snd_ctl_elem_list(handle, &elist) < 0) { db_msg("snd_ctl_elem_list 1 failed\n"); goto check_audio_route_err; } eid = calloc(elist.count, sizeof(snd_ctl_elem_id_t)); elist.space = elist.count; elist.pids = eid; if (snd_ctl_elem_list(handle, &elist) < 0) { db_msg("snd_ctl_elem_list 2 failed\n"); goto check_audio_route_err; } for (i = 0; i < elist.count; ++i) { info->id.numid = eid[i].numid; if ((err = snd_ctl_elem_info(handle, info)) < 0) { db_msg("Cannot find the given element from control\n"); goto check_audio_route_err; } //db_msg("name[%d]=%s\n", i, snd_ctl_elem_info_get_name(info)); if (!strcmp(snd_ctl_elem_info_get_name(info), route_ctrl_name)) { db_msg("route ctrl found!!!\n"); break; } } snd_ctl_elem_value_set_numid(elem_value, info->id.numid); if ((err = snd_ctl_elem_read(handle,elem_value)) < 0) { db_msg("snd_ctl_elem_read error: %s\n", snd_strerror(err)); goto check_audio_route_err; } db_msg("numid=%d\n", snd_ctl_elem_value_get_numid(elem_value)); db_msg("name=%s\n", snd_ctl_elem_value_get_name(elem_value)); //to set the new value snd_ctl_elem_value_set_enumerated(elem_value,0, 1); if ((err = snd_ctl_elem_write(handle,elem_value)) < 0) { db_msg("snd_ctl_elem_write error: %s\n", snd_strerror(err)); goto check_audio_route_err; } //read it out again to check if we did set the registers. if ((err = snd_ctl_elem_read(handle,elem_value)) < 0) { db_msg("snd_ctl_elem_read error: %s\n", snd_strerror(err)); goto check_audio_route_err; } db_msg("after: %d\n", snd_ctl_elem_value_get_enumerated(elem_value, 0)); snd_ctl_close(handle); return 0; check_audio_route_err: snd_ctl_close(handle); return -1; }
static void update_peak_switch(void) { int err; if ((err = snd_ctl_elem_read(ctl, peaks)) < 0) g_print("Unable to read peaks: %s\n", snd_strerror(err)); }
status_t ALSAControl::get(const char *name, unsigned int &value, int index) { if (!mHandle) { ALOGE("Control not initialized"); return NO_INIT; } 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); snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_name(id, name); snd_ctl_elem_info_set_id(info, id); int ret = snd_ctl_elem_info(mHandle, info); if (ret < 0) { ALOGE("Control '%s' cannot get element info: %d", name, ret); return BAD_VALUE; } int count = snd_ctl_elem_info_get_count(info); if (index >= count) { ALOGE("Control '%s' index is out of range (%d >= %d)", name, index, count); return BAD_VALUE; } snd_ctl_elem_info_get_id(info, id); snd_ctl_elem_value_set_id(control, id); ret = snd_ctl_elem_read(mHandle, control); if (ret < 0) { ALOGE("Control '%s' cannot read element value: %d", name, ret); return BAD_VALUE; } snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info); switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: value = snd_ctl_elem_value_get_boolean(control, index); break; case SND_CTL_ELEM_TYPE_INTEGER: value = snd_ctl_elem_value_get_integer(control, index); break; case SND_CTL_ELEM_TYPE_INTEGER64: value = snd_ctl_elem_value_get_integer64(control, index); break; case SND_CTL_ELEM_TYPE_ENUMERATED: value = snd_ctl_elem_value_get_enumerated(control, index); break; case SND_CTL_ELEM_TYPE_BYTES: value = snd_ctl_elem_value_get_byte(control, index); break; default: return BAD_VALUE; } return NO_ERROR; }
static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type) { const char *pos; int err; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *value; snd_ctl_elem_info_t *info; unsigned int *res = NULL; snd_ctl_elem_id_malloc(&id); snd_ctl_elem_value_malloc(&value); snd_ctl_elem_info_malloc(&info); err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos); if (err < 0) goto __fail; while (*pos && isspace(*pos)) pos++; if (!*pos) { uc_error("undefined value for cset >%s<", cset); err = -EINVAL; goto __fail; } snd_ctl_elem_info_set_id(info, id); err = snd_ctl_elem_info(ctl, info); if (err < 0) goto __fail; if (type == SEQUENCE_ELEMENT_TYPE_CSET_TLV) { if (!snd_ctl_elem_info_is_tlv_writable(info)) { err = -EINVAL; goto __fail; } err = read_tlv_file(&res, pos); if (err < 0) goto __fail; err = snd_ctl_elem_tlv_write(ctl, id, res); if (err < 0) goto __fail; } else { snd_ctl_elem_value_set_id(value, id); err = snd_ctl_elem_read(ctl, value); if (err < 0) goto __fail; if (type == SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE) err = binary_file_parse(value, info, pos); else err = snd_ctl_ascii_value_parse(ctl, value, info, pos); if (err < 0) goto __fail; err = snd_ctl_elem_write(ctl, value); if (err < 0) goto __fail; } err = 0; __fail: if (id != NULL) free(id); if (value != NULL) free(value); if (info != NULL) free(info); if (res != NULL) free(res); return err; }