static snd_mixer_elem_t *find_mixer_elem_by_name(const char *goal_name) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid = NULL; snd_mixer_selem_id_malloc(&sid); for (elem = snd_mixer_first_elem(alsa_mixer_handle); elem; elem = snd_mixer_elem_next(elem)) { const char *name; snd_mixer_selem_get_id(elem, sid); name = snd_mixer_selem_id_get_name(sid); d_print("name = %s\n", name); d_print("has playback volume = %d\n", snd_mixer_selem_has_playback_volume(elem)); d_print("has playback switch = %d\n", snd_mixer_selem_has_playback_switch(elem)); if (strcasecmp(name, goal_name) == 0) { if (!snd_mixer_selem_has_playback_volume(elem)) { d_print("mixer element `%s' does not have playback volume\n", name); elem = NULL; } break; } } snd_mixer_selem_id_free(sid); return elem; }
static int alsa_mixer_open(int *volume_max) { snd_mixer_selem_id_t *sid; snd_mixer_elem_t *elem; int count; int rc; snd_mixer_selem_id_alloca(&sid); rc = snd_mixer_open(&alsa_mixer_handle, 0); if (rc < 0) goto error; rc = snd_mixer_attach(alsa_mixer_handle, alsa_mixer_device); if (rc < 0) goto error; rc = snd_mixer_selem_register(alsa_mixer_handle, NULL, NULL); if (rc < 0) goto error; rc = snd_mixer_load(alsa_mixer_handle); if (rc < 0) goto error; count = snd_mixer_get_count(alsa_mixer_handle); if (count == 0) { d_print("error: mixer does not have elements\n"); return -2; } elem = snd_mixer_first_elem(alsa_mixer_handle); while (elem) { const char *name; int has_vol, has_switch; snd_mixer_selem_get_id(elem, sid); name = snd_mixer_selem_id_get_name(sid); d_print("name = %s\n", name); d_print("has playback volume = %d\n", snd_mixer_selem_has_playback_volume(elem)); d_print("has playback switch = %d\n", snd_mixer_selem_has_playback_switch(elem)); if (strcasecmp(name, alsa_mixer_element)) { elem = snd_mixer_elem_next(elem); continue; } has_vol = snd_mixer_selem_has_playback_volume(elem); if (!has_vol) { d_print("mixer element `%s' does not have playback volume\n", name); return -2; } snd_mixer_selem_get_playback_volume_range(elem, &mixer_vol_min, &mixer_vol_max); has_switch = snd_mixer_selem_has_playback_switch(elem); /* FIXME: get number of channels */ mixer_elem = elem; *volume_max = mixer_vol_max - mixer_vol_min; return 0; } d_print("error: mixer element `%s' not found\n", alsa_mixer_element); return -2; error: d_print("error: %s\n", snd_strerror(rc)); return -1; }
void refocus_control(void) { if (focus_control_index < controls_count) { snd_mixer_selem_get_id(controls[focus_control_index].elem, current_selem_id); current_control_flags = controls[focus_control_index].flags; } display_controls(); }
void moko_alsa_volume_control_set_element_from_name (MokoAlsaVolumeControl *control, const gchar *name) { MokoAlsaVolumeControlPrivate *priv = ALSA_VOLUME_CONTROL_PRIVATE (control); if (!priv->device) return; detach_mixer (control); if (!name) { moko_alsa_volume_control_set_element (control, NULL); return; } open_mixer (control); if ((snd_mixer_attach (priv->mixer_handle, priv->device) == 0) && (snd_mixer_selem_register (priv->mixer_handle, NULL, NULL) == 0) && (snd_mixer_load (priv->mixer_handle) == 0)) { snd_mixer_elem_t *elem; elem = snd_mixer_first_elem (priv->mixer_handle); while (elem) { const char *elem_name = snd_mixer_selem_get_name (elem); if (strcmp (elem_name, name) == 0) break; elem = snd_mixer_elem_next (elem); } if (!elem) { snd_mixer_detach (priv->mixer_handle, priv->device); close_mixer (control); g_warning ("Mixer element '%s' not found", name); attach_mixer (control); } else { snd_mixer_selem_id_t *id; if (snd_mixer_selem_id_malloc (&id) != 0) { g_warning ("Unable to allocate element id"); snd_mixer_detach ( priv->mixer_handle, priv->device); close_mixer (control); } else { snd_mixer_selem_get_id (elem, id); snd_mixer_detach ( priv->mixer_handle, priv->device); close_mixer (control); g_debug ("Setting element ID"); moko_alsa_volume_control_set_element ( control, id); snd_mixer_selem_id_free (id); } } } else g_warning ("Unable to open mixer on card '%s'", priv->device); }
static int on_mixer_event(snd_mixer_t *handle, unsigned int mask, snd_mixer_elem_t *elem) { snd_mixer_selem_id_t *sid; if(mask & SND_CTL_EVENT_MASK_ADD) { snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_get_id(elem, sid); DEBUG("set callback for mixer control = %s\n", snd_mixer_selem_id_get_name(sid)); snd_mixer_elem_set_callback(elem, on_mixer_elem_event); } return 0; }
static int on_mixer_elem_event(snd_mixer_elem_t *elem, unsigned int mask) { snd_mixer_selem_id_t *sid; void *data = NULL; if(elem) data = snd_mixer_elem_get_callback_private(elem); if(data) { long min, max, Rvol, Lvol; snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_get_id(elem, sid); DEBUG("mixer elem control = %s, mask = %x, data = %x\n", snd_mixer_selem_id_get_name(sid), mask, data); if(mask & SND_CTL_EVENT_MASK_VALUE) { char path[1024] = {0}; alsa_mixer_t *mixer = (alsa_mixer_t *)g_object_get_data(G_OBJECT(data), "mixer-obj"); GtkWidget *img = (GtkWidget *)g_object_get_data(G_OBJECT(data), "image-obj"); DEBUG("mixer = %x, img = %x\n", mixer, img); if(snd_mixer_selem_has_playback_volume(elem)) { if(mixer->pcm_muted != alsa_mixer_is_muted(elem, NULL)) { mixer->pcm_muted = !mixer->pcm_muted; g_snprintf(path, 1024, DVM_CONFIG_PATH"/%s", g_playback_iconset[mixer->pcm_muted ? 3: 0]); DEBUG("playback switch detected, image path = %s\n", path); gtk_image_set_from_file(GTK_IMAGE(img), path); } snd_mixer_selem_get_playback_volume(elem, 0, &Rvol); snd_mixer_selem_get_playback_volume(elem, 1, &Lvol); snd_mixer_selem_get_playback_volume_range(elem, &min, &max); DEBUG("new val = %d, %d, min = %d, max = %d\n", Rvol, Lvol, min, max); } else if(snd_mixer_selem_has_capture_volume(elem)) { if(mixer->mic_muted != alsa_mixer_is_muted(elem, NULL)) { mixer->mic_muted = !mixer->mic_muted; g_snprintf(path, 1024, DVM_CONFIG_PATH"/%s", g_capture_iconset[mixer->mic_muted ? 3: 0]); DEBUG("capture switch detected, image path = %s\n", path); gtk_image_set_from_file(GTK_IMAGE(img), path); } snd_mixer_selem_get_capture_volume_range(elem, &min, &max); snd_mixer_selem_get_capture_volume(elem, 0, &Rvol); snd_mixer_selem_get_capture_volume(elem, 1, &Lvol); DEBUG("new val = %d, %d, min = %d, max = %d\n", Rvol, Lvol, min, max); } g_mixer_ui_updated = TRUE; gtk_adjustment_set_value(GTK_ADJUSTMENT(data), ((gdouble)(Rvol+Lvol)*50)/(max-min)); } } return 0; }
/* * The purpose of this function is to let the user to select * the input where he plugged his signals. * Now if user select "default", as device, we have to select the input * on the mixer of the card used by "default". * What is the card used by device "default" ? */ static void as_setup_input_combo (GtkWidget *combo, SoundParams *sparams) { snd_mixer_t *handle; int i ; snd_mixer_selem_id_t *sid; snd_mixer_elem_t *elem; snd_mixer_selem_id_alloca(&sid); char *devname; char name[32]; devname = sparams->device_name; if ( *sparams->indexstr == '-' ) { sprintf(name, "hw:%d", sparams->firstcard); devname = name; } handle = sound_open_mixer(devname); if ( handle == NULL ){ return ; } for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) { snd_mixer_selem_get_id(elem, sid); if (! snd_mixer_selem_is_active(elem)) { continue; } const char *control_name = snd_mixer_selem_id_get_name(sid); // printf("Simple mixer control '%s',%i\n", control_name, snd_mixer_selem_id_get_index(sid)); if (snd_mixer_selem_is_enum_capture(elem)) { int items; char itemname[40]; app_free(sparams->control_name); sparams->control_name = app_strdup(control_name); items = snd_mixer_selem_get_enum_items(elem); // printf(" Items:"); for (i = 0; i < items; i++) { snd_mixer_selem_get_enum_item_name(elem, i, sizeof(itemname) - 1, itemname); // printf(" '%s'", itemname); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), itemname ); if ( i == sparams->input ) { gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i); } } // printf("\n"); } } snd_mixer_close(handle); return ; }
void list_mixers(const char *output_device) { int err; snd_mixer_t *handle; snd_mixer_selem_id_t *sid; snd_mixer_elem_t *elem; char *ctl = ctl4device(output_device); snd_mixer_selem_id_alloca(&sid); LOG_INFO("listing mixers for: %s", output_device); if ((err = snd_mixer_open(&handle, 0)) < 0) { LOG_ERROR("open error: %s", snd_strerror(err)); return; } if ((err = snd_mixer_attach(handle, ctl)) < 0) { LOG_ERROR("attach error: %s", snd_strerror(err)); snd_mixer_close(handle); free(ctl); return; } free(ctl); if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { LOG_ERROR("register error: %s", snd_strerror(err)); snd_mixer_close(handle); return; } if ((err = snd_mixer_load(handle)) < 0) { LOG_ERROR("load error: %s", snd_strerror(err)); snd_mixer_close(handle); return; } printf("Volume controls for %s\n", output_device); for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_selem_has_playback_volume(elem)) { snd_mixer_selem_get_id(elem, sid); printf(" %s", snd_mixer_selem_id_get_name(sid)); if (snd_mixer_selem_id_get_index(sid)) { printf(",%d", snd_mixer_selem_id_get_index(sid)); } printf("\n"); } } printf("\n"); snd_mixer_close(handle); }
void SoundPref::getMixerDevices(int mode) { snd_mixer_t *mixer; QComboBox *cmb; if (mode == modePlayback) cmb = ui.playbackMixerDeviceCmb; else { // TODO : capture mixer devices } cmb->clear(); int err; if ((err = snd->getMixer(&mixer, mixerCard)) < 0) { return; } snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); int indx = 0; int current = -1; cmb->addItem(""); for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem)) { snd_mixer_selem_get_id(elem, sid); if (!snd_mixer_selem_is_active(elem)) continue; QString device = snd_mixer_selem_id_get_name(sid); if (mode == modePlayback) { if (snd_mixer_selem_has_playback_volume(elem)) cmb->addItem(device); } else if (mode == modeCapture) { // TODO: } else continue; if (device == mixerDevice) { current = indx; } indx ++; } if (current >= 0) cmb->setCurrentIndex(current+1); snd_mixer_close(mixer); }
void lamixer_mixer_init(char card[64]) { snd_mixer_elem_t *elem; gint err; snd_mixer_selem_id_alloca(&sid); err = snd_mixer_open (&mixer_handle, 0); err = snd_mixer_attach (mixer_handle, card); err = snd_mixer_selem_register (mixer_handle, NULL, NULL); err = snd_mixer_load (mixer_handle); for (elem = snd_mixer_first_elem(mixer_handle); elem; elem = snd_mixer_elem_next(elem)) { snd_mixer_selem_get_id(elem, sid); if (!snd_mixer_selem_is_active(elem)) continue; VolumeBoxes = g_list_append(VolumeBoxes, lamixer_volelem_new(elem)); } }
static int open_mixer(PxDev *dev, int card, int playback) { snd_mixer_elem_t *elem; char name[256]; int err; int i; sprintf(name, "hw:%d", card); dev->card = card; dev->handle = NULL; do { err = snd_mixer_open(&dev->handle, 0); if (err < 0) { break; } err = snd_mixer_attach(dev->handle, name); if (err < 0) { break; } err = snd_mixer_selem_register(dev->handle, NULL, NULL); if (err < 0) { break; } err = snd_mixer_load(dev->handle); if (err < 0) { break; } for (elem = snd_mixer_first_elem(dev->handle); elem != NULL; elem = snd_mixer_elem_next(elem)) { if (!playback) { if (!snd_mixer_selem_has_capture_volume(elem) && !snd_mixer_selem_has_capture_switch(elem) && !snd_mixer_selem_has_common_volume(elem)) { continue; } } else { if (!snd_mixer_selem_has_playback_volume(elem) && !snd_mixer_selem_has_playback_switch(elem) && !snd_mixer_selem_has_common_volume(elem)) { continue; } } dev->numselems++; } dev->selems = calloc(dev->numselems, sizeof(PxSelem)); if (dev->selems == NULL) { break; } i = 0; for (elem = snd_mixer_first_elem(dev->handle); elem != NULL; elem = snd_mixer_elem_next(elem)) { if (!playback) { if (!snd_mixer_selem_has_capture_volume(elem) && !snd_mixer_selem_has_capture_switch(elem) && !snd_mixer_selem_has_common_volume(elem)) { continue; } } else { if (!snd_mixer_selem_has_playback_volume(elem) && !snd_mixer_selem_has_playback_switch(elem) && !snd_mixer_selem_has_common_volume(elem)) { continue; } } if (snd_mixer_selem_id_malloc(&dev->selems[i].sid) < 0) { break; } snd_mixer_selem_get_id(elem, dev->selems[i].sid); dev->selems[i].elem = elem; snprintf(name, sizeof(name), "%s:%d", snd_mixer_selem_id_get_name(dev->selems[i].sid), snd_mixer_selem_id_get_index(dev->selems[i].sid)); dev->selems[i].name = strdup(name); if (!dev->selems[i].name) { break; } i++; } if (i == dev->numselems) { return TRUE; } } while (FALSE); if (dev->selems) { for (i = 0; i < dev->numselems; i++) { if (dev->selems[i].sid) { snd_mixer_selem_id_free(dev->selems[i].sid); } if (dev->selems[i].name) { free(dev->selems[i].name); } } free(dev->selems); dev->selems = NULL; } if (dev->handle) { snd_mixer_close(dev->handle); dev->handle = NULL; } return FALSE; }
static int mixer_open(void) { snd_mixer_elem_t *elem; snd_mixer_elem_t *master; snd_mixer_elem_t *pcm; snd_mixer_elem_t *custom; snd_mixer_selem_id_t *sid; int ret; ret = snd_mixer_open(&mixer_hdl, 0); if (ret < 0) { DPRINTF(E_LOG, L_LAUDIO, "Failed to open mixer: %s\n", snd_strerror(ret)); mixer_hdl = NULL; return -1; } ret = snd_mixer_attach(mixer_hdl, card_name); if (ret < 0) { DPRINTF(E_LOG, L_LAUDIO, "Failed to attach mixer: %s\n", snd_strerror(ret)); goto out_close; } ret = snd_mixer_selem_register(mixer_hdl, NULL, NULL); if (ret < 0) { DPRINTF(E_LOG, L_LAUDIO, "Failed to register mixer: %s\n", snd_strerror(ret)); goto out_detach; } ret = snd_mixer_load(mixer_hdl); if (ret < 0) { DPRINTF(E_LOG, L_LAUDIO, "Failed to load mixer: %s\n", snd_strerror(ret)); goto out_detach; } /* Grab interesting elements */ snd_mixer_selem_id_alloca(&sid); pcm = NULL; master = NULL; custom = NULL; for (elem = snd_mixer_first_elem(mixer_hdl); elem; elem = snd_mixer_elem_next(elem)) { snd_mixer_selem_get_id(elem, sid); if (mixer_name && (strcmp(snd_mixer_selem_id_get_name(sid), mixer_name) == 0)) { custom = elem; break; } else if (strcmp(snd_mixer_selem_id_get_name(sid), "PCM") == 0) pcm = elem; else if (strcmp(snd_mixer_selem_id_get_name(sid), "Master") == 0) master = elem; } if (mixer_name) { if (custom) vol_elem = custom; else { DPRINTF(E_LOG, L_LAUDIO, "Failed to open configured mixer element '%s'\n", mixer_name); goto out_detach; } } else if (pcm) vol_elem = pcm; else if (master) vol_elem = master; else { DPRINTF(E_LOG, L_LAUDIO, "Failed to open PCM or Master mixer element\n"); goto out_detach; } /* Get min & max volume */ snd_mixer_selem_get_playback_volume_range(vol_elem, &vol_min, &vol_max); return 0; out_detach: snd_mixer_detach(mixer_hdl, card_name); out_close: snd_mixer_close(mixer_hdl); mixer_hdl = NULL; vol_elem = NULL; return -1; }
bool LapsusAlsaMixer::init() { int err; snd_ctl_t *ctl_handle; snd_ctl_card_info_t *hw_info; snd_ctl_card_info_alloca(&hw_info); if ((err = snd_ctl_open (&ctl_handle, "default", 0)) < 0) return false; if ((err = snd_ctl_card_info (ctl_handle, hw_info)) < 0) return false; snd_ctl_close (ctl_handle); if ((err = snd_mixer_open (&_handle, 0)) < 0) return false; if ((err = snd_mixer_attach (_handle, "default")) < 0) return false; if ((err = snd_mixer_selem_register (_handle, 0, 0)) < 0) return false; if ((err = snd_mixer_load (_handle)) < 0) return false; // printf("Card name: '%s'\n", snd_ctl_card_info_get_name(hw_info)); // printf("Device name: '%s'\n", snd_ctl_card_info_get_mixername(hw_info)); snd_mixer_elem_t *elem; snd_mixer_selem_id_t *tmp_sid = 0; for (elem = snd_mixer_first_elem(_handle); elem; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_selem_is_active(elem)) { if (!tmp_sid) tmp_sid = (snd_mixer_selem_id_t*) malloc(snd_mixer_selem_id_sizeof()); snd_mixer_selem_get_id(elem, tmp_sid); const char *name = snd_mixer_selem_id_get_name( tmp_sid ); if (!strcasecmp(name, "Headphone")) { if (sids[ID_HP]) delete sids[ID_HP]; sids[ID_HP] = new SIDInfo(_handle, tmp_sid); tmp_sid = 0; } else if (!strcasecmp(name, "Front")) { if (sids[ID_F]) delete sids[ID_F]; sids[ID_F] = new SIDInfo(_handle, tmp_sid); tmp_sid = 0; } else if (!strcasecmp(name, "Master")) { if (sids[ID_M]) delete sids[ID_M]; sids[ID_M] = new SIDInfo(_handle, tmp_sid); tmp_sid = 0; } } } if (tmp_sid) free(tmp_sid); bool foundAny = false; for (int i = 0; i < ID_LAST; ++i) { if (sids[i]) { if (sids[i]->hasMute) { foundAny = true; } if (sids[i]->hasVolume) { foundAny = true; long range = sids[i]->max - sids[i]->min; if (range > _globalMax) _globalMax = range; } } } if (_globalMax > INT_MAX) _globalMax = INT_MAX; if (!foundAny) return false; for (int i = 0; i < ID_LAST; ++i) { if (sids[i]) sids[i]->setGlobalMax(_globalMax); } if ((_count = snd_mixer_poll_descriptors_count(_handle)) < 0) return false; _fds = (struct pollfd*) calloc(_count, sizeof(struct pollfd)); if (!_fds) return false; if ((err = snd_mixer_poll_descriptors(_handle, _fds, _count)) < 0) return false; if (err != _count) return 0; _sns = new QSocketNotifier*[_count]; for ( int i = 0; i < _count; ++i ) { _sns[i] = new QSocketNotifier(_fds[i].fd, QSocketNotifier::Read); connect(_sns[i], SIGNAL(activated(int)), this, SLOT(alsaEvent())); } // To read our current parameters. Signals will be emited, but those signals // are not yet connected to anything - this method is called from constructor // only. getVolume(); mixerIsMuted(); return true; }
ALSAMixer::ALSAMixer(const char *sndcard) { int err; LOGI(" Init ALSAMIXER for SNDCARD : %s",sndcard); mixerMasterProp = ALSA_PROP(AudioSystem::DEVICE_OUT_ALL, "master", "PCM", "Capture"); mixerProp = { ALSA_PROP(AudioSystem::DEVICE_OUT_EARPIECE, "earpiece", "Earpiece", "Capture"), ALSA_PROP(AudioSystem::DEVICE_OUT_SPEAKER, "speaker", "Speaker", ""), ALSA_PROP(AudioSystem::DEVICE_OUT_WIRED_HEADSET, "headset", "Headphone", "Capture"), ALSA_PROP(AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, "bluetooth.sco", "Bluetooth", "Bluetooth Capture"), ALSA_PROP(AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, "bluetooth.a2dp", "Bluetooth A2DP", "Bluetooth A2DP Capture"), ALSA_PROP(static_cast<AudioSystem::audio_devices>(0), "", NULL, NULL) }; initMixer (&mMixer[SND_PCM_STREAM_PLAYBACK], sndcard); initMixer (&mMixer[SND_PCM_STREAM_CAPTURE], sndcard); snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); for (int i = 0; i <= SND_PCM_STREAM_LAST; i++) { mixer_info_t *info = mixerMasterProp[i].mInfo = new mixer_info_t; property_get (mixerMasterProp[i].propName, info->name, mixerMasterProp[i].propDefault); for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; snd_mixer_selem_get_id(elem, sid); // Find PCM playback volume control element. const char *elementName = snd_mixer_selem_id_get_name(sid); if (info->elem == NULL && strcmp(elementName, info->name) == 0 && hasVolume[i] (elem)) { info->elem = elem; getVolumeRange[i] (elem, &info->min, &info->max); info->volume = info->max; setVol[i] (elem, info->volume); if (i == SND_PCM_STREAM_PLAYBACK && snd_mixer_selem_has_playback_switch (elem)) snd_mixer_selem_set_playback_switch_all (elem, 1); break; } } LOGV("Mixer: master '%s' %s.", info->name, info->elem ? "found" : "not found"); for (int j = 0; mixerProp[j][i].device; j++) { mixer_info_t *info = mixerProp[j][i].mInfo = new mixer_info_t; property_get (mixerProp[j][i].propName, info->name, mixerProp[j][i].propDefault); for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; snd_mixer_selem_get_id(elem, sid); // Find PCM playback volume control element. const char *elementName = snd_mixer_selem_id_get_name(sid); if (info->elem == NULL && strcmp(elementName, info->name) == 0 && hasVolume[i] (elem)) { info->elem = elem; getVolumeRange[i] (elem, &info->min, &info->max); info->volume = info->max; setVol[i] (elem, info->volume); if (i == SND_PCM_STREAM_PLAYBACK && snd_mixer_selem_has_playback_switch (elem)) snd_mixer_selem_set_playback_switch_all (elem, 1); break; } } LOGV("Mixer: route '%s' %s.", info->name, info->elem ? "found" : "not found"); } } LOGV("mixer initialized."); }
/****************************************************************************** * setMixerVolume *****************************************************************************/ static Int setMixerVolume (Sound_Attrs *attrs) { Int status; snd_mixer_t *rcMixer; snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; snd_mixer_selem_id_malloc (&sid); /* Open the mixer device */ status = snd_mixer_open (&rcMixer, 0); if ( status<0 ) { Dmai_err2 ("Failed to open mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } /* Attach mixer with sound card */ status = snd_mixer_attach (rcMixer,AUDIO_MIXER); if (status <0) { Dmai_err2 ("Failed to attach mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } /* Register mixer with selected elements */ status = snd_mixer_selem_register (rcMixer, NULL, NULL); if (status <0) { Dmai_err2 ("Failed to register mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } /* Load mixer */ status = snd_mixer_load (rcMixer); if (status <0) { Dmai_err2 ("Failed to load mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } for (elem = snd_mixer_first_elem (rcMixer); elem; elem=snd_mixer_elem_next(elem)) { snd_mixer_selem_get_id(elem,sid); if (!snd_mixer_selem_is_active(elem)) continue; if (attrs->mode == Sound_Mode_OUTPUT || attrs->mode == Sound_Mode_FULLDUPLEX) { if (snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) snd_mixer_selem_set_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain); if (snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) snd_mixer_selem_set_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain); } if (attrs->mode == Sound_Mode_INPUT || attrs->mode == Sound_Mode_FULLDUPLEX) { if (snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) snd_mixer_selem_set_capture_volume (elem, SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain); if (snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) snd_mixer_selem_set_capture_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain); } } snd_mixer_selem_id_free (sid); snd_mixer_close (rcMixer); return Dmai_EOK; }
ALSAMixer::ALSAMixer() { int err; initMixer (&mMixer[SND_PCM_STREAM_PLAYBACK], "AndroidOut"); initMixer (&mMixer[SND_PCM_STREAM_CAPTURE], "AndroidIn"); snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); for (int i = 0; i <= SND_PCM_STREAM_LAST; i++) { mixer_info_t *info = mixerMasterProp[i].mInfo = new mixer_info_t; property_get (mixerMasterProp[i].propName, info->name, mixerMasterProp[i].propDefault); for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; snd_mixer_selem_get_id(elem, sid); // Find PCM playback volume control element. const char *elementName = snd_mixer_selem_id_get_name(sid); if (info->elem == NULL && strcmp(elementName, info->name) == 0 && hasVolume[i] (elem)) { info->elem = elem; getVolumeRange[i] (elem, &info->min, &info->max); info->volume = info->max; setVol[i] (elem, info->volume); if (i == SND_PCM_STREAM_PLAYBACK && snd_mixer_selem_has_playback_switch (elem)) snd_mixer_selem_set_playback_switch_all (elem, 1); break; } } LOGV("Mixer: master '%s' %s.", info->name, info->elem ? "found" : "not found"); for (int j = 0; mixerProp[j][i].device; j++) { mixer_info_t *info = mixerProp[j][i].mInfo = new mixer_info_t; property_get (mixerProp[j][i].propName, info->name, mixerProp[j][i].propDefault); for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; snd_mixer_selem_get_id(elem, sid); // Find PCM playback volume control element. const char *elementName = snd_mixer_selem_id_get_name(sid); if (info->elem == NULL && strcmp(elementName, info->name) == 0 && hasVolume[i] (elem)) { info->elem = elem; getVolumeRange[i] (elem, &info->min, &info->max); info->volume = info->max; setVol[i] (elem, info->volume); if (i == SND_PCM_STREAM_PLAYBACK && snd_mixer_selem_has_playback_switch (elem)) snd_mixer_selem_set_playback_switch_all (elem, 1); break; } } LOGV("Mixer: route '%s' %s.", info->name, info->elem ? "found" : "not found"); } } #ifdef AUDIO_MODEM_TI ALSAControl control("hw:00"); status_t error; #if 0//(WORKAROUND_AVOID_VOICE_VOLUME_SATURATION == 1) //[LG_FW_P970_MERGE] - jungsoo1221.lee LOGV("Workaround: Voice call max volume limited to: %d", WORKAROUND_MAX_VOICE_VOLUME); #endif #if 0//(WORKAROUND_SET_VOICE_VOLUME_MIN == 1) //[LG_FW_P970_MERGE] - jungsoo1221.lee LOGV("Workaround: Voice call min volume limited to: %d", WORKAROUND_MIN_VOICE_VOLUME); #endif for (int i = 0; inCallVolumeProp[i].device; i++) { mixer_incall_vol_info_t *info = inCallVolumeProp[i].mInfo = new mixer_incall_vol_info_t; property_get (inCallVolumeProp[i].propName, info->name, inCallVolumeProp[i].propDefault); error = control.get(info->name, info->volume, 0); error = control.getmin(info->name, info->min); error = control.getmax(info->name, info->max); #if 0//(WORKAROUND_AVOID_VOICE_VOLUME_SATURATION == 1) //[LG_FW_P970_MERGE] - jungsoo1221.lee info->max = WORKAROUND_MAX_VOICE_VOLUME; #endif #if 0//(WORKAROUND_SET_VOICE_VOLUME_MIN == 1) //[LG_FW_P970_MERGE] - jungsoo1221.lee info->min = WORKAROUND_MIN_VOICE_VOLUME; #endif if (error < 0) { LOGV("Mixer: In Call Volume '%s': not found", info->name); } else { LOGV("Mixer: In Call Volume '%s': vol. %d min. %d max. %d", info->name, info->volume, info->min, info->max); } } #endif LOGV("mixer initialized."); }
ALSAMixer::ALSAMixer() { int err; initMixer (&mMixer[SND_PCM_STREAM_PLAYBACK], "AndroidOut"); initMixer (&mMixer[SND_PCM_STREAM_CAPTURE], "AndroidIn"); snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); for (int i = 0; i <= SND_PCM_STREAM_LAST; i++) { if (!mMixer[i]) continue; mixer_info_t *info = mixerMasterProp[i].mInfo = new mixer_info_t; property_get (mixerMasterProp[i].propName, info->name, mixerMasterProp[i].propDefault); for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; snd_mixer_selem_get_id(elem, sid); // Find PCM playback volume control element. const char *elementName = snd_mixer_selem_id_get_name(sid); if (info->elem == NULL && strcmp(elementName, info->name) == 0 && hasVolume[i] (elem)) { info->elem = elem; getVolumeRange[i] (elem, &info->min, &info->max); //info->volume = info->max; //setVol[i] (elem, info->volume); //if (i == SND_PCM_STREAM_PLAYBACK && // snd_mixer_selem_has_playback_switch (elem)) // snd_mixer_selem_set_playback_switch_all (elem, 1); break; } } ALOGV("Mixer: master '%s' %s.", info->name, info->elem ? "found" : "not found"); for (int j = 0; mixerProp[j][i].device; j++) { mixer_info_t *info = mixerProp[j][i].mInfo = new mixer_info_t; property_get (mixerProp[j][i].propName, info->name, mixerProp[j][i].propDefault); for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; snd_mixer_selem_get_id(elem, sid); // Find PCM playback volume control element. const char *elementName = snd_mixer_selem_id_get_name(sid); if (info->elem == NULL && strcmp(elementName, info->name) == 0 && hasVolume[i] (elem)) { info->elem = elem; getVolumeRange[i] (elem, &info->min, &info->max); //info->volume = info->max; //setVol[i] (elem, info->volume); //if (i == SND_PCM_STREAM_PLAYBACK && // snd_mixer_selem_has_playback_switch (elem)) // snd_mixer_selem_set_playback_switch_all (elem, 1); break; } } ALOGV("Mixer: route '%s' %s.", info->name, info->elem ? "found" : "not found"); } } ALOGV("mixer initialized."); }
static int alsa_mixer_init(alsa_mixer_t *mixer, char *card) { snd_mixer_selem_id_t *sid; snd_mixer_elem_t *elem; snd_mixer_selem_id_alloca(&sid); int err; if ((err = snd_mixer_open(&mixer->handle, 0)) < 0) { DEBUG("Mixer %s open error: %s", card, snd_strerror(err)); mixer->handle = NULL; return err; } if ((err = snd_mixer_attach(mixer->handle, card)) < 0) { DEBUG("Mixer %s local error: %s\n", card, snd_strerror(err)); snd_mixer_close(mixer->handle); mixer->handle = NULL; return err; } if ((err = snd_mixer_selem_register(mixer->handle, NULL, NULL)) < 0) { DEBUG("Mixer register error: %s", snd_strerror(err)); snd_mixer_close(mixer->handle); return err; } snd_mixer_set_callback(mixer->handle, on_mixer_event); err = snd_mixer_load(mixer->handle); if (err < 0) { DEBUG("Mixer %s load error: %s", card, snd_strerror(err)); snd_mixer_close(mixer->handle); return err; } for (elem = snd_mixer_first_elem(mixer->handle); elem; elem = snd_mixer_elem_next(elem)) { const char *name = NULL; snd_mixer_selem_get_id(elem, sid); if (!snd_mixer_selem_is_active(elem)) continue; name = snd_mixer_selem_id_get_name(sid); if(snd_mixer_selem_has_playback_volume(elem)) { if(strcmp(name, "Master") == 0) mixer->master = elem; else if(strcmp(name, "PCM") == 0) mixer->pcm = elem; } else if(snd_mixer_selem_has_capture_volume(elem) || snd_mixer_selem_has_capture_switch(elem)) { DEBUG("capture elem name = %s\n", name); /**make sure have one capture source if capture is available*/ if(NULL == mixer->mic) { mixer->mic = elem; } /**if have Microphone, replace it*/ if(strcmp(name, "Microphone") == 0) mixer->mic = elem; if(strcmp(name, "Capture") == 0) mixer->mic = elem; } } DEBUG("master = %x, pcm = %x, microphone = %x\n", mixer->master, mixer->pcm, mixer->mic); return 0; }