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); }
static int hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) { hammerfall_t *h = (hammerfall_t *) hw->private_hw; snd_ctl_elem_value_t *ctl; snd_ctl_elem_id_t *ctl_id; int err; int i; snd_ctl_elem_value_alloca (&ctl); snd_ctl_elem_id_alloca (&ctl_id); set_control_id (ctl_id, "Channels Thru"); snd_ctl_elem_value_set_id (ctl, ctl_id); for (i = 0; i < 26; i++) { snd_ctl_elem_value_set_integer (ctl, i, (mask & (1<<i)) ? 1 : 0); } if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) != 0) { jack_error ("ALSA/Hammerfall: cannot set input monitoring (%s)", snd_strerror (err)); return -1; } hw->input_monitor_mask = mask; return 0; }
int phoneui_utils_sound_volume_raw_set(enum SoundControlType type, long value) { int err; unsigned int i, count; snd_hctl_elem_t *elem; snd_ctl_elem_value_t *control; elem = controls[STATE_INDEX][type].element; if (!elem) { return -1; } snd_ctl_elem_value_alloca(&control); count = controls[STATE_INDEX][type].count; for (i = 0 ; i < count ; i++) { snd_ctl_elem_value_set_integer(control, i, value); } err = snd_hctl_elem_write(elem, control); if (err) { g_warning("%s", snd_strerror(err)); return -1; } /* FIXME put it somewhere else, this is not the correct place! */ phoneui_utils_sound_volume_save(type); return 0; }
static int elem_write_route(selem_none_t *s, int dir, selem_ctl_type_t type) { snd_ctl_elem_value_t *ctl; unsigned int idx; int err; selem_ctl_t *c = &s->ctls[type]; snd_ctl_elem_value_alloca(&ctl); if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0) return err; for (idx = 0; idx < c->values * c->values; idx++) snd_ctl_elem_value_set_integer(ctl, idx, 0); for (idx = 0; idx < c->values; idx++) snd_ctl_elem_value_set_integer(ctl, idx * c->values + idx, !!(s->str[dir].sw & (1 << idx))); if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0) return err; return 0; }
int set_gain(int idx, int src, int dst, int val) { int err; 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[idx], 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); snd_ctl_elem_value_set_integer(ctl, 2, val); if ((err = snd_ctl_elem_write(handle, ctl)) < 0) { #ifndef QUIET fprintf(stderr, "Alsa error: %s\n", snd_strerror(err)); #endif return HDSPMM_ERROR_ALSA_WRITE; } val = snd_ctl_elem_value_get_integer(ctl, 2); snd_ctl_close(handle); return val; }
static int setamixer(int devnum,char *param, int v1, int v2) { int type; char str[100]; snd_hctl_t *hctl; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *control; snd_hctl_elem_t *elem; snd_ctl_elem_info_t *info; sprintf(str,"hw:%d",devnum); if (snd_hctl_open(&hctl, str, 0)) return(-1); snd_hctl_load(hctl); snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_name(id, param); elem = snd_hctl_find_elem(hctl, id); if (!elem) { snd_hctl_close(hctl); return(-1); } snd_ctl_elem_info_alloca(&info); snd_hctl_elem_info(elem,info); type = snd_ctl_elem_info_get_type(info); snd_ctl_elem_value_alloca(&control); snd_ctl_elem_value_set_id(control, id); switch(type) { case SND_CTL_ELEM_TYPE_INTEGER: snd_ctl_elem_value_set_integer(control, 0, v1); if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2); break; case SND_CTL_ELEM_TYPE_BOOLEAN: snd_ctl_elem_value_set_integer(control, 0, (v1 != 0)); break; } if (snd_hctl_elem_write(elem, control)) { snd_hctl_close(hctl); return(-1); } snd_hctl_close(hctl); return(0); }
static void change_int_elem_members(struct elem_set_trial *trial, snd_ctl_elem_value_t *elem_data) { long val; unsigned int i; for (i = 0; i < trial->member_count; ++i) { val = snd_ctl_elem_value_get_integer(elem_data, i); snd_ctl_elem_value_set_integer(elem_data, i, ++val); } }
void audio_set_default_levels() { int err; snd_ctl_t *ctl; snd_ctl_elem_value_t *val; snd_ctl_elem_value_alloca(&val); if (snd_ctl_open(&ctl, ALSA_DEVICE, 0)) { fprintf(stderr, "can't open audio device"); return; } /* unmute microphone */ snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, "Mic Capture Switch"); snd_ctl_elem_value_set_integer(val, 0, 1); err = snd_ctl_elem_write(ctl, val); if (err) fprintf(stderr, "can't unmute microphone: %s\n", snd_strerror(err)); /* unmute speaker */ snd_ctl_elem_value_clear(val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, "Speaker Playback Switch"); snd_ctl_elem_value_set_integer(val, 0, 1); err = snd_ctl_elem_write(ctl, val); if (err) fprintf(stderr, "can't unmute speaker: %s\n", snd_strerror(err)); /* set mic volume */ snd_ctl_elem_value_clear(val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, "Mic Capture Volume"); snd_ctl_elem_value_set_integer(val, 0, DEFAULT_MIC_VOL); err = snd_ctl_elem_write(ctl, val); if (err) fprintf(stderr, "can't set microphone volume: %s\n", snd_strerror(err)); /* set speaker volume */ snd_ctl_elem_value_clear(val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, "Speaker Playback Volume"); snd_ctl_elem_value_set_integer(val, 0, DEFAULT_SPKR_VOL); snd_ctl_elem_value_set_integer(val, 1, DEFAULT_SPKR_VOL); err = snd_ctl_elem_write(ctl, val); if (err) fprintf(stderr, "can't set speaker volume: %s\n", snd_strerror(err)); /* set capture source */ snd_ctl_elem_value_clear(val); snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_value_set_name(val, "PCM Capture Source"); snd_ctl_elem_value_set_integer(val, 0, 0); err = snd_ctl_elem_write(ctl, val); if (err) fprintf(stderr, "can't set capture source: %s\n", snd_strerror(err)); snd_ctl_close(ctl); }
static int elem_write_switch_constant(selem_none_t *s, selem_ctl_type_t type, int val) { snd_ctl_elem_value_t *ctl; unsigned int idx; int err; selem_ctl_t *c = &s->ctls[type]; snd_ctl_elem_value_alloca(&ctl); if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0) return err; for (idx = 0; idx < c->values; idx++) snd_ctl_elem_value_set_integer(ctl, idx, !!val); if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0) return err; return 0; }
static int elem_write_volume(selem_none_t *s, int dir, selem_ctl_type_t type) { snd_ctl_elem_value_t *ctl; unsigned int idx; int err; selem_ctl_t *c = &s->ctls[type]; snd_ctl_elem_value_alloca(&ctl); if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0) return err; for (idx = 0; idx < c->values; idx++) snd_ctl_elem_value_set_integer(ctl, idx, from_user(s, dir, c, s->str[dir].vol[idx])); if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0) return err; return 0; }
void ipga_volume_adjust(GtkAdjustment *adj, gpointer data) { int idx = (int)(long)data; snd_ctl_elem_value_t *val; int err, ival = -(int)adj->value; char text[16]; 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); snd_ctl_elem_value_set_integer(val, 0, ival); sprintf(text, "%03i", ival); gtk_label_set_text(av_ipga_volume_label[idx], text); if ((err = snd_ctl_elem_write(ctl, val)) < 0) g_print("Unable to write ipga volume: %s\n", snd_strerror(err)); }
/****************************************************************************** * setMixerInput *****************************************************************************/ static Int setMixerControl (const Char *name, Int value) { Int status; snd_hctl_t *hctl; snd_ctl_elem_id_t *id; snd_hctl_elem_t *elem; snd_ctl_elem_value_t *control; if ((status = snd_hctl_open(&hctl, AUDIO_MIXER, 0)) < 0) { Dmai_err2("setMixerControl %s open error: %s\n", AUDIO_MIXER, snd_strerror(status)); return Dmai_EFAIL;; } if ((status = snd_hctl_load(hctl)) < 0) { Dmai_err2("setMixerControl %s load error: %s\n", AUDIO_MIXER, snd_strerror(status)); return Dmai_EFAIL;; } snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_name(id, name); elem = snd_hctl_find_elem(hctl, id); if (!elem) { Dmai_err1("setMixerControl %s find element error\n", AUDIO_MIXER); snd_hctl_close(hctl); return Dmai_EFAIL; } snd_ctl_elem_value_alloca(&control); snd_ctl_elem_value_set_id(control, id); snd_ctl_elem_value_set_integer(control, 0, value); snd_hctl_elem_write(elem, control); snd_hctl_close(hctl); return Dmai_EOK; }
/** * alsa dumy codec controls interface */ int dummy_alsa_control_raw(char * id_string , long vol, int rw, long * value){ int err; snd_hctl_t *hctl; snd_ctl_elem_id_t *id; snd_hctl_elem_t *elem; snd_ctl_elem_value_t *control; snd_ctl_elem_info_t *info; snd_ctl_elem_type_t type; unsigned int idx = 0, count; long tmp, min, max; char dev[10] = {0}; int card = alsa_get_aml_card(); int port = alsa_get_spdif_port(); adec_print("card = %d, port = %d\n", card, port); sprintf(dev, "hw:%d,%d", (card >= 0) ? card : 0, (port >= 0) ? port : 0); if ((err = snd_hctl_open(&hctl, dev, 0)) < 0) { printf("Control %s open error: %s\n", dev, snd_strerror(err)); return err; } if (err = snd_hctl_load(hctl)< 0) { printf("Control %s open error: %s\n", dev, snd_strerror(err)); return err; } snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_name(id, id_string); elem = snd_hctl_find_elem(hctl, id); snd_ctl_elem_value_alloca(&control); snd_ctl_elem_value_set_id(control, id); snd_ctl_elem_info_alloca(&info); if ((err = snd_hctl_elem_info(elem, info)) < 0) { printf("Control %s snd_hctl_elem_info error: %s\n", dev, snd_strerror(err)); return err; } count = snd_ctl_elem_info_get_count(info); type = snd_ctl_elem_info_get_type(info); for (idx = 0; idx < count; idx++) { switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: if(rw){ tmp = 0; if (vol >= 1) { tmp = 1; } snd_ctl_elem_value_set_boolean(control, idx, tmp); err = snd_hctl_elem_write(elem, control); }else *value = snd_ctl_elem_value_get_boolean(control, idx); break; case SND_CTL_ELEM_TYPE_INTEGER: if(rw){ min = snd_ctl_elem_info_get_min(info); max = snd_ctl_elem_info_get_max(info); if ((vol >= min) && (vol <= max)) tmp = vol; else if (vol < min) tmp = min; else if (vol > max) tmp = max; snd_ctl_elem_value_set_integer(control, idx, tmp); err = snd_hctl_elem_write(elem, control); }else *value = snd_ctl_elem_value_get_integer(control, idx); break; default: printf("?"); break; } if (err < 0){ printf ("control%s access error=%s,close control device\n", dev, snd_strerror(err)); snd_hctl_close(hctl); return err; } } return 0; }
static int amixer_control(t_amixer *x, int argc, t_atom *argv, int roflag) { int err; snd_ctl_t *handle; snd_ctl_elem_info_t *info; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *control; char *ptr; unsigned int idx, count; long tmp; snd_ctl_elem_type_t type; snd_ctl_elem_info_alloca(&info); snd_ctl_elem_id_alloca(&id); snd_ctl_elem_value_alloca(&control); if (argc < 1) { error("Specify a full control identifier: [[iface=<iface>,][name='name',][index=<index>,][device=<device>,][subdevice=<subdevice>]]|[numid=<numid>]\n"); return -EINVAL; } if(A_FLOAT==argv->a_type){ snd_ctl_elem_id_set_numid(id, atom_getint(argv)); if(0) { error("Wrong control identifier: %d\n", atom_getint(argv)); return -EINVAL; } } else { if (parse_control_id(atom_getsymbol(argv)->s_name, id)) { error("Wrong control identifier: %s\n", atom_getsymbol(argv)->s_name); return -EINVAL; } } if ((err = snd_ctl_open(&handle, x->card, 0)) < 0) { error("Control %s open error: %s\n", x->card, snd_strerror(err)); return err; } snd_ctl_elem_info_set_id(info, id); if ((err = snd_ctl_elem_info(handle, info)) < 0) { error("Control %s cinfo error: %s\n", x->card, snd_strerror(err)); return err; } snd_ctl_elem_info_get_id(info, id); /* FIXME: Remove it when hctl find works ok !!! */ type = snd_ctl_elem_info_get_type(info); count = snd_ctl_elem_info_get_count(info); snd_ctl_elem_value_set_id(control, id); if (!roflag) { t_float atom_float = atom_getfloat(argv+1); int atom_isfloat = (A_FLOAT==(argv+1)->a_type); post("now setting"); ptr = atom_getsymbol(argv+1)->s_name; for (idx = 0; idx < count && idx < 128 && ptr && *ptr; idx++) { switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: tmp = 0; if(atom_isfloat){ tmp=(atom_float>0)?1:0; } else if (!strncasecmp(ptr, "on", 2) || !strncasecmp(ptr, "up", 2)) { tmp = 1; ptr += 2; } else if (!strncasecmp(ptr, "yes", 3)) { tmp = 1; ptr += 3; } else if (!strncasecmp(ptr, "toggle", 6)) { tmp = snd_ctl_elem_value_get_boolean(control, idx); tmp = tmp > 0 ? 0 : 1; ptr += 6; } else if (isdigit(*ptr)) { tmp = atoi(ptr) > 0 ? 1 : 0; while (isdigit(*ptr)) ptr++; } else { while (*ptr && *ptr != ',') ptr++; } snd_ctl_elem_value_set_boolean(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_INTEGER: tmp = atom_isfloat?((int)atom_float):get_integer(&ptr, snd_ctl_elem_info_get_min(info), snd_ctl_elem_info_get_max(info)); snd_ctl_elem_value_set_integer(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_INTEGER64: tmp = atom_isfloat?((int)atom_float):get_integer64(&ptr, snd_ctl_elem_info_get_min64(info), snd_ctl_elem_info_get_max64(info)); snd_ctl_elem_value_set_integer64(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_ENUMERATED: tmp = atom_isfloat?((int)atom_float):get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1); snd_ctl_elem_value_set_enumerated(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_BYTES: tmp = atom_isfloat?((int)atom_float):get_integer(&ptr, 0, 255); snd_ctl_elem_value_set_byte(control, idx, tmp); break; default: break; } if (!strchr(atom_getsymbol(argv+1)->s_name, ',')) ptr = atom_getsymbol(argv+1)->s_name; else if (*ptr == ',') ptr++; } if ((err = snd_ctl_elem_write(handle, control)) < 0) { error("Control %s element write error: %s\n", x->card, snd_strerror(err)); return err; } } snd_ctl_close(handle); if (1) { snd_hctl_t *hctl; snd_hctl_elem_t *elem; if ((err = snd_hctl_open(&hctl, x->card, 0)) < 0) { error("Control %s open error: %s\n", x->card, snd_strerror(err)); return err; } if ((err = snd_hctl_load(hctl)) < 0) { error("Control %s load error: %s\n", x->card, snd_strerror(err)); return err; } elem = snd_hctl_find_elem(hctl, id); if (elem) show_control(x->card, " ", elem, LEVEL_BASIC | LEVEL_ID); else printf("Could not find the specified element\n"); snd_hctl_close(hctl); } }
static int cset(int argc, char *argv[], int roflag, int keep_handle) { int err; static snd_ctl_t *handle = NULL; snd_ctl_elem_info_t *info; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *control; char *ptr; unsigned int idx, count; long tmp; snd_ctl_elem_type_t type; snd_ctl_elem_info_alloca(&info); snd_ctl_elem_id_alloca(&id); snd_ctl_elem_value_alloca(&control); if (argc < 1) return -EINVAL; if (parse_control_id(argv[0], id)) return -EINVAL; if (handle == NULL && (err = snd_ctl_open(&handle, card, 0)) < 0) return err; snd_ctl_elem_info_set_id(info, id); if ((err = snd_ctl_elem_info(handle, info)) < 0) { if (!keep_handle) { snd_ctl_close(handle); handle = NULL; } return err; } snd_ctl_elem_info_get_id(info, id); type = snd_ctl_elem_info_get_type(info); count = snd_ctl_elem_info_get_count(info); snd_ctl_elem_value_set_id(control, id); if (!roflag) { ptr = argv[1]; for (idx = 0; idx < count && idx < 128 && ptr && *ptr; idx++) { switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: tmp = 0; if (!strncasecmp(ptr, "on", 2) || !strncasecmp(ptr, "up", 2)) { tmp = 1; ptr += 2; } else if (!strncasecmp(ptr, "yes", 3)) { tmp = 1; ptr += 3; } else if (!strncasecmp(ptr, "toggle", 6)) { tmp = snd_ctl_elem_value_get_boolean(control, idx); tmp = tmp > 0 ? 0 : 1; ptr += 6; } else if (isdigit(*ptr)) { tmp = atoi(ptr) > 0 ? 1 : 0; while (isdigit(*ptr)) ptr++; } else { while (*ptr && *ptr != ',') ptr++; } snd_ctl_elem_value_set_boolean(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_INTEGER: tmp = get_integer(&ptr, snd_ctl_elem_info_get_min(info), snd_ctl_elem_info_get_max(info)); snd_ctl_elem_value_set_integer(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_INTEGER64: tmp = get_integer64(&ptr, snd_ctl_elem_info_get_min64(info), snd_ctl_elem_info_get_max64(info)); snd_ctl_elem_value_set_integer64(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_ENUMERATED: tmp = get_ctl_enum_item_index(handle, info, &ptr); if (tmp < 0) tmp = get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1); snd_ctl_elem_value_set_enumerated(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_BYTES: tmp = get_integer(&ptr, 0, 255); snd_ctl_elem_value_set_byte(control, idx, tmp); break; default: break; } if (!strchr(argv[1], ',')) ptr = argv[1]; else if (*ptr == ',') ptr++; } if ((err = snd_ctl_elem_write(handle, control)) < 0) { if (!keep_handle) { snd_ctl_close(handle); handle = NULL; } return err; } } if (! keep_handle) { snd_ctl_close(handle); handle = NULL; } if (!quiet) { snd_hctl_t *hctl; snd_hctl_elem_t *elem; if ((err = snd_hctl_open(&hctl, card, 0)) < 0) return err; if ((err = snd_hctl_load(hctl)) < 0) return err; elem = snd_hctl_find_elem(hctl, id); if (elem) show_control(" ", elem, LEVEL_BASIC | LEVEL_ID); snd_hctl_close(hctl); } return 0; }
void V4LRadioControl::callAmixer(const QString& target, const QString& value) { int err; long tmp; unsigned int count; static snd_ctl_t *handle = NULL; QString card("hw:0"); snd_ctl_elem_info_t *info; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *control; snd_ctl_elem_type_t type; snd_ctl_elem_info_alloca(&info); snd_ctl_elem_id_alloca(&id); snd_ctl_elem_value_alloca(&control); snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); /* MIXER */ // in amixer parse func // char target[64]; // e.g. PGA CAPTure Switch snd_ctl_elem_id_set_name(id, target.toAscii()); if (handle == NULL && (err = snd_ctl_open(&handle, card.toAscii(), 0)) < 0) { return; } snd_ctl_elem_info_set_id(info, id); if ((err = snd_ctl_elem_info(handle, info)) < 0) { snd_ctl_close(handle); handle = NULL; return; } snd_ctl_elem_info_get_id(info, id); /* FIXME: Remove it when hctl find works ok !!! */ type = snd_ctl_elem_info_get_type(info); count = snd_ctl_elem_info_get_count(info); snd_ctl_elem_value_set_id(control, id); tmp = 0; for (uint idx = 0; idx < count && idx < 128; idx++) { switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: #ifdef MULTIMEDIA_MAEMO_DEBUG qDebug() << "SND_CTL_ELEM_TYPE_BOOLEAN" << SND_CTL_ELEM_TYPE_BOOLEAN; #endif if ((value == "on") ||(value == "1")) { tmp = 1; } snd_ctl_elem_value_set_boolean(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_ENUMERATED: tmp = getEnumItemIndex(handle, info, value); snd_ctl_elem_value_set_enumerated(control, idx, tmp); break; case SND_CTL_ELEM_TYPE_INTEGER: #ifdef MULTIMEDIA_MAEMO_DEBUG qDebug() << "SND_CTL_ELEM_TYPE_INTEGER" << SND_CTL_ELEM_TYPE_INTEGER; #endif tmp = atoi(value.toAscii()); if (tmp < snd_ctl_elem_info_get_min(info)) tmp = snd_ctl_elem_info_get_min(info); else if (tmp > snd_ctl_elem_info_get_max(info)) tmp = snd_ctl_elem_info_get_max(info); snd_ctl_elem_value_set_integer(control, idx, tmp); break; default: break; } } if ((err = snd_ctl_elem_write(handle, control)) < 0) { snd_ctl_close(handle); handle = NULL; return; } snd_ctl_close(handle); handle = NULL; }
/** * \brief parse ASCII string as CTL element value * \param handle CTL handle * \param dst destination CTL element value * \param info CTL element info structure * \param value source ASCII string * \return zero on success, otherwise a negative error code * * Note: For toggle command, the dst must contain previous (current) * state (do the #snd_ctl_elem_read call to obtain it). */ int snd_ctl_ascii_value_parse(snd_ctl_t *handle, snd_ctl_elem_value_t *dst, snd_ctl_elem_info_t *info, const char *value) { const char *ptr = value; snd_ctl_elem_id_t myid = {0}; snd_ctl_elem_type_t type; unsigned int idx, count; long tmp; long long tmp64; snd_ctl_elem_info_get_id(info, &myid); type = snd_ctl_elem_info_get_type(info); count = snd_ctl_elem_info_get_count(info); snd_ctl_elem_value_set_id(dst, &myid); for (idx = 0; idx < count && idx < 128 && ptr && *ptr; idx++) { if (*ptr == ',') goto skip; switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: tmp = 0; if (!strncasecmp(ptr, "on", 2) || !strncasecmp(ptr, "up", 2)) { tmp = 1; ptr += 2; } else if (!strncasecmp(ptr, "yes", 3)) { tmp = 1; ptr += 3; } else if (!strncasecmp(ptr, "toggle", 6)) { tmp = snd_ctl_elem_value_get_boolean(dst, idx); tmp = tmp > 0 ? 0 : 1; ptr += 6; } else if (isdigit(*ptr)) { tmp = atoi(ptr) > 0 ? 1 : 0; while (isdigit(*ptr)) ptr++; } else { while (*ptr && *ptr != ',') ptr++; } snd_ctl_elem_value_set_boolean(dst, idx, tmp); break; case SND_CTL_ELEM_TYPE_INTEGER: tmp = get_integer(&ptr, snd_ctl_elem_info_get_min(info), snd_ctl_elem_info_get_max(info)); snd_ctl_elem_value_set_integer(dst, idx, tmp); break; case SND_CTL_ELEM_TYPE_INTEGER64: tmp64 = get_integer64(&ptr, snd_ctl_elem_info_get_min64(info), snd_ctl_elem_info_get_max64(info)); snd_ctl_elem_value_set_integer64(dst, idx, tmp64); break; case SND_CTL_ELEM_TYPE_ENUMERATED: tmp = get_ctl_enum_item_index(handle, info, &ptr); if (tmp < 0) tmp = get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1); snd_ctl_elem_value_set_enumerated(dst, idx, tmp); break; case SND_CTL_ELEM_TYPE_BYTES: tmp = get_integer(&ptr, 0, 255); snd_ctl_elem_value_set_byte(dst, idx, tmp); break; default: break; } skip: if (!strchr(value, ',')) ptr = value; else if (*ptr == ',') ptr++; } return 0; }
void main( int argc, char *argv[] ) { struct structArgs cmdArgs; int errNum; // ************************************************************************ // 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 info container. // ************************************************************************ // Get command line parameters. // ************************************************************************ argp_parse( &argp, argc, argv, 0, 0, &cmdArgs ); printf( "Card = %i\n", cmdArgs.card ); printf( "Control = %i\n", cmdArgs.control ); printf( "Value 1 = %i\n", cmdArgs.value1 ); printf( "Value 2 = %i\n", cmdArgs.value2 ); // ************************************************************************ // Set up ALSA control. // ************************************************************************ sprintf( cmdArgs.deviceID, "hw:%i", cmdArgs.card ); printf( "Device ID = %s.\n", cmdArgs.deviceID ); if ( snd_ctl_open( &ctl, cmdArgs.deviceID, 1 ) < 0 ) { printf( "Error opening control.\n" ); return; } // Initialise a simple control element id structure. snd_ctl_elem_id_alloca( &id ); snd_ctl_elem_id_set_numid( id, cmdArgs.control ); // Initialise info element. snd_ctl_elem_info_alloca( &info ); snd_ctl_elem_info_set_numid( info, cmdArgs.control ); // Is the control valid? if ( snd_ctl_elem_info( ctl, info ) < 0 ) { printf( "Error getting control element info.\n" ); return; } // Find type of control. // either: // SND_CTL_ELEM_TYPE_INTEGER, // SND_CTL_ELEM_TYPE_INTEGER64, // SND_CTL_ELEM_TYPE_ENUMERATED, etc. // Only interested in INTEGER. type = snd_ctl_elem_info_get_type( info ); if ( type != SND_CTL_ELEM_TYPE_INTEGER ) { printf( "Control type is not integer.\n" ); printf( "Type = %s\n", type ); return; } // ************************************************************************ // Get some information for selected control. // ************************************************************************ printf( "Min value for control = %d\n", snd_ctl_elem_info_get_min( info )); printf( "Max value for control = %d\n", snd_ctl_elem_info_get_max( info )); printf( "Step value for control = %d\n", snd_ctl_elem_info_get_step( info )); // Initialise the control element value container. snd_ctl_elem_value_alloca( &control ); snd_ctl_elem_value_set_id( control, id ); // ************************************************************************ // Set values for selected control. // ************************************************************************ snd_ctl_elem_value_set_integer( control, 0, cmdArgs.value1 ); if ( snd_ctl_elem_write( ctl, control ) < 0 ) printf( "Error setting L volume" ); else printf( "Set L volume to %d.\n", cmdArgs.value1 ); snd_ctl_elem_value_set_integer( control, 1, cmdArgs.value2 ); if ( snd_ctl_elem_write( ctl, control ) < 0 ) printf( "Error setting R volume" ); else printf( "Set R volume to %d.\n", cmdArgs.value2 ); // ************************************************************************ // Clean up. // ************************************************************************ snd_ctl_close( ctl ); return; }
int hw_audio_set(const char *name, int value) { static snd_ctl_t *handle = NULL; 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); 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); if (handle == NULL && (err = snd_ctl_open(&handle, "default", 0)) < 0) { LOGE("Control default open error: %s\n", snd_strerror(err)); return 0; } int ret = snd_ctl_elem_info(handle, info); if (ret < 0) { LOGE("Cannot find the given element from control default ret=%d %s ", ret, snd_strerror(ret)); return 0; } snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info); snd_ctl_elem_info_get_id(info, id); snd_ctl_elem_value_set_id(control, id); switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: snd_ctl_elem_value_set_boolean(control, 0, value); break; case SND_CTL_ELEM_TYPE_INTEGER: snd_ctl_elem_value_set_integer(control, 0, value); break; case SND_CTL_ELEM_TYPE_INTEGER64: snd_ctl_elem_value_set_integer64(control, 0, value); break; case SND_CTL_ELEM_TYPE_ENUMERATED: snd_ctl_elem_value_set_enumerated(control, 0, value); break; case SND_CTL_ELEM_TYPE_BYTES: snd_ctl_elem_value_set_byte(control, 0, value); break; default: break; } ret = snd_ctl_elem_write(handle, control); if(ret <0) { LOGE("Control default load error: %s\n", snd_strerror(ret)); } return 1; }
/************************************************************************** * ALSA_CheckSetVolume [internal] * * Helper function for Alsa volume queries. This tries to simplify * the process of managing the volume. All parameters are optional * (pass NULL to ignore or not use). * Return values are MMSYSERR_NOERROR on success, or !0 on failure; * error codes are normalized into the possible documented return * values from waveOutGetVolume. */ int ALSA_CheckSetVolume(snd_hctl_t *hctl, int *out_left, int *out_right, int *out_min, int *out_max, int *out_step, int *new_left, int *new_right) { int rc = MMSYSERR_NOERROR; int value_count = 0; snd_hctl_elem_t * elem = NULL; snd_ctl_elem_info_t * eleminfop = NULL; snd_ctl_elem_value_t * elemvaluep = NULL; snd_ctl_elem_id_t * elemidp = NULL; const char *names[] = {"PCM Playback Volume", "Line Playback Volume", NULL}; const char **name; #define EXIT_ON_ERROR(f,txt,exitcode) do \ { \ int err; \ if ( (err = (f) ) < 0) \ { \ ERR(txt " failed: %s\n", snd_strerror(err)); \ rc = exitcode; \ goto out; \ } \ } while(0) if (! hctl) return MMSYSERR_NOTSUPPORTED; /* Allocate areas to return information about the volume */ EXIT_ON_ERROR(snd_ctl_elem_id_malloc(&elemidp), "snd_ctl_elem_id_malloc", MMSYSERR_NOMEM); EXIT_ON_ERROR(snd_ctl_elem_value_malloc (&elemvaluep), "snd_ctl_elem_value_malloc", MMSYSERR_NOMEM); EXIT_ON_ERROR(snd_ctl_elem_info_malloc (&eleminfop), "snd_ctl_elem_info_malloc", MMSYSERR_NOMEM); snd_ctl_elem_id_clear(elemidp); snd_ctl_elem_value_clear(elemvaluep); snd_ctl_elem_info_clear(eleminfop); /* Setup and find an element id that exactly matches the characteristic we want ** FIXME: It is probably short sighted to hard code and fixate on PCM Playback Volume */ for( name = names; *name; name++ ) { snd_ctl_elem_id_set_name(elemidp, *name); snd_ctl_elem_id_set_interface(elemidp, SND_CTL_ELEM_IFACE_MIXER); elem = snd_hctl_find_elem(hctl, elemidp); if (elem) { /* Read and return volume information */ EXIT_ON_ERROR(snd_hctl_elem_info(elem, eleminfop), "snd_hctl_elem_info", MMSYSERR_NOTSUPPORTED); value_count = snd_ctl_elem_info_get_count(eleminfop); if (out_min || out_max || out_step) { if (!snd_ctl_elem_info_is_readable(eleminfop)) { ERR("snd_ctl_elem_info_is_readable returned false; cannot return info\n"); rc = MMSYSERR_NOTSUPPORTED; goto out; } if (out_min) *out_min = snd_ctl_elem_info_get_min(eleminfop); if (out_max) *out_max = snd_ctl_elem_info_get_max(eleminfop); if (out_step) *out_step = snd_ctl_elem_info_get_step(eleminfop); } if (out_left || out_right) { EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED); if (out_left) *out_left = snd_ctl_elem_value_get_integer(elemvaluep, 0); if (out_right) { if (value_count == 1) *out_right = snd_ctl_elem_value_get_integer(elemvaluep, 0); else if (value_count == 2) *out_right = snd_ctl_elem_value_get_integer(elemvaluep, 1); else { ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while getting volume info\n", value_count); rc = -1; goto out; } } } /* Set the volume */ if (new_left || new_right) { EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED); if (new_left) snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_left); if (new_right) { if (value_count == 1) snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_right); else if (value_count == 2) snd_ctl_elem_value_set_integer(elemvaluep, 1, *new_right); else { ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while setting volume info\n", value_count); rc = -1; goto out; } } EXIT_ON_ERROR(snd_hctl_elem_write(elem, elemvaluep), "snd_hctl_elem_write", MMSYSERR_NOTSUPPORTED); } break; } } if( !*name ) { ERR("Could not find '{PCM,Line} Playback Volume' element\n"); rc = MMSYSERR_NOTSUPPORTED; } #undef EXIT_ON_ERROR out: if (elemvaluep) snd_ctl_elem_value_free(elemvaluep); if (eleminfop) snd_ctl_elem_info_free(eleminfop); if (elemidp) snd_ctl_elem_id_free(elemidp); return rc; }
status_t ALSAControl::set(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_id_alloca(&id); snd_ctl_elem_info_alloca(&info); 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; } if (index == -1) index = 0; // Range over all of them else count = index + 1; // Just do the one specified snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info); snd_ctl_elem_value_t *control; snd_ctl_elem_value_alloca(&control); snd_ctl_elem_info_get_id(info, id); snd_ctl_elem_value_set_id(control, id); for (int i = index; i < count; i++) switch (type) { case SND_CTL_ELEM_TYPE_BOOLEAN: snd_ctl_elem_value_set_boolean(control, i, value); break; case SND_CTL_ELEM_TYPE_INTEGER: snd_ctl_elem_value_set_integer(control, i, value); break; case SND_CTL_ELEM_TYPE_INTEGER64: snd_ctl_elem_value_set_integer64(control, i, value); break; case SND_CTL_ELEM_TYPE_ENUMERATED: snd_ctl_elem_value_set_enumerated(control, i, value); break; case SND_CTL_ELEM_TYPE_BYTES: snd_ctl_elem_value_set_byte(control, i, value); break; default: break; } ret = snd_ctl_elem_write(mHandle, control); return (ret < 0) ? BAD_VALUE : NO_ERROR; }
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; }