static void balance_volumes(void) { struct control *control; long left, right; int err; control = get_focus_control(TYPE_PVOLUME | TYPE_CVOLUME); if (!control || !(control->flags & HAS_VOLUME_1)) return; if (control->flags & TYPE_PVOLUME) { err = snd_mixer_selem_get_playback_volume(control->elem, control->volume_channels[0], &left); if (err < 0) return; err = snd_mixer_selem_get_playback_volume(control->elem, control->volume_channels[1], &right); if (err < 0) return; } else { err = snd_mixer_selem_get_capture_volume(control->elem, control->volume_channels[0], &left); if (err < 0) return; err = snd_mixer_selem_get_capture_volume(control->elem, control->volume_channels[1], &right); if (err < 0) return; } left = (left + right) / 2; if (control->flags & TYPE_PVOLUME) { snd_mixer_selem_set_playback_volume(control->elem, control->volume_channels[0], left); snd_mixer_selem_set_playback_volume(control->elem, control->volume_channels[1], left); } else { snd_mixer_selem_set_capture_volume(control->elem, control->volume_channels[0], left); snd_mixer_selem_set_capture_volume(control->elem, control->volume_channels[1], left); } display_controls(); }
static gint gam_slider_pan_get_volume (GamSliderPan *gam_slider_pan) { glong left_chn, right_chn, pmin, pmax; if (snd_mixer_selem_has_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) snd_mixer_selem_get_playback_volume_range (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), &pmin, &pmax); else snd_mixer_selem_get_capture_volume_range (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), &pmin, &pmax); if (snd_mixer_selem_has_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) snd_mixer_selem_get_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_LEFT, &left_chn); else snd_mixer_selem_get_capture_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_LEFT, &left_chn); if (snd_mixer_selem_is_playback_mono (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) { return rint (100 - (left_chn * (100 / (gfloat)pmax))); } else { if (snd_mixer_selem_has_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) snd_mixer_selem_get_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_RIGHT, &right_chn); else snd_mixer_selem_get_capture_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_RIGHT, &right_chn); return rint (100 - (MAX(left_chn, right_chn) * (100 / (gfloat)pmax))); } }
static gboolean alsa_mixer_is_muted(snd_mixer_elem_t *elem, gboolean *need_reset) { int sw; long Rvol, Lvol, min, max; if(need_reset) *need_reset = FALSE; /**if switch is available, get switch status directly*/ if(snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_get_playback_switch(elem, 0, &sw); return sw ? FALSE: TRUE; } else if(snd_mixer_selem_has_capture_switch(elem)) { snd_mixer_selem_get_capture_switch(elem, 0, &sw); return sw ? FALSE: TRUE; } if(snd_mixer_selem_has_playback_volume(elem)) { 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); if(need_reset) *need_reset = !!(max - Rvol); return (Rvol + Lvol) ? FALSE: TRUE; } else if(snd_mixer_selem_has_capture_volume(elem)) { 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); if(need_reset) *need_reset = !!(max - Rvol); return (Rvol + Lvol) ? FALSE: TRUE; } }
void lamixer_volbox_show(VolBox *volumebox, snd_mixer_elem_t *elem, GtkWidget *mixerbox) { long rangevalue_left,rangevalue_right; int mute, *bCols; if (volumebox->type == 1) { snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); bCols = &pCols; } else if (volumebox->type == 2) { snd_mixer_selem_get_capture_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); bCols = &cCols; } volumebox->curval = rangevalue_left; gtk_table_attach(GTK_TABLE(mixerbox), volumebox->vollabel, *bCols-1, *bCols, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); gtk_range_set_value(GTK_RANGE(volumebox->volbar), rangevalue_left); gtk_box_pack_start(GTK_BOX(volumebox->volbarbox), volumebox->volbar, TRUE, TRUE, 0); volumebox->hsignalid = g_signal_connect(G_OBJECT(volumebox->volbar), "value-changed", G_CALLBACK(lamixer_volbox_changed), volumebox); if (volumebox->rvolbar != NULL) { if (volumebox->type == 1) { snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue_right); } else if (volumebox->type == 2) { snd_mixer_selem_get_capture_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue_right); } volumebox->rcurval = rangevalue_right; gtk_box_pack_start(GTK_BOX(volumebox->volbarbox), volumebox->rvolbar, TRUE, TRUE, 0); gtk_range_set_value(GTK_RANGE(volumebox->rvolbar), rangevalue_right); volumebox->hsignalidr = g_signal_connect(G_OBJECT(volumebox->rvolbar), "value-changed", G_CALLBACK(lamixer_volboxr_changed), volumebox); } gtk_table_attach(GTK_TABLE(mixerbox), volumebox->volbarbox, *bCols-1, *bCols, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0); if (volumebox->lockswitch != NULL) { gtk_table_attach(GTK_TABLE(mixerbox), volumebox->lockswitch, *bCols-1, *bCols, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(volumebox->lockswitch), TRUE); } if (volumebox->muteswitch != NULL) { snd_mixer_selem_get_playback_switch (elem, SND_MIXER_SCHN_FRONT_LEFT, &mute); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(volumebox->muteswitch), !mute); volumebox->hmutesignalid = g_signal_connect(G_OBJECT(volumebox->muteswitch), "toggled", G_CALLBACK(lamixer_muteswitch_changed), elem); gtk_table_attach(GTK_TABLE(mixerbox), volumebox->muteswitch, *bCols-1, *bCols, 3, 4, GTK_SHRINK, GTK_SHRINK, 0, 0); } gtk_table_resize(GTK_TABLE(mixerbox), mRows, ++(*bCols)); gtk_table_attach(GTK_TABLE(mixerbox), gtk_vseparator_new (), *bCols-1, *bCols, 0, 5, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 4, 0); gtk_table_resize(GTK_TABLE(mixerbox), mRows, ++(*bCols)); }
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; }
static int elem_get_vol_percent(snd_mixer_elem_t *elem) { int i, percent; long pmin, pmax, volume; for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { /* playback volume */ if (snd_mixer_selem_has_playback_channel(elem, i) && !snd_mixer_selem_has_common_volume(elem)) { snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax); if (snd_mixer_selem_has_playback_volume(elem)) snd_mixer_selem_get_playback_volume(elem, i, &volume); } /* capture volume */ else if (snd_mixer_selem_has_capture_channel(elem, i) && !snd_mixer_selem_has_common_volume(elem)) { snd_mixer_selem_get_capture_volume_range(elem, &pmin, &pmax); if (snd_mixer_selem_has_capture_volume(elem)) snd_mixer_selem_get_capture_volume(elem, i, &volume); } else { /* Misc. ex: Boost */ snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax); snd_mixer_selem_get_playback_volume(elem, i, &volume); } } percent = (int) ((double)(volume - pmin) / (double)(pmax - pmin) * 100); return percent; }
static void update_volume (MokoAlsaVolumeControl *control) { long volume; MokoAlsaVolumeControlPrivate *priv = ALSA_VOLUME_CONTROL_PRIVATE (control); /* TODO: Average out volume across channels? */ switch (priv->control_type) { case PLAYBACK : snd_mixer_selem_get_playback_volume ( priv->mixer_elem, 0, &volume); break; case CAPTURE : snd_mixer_selem_get_capture_volume ( priv->mixer_elem, 0, &volume); break; case CONTROL : default : /* TODO: Handle switches? */ g_warning ("Unhandled control type"); return; } if (priv->volume != volume) { priv->volume = volume; g_signal_emit (control, signals[VOLUME_CHANGED], 0, (gdouble)(priv->volume - priv->min) / (gdouble)(priv->max - priv->min)); } }
static void _get_volume(snd_mixer_elem_t *elem, int playback, int n, long *val) { if (playback) snd_mixer_selem_get_playback_volume(elem, n, val); else snd_mixer_selem_get_capture_volume(elem, n, val); }
static PxVolume get_volume_indexed(PxDev *dev, int i, int playback) { snd_mixer_elem_t *elem; long vol, min, max; if (!dev->handle) { return 0.0; } if (i < 0 || i > dev->numselems) { return 0.0; } elem = dev->selems[i].elem; if (playback) { snd_mixer_selem_get_playback_volume_range(elem, &min, &max); if (snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) { snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &vol); return (PxVolume) vol / (max - min); } } else { snd_mixer_selem_get_capture_volume_range(elem, &min, &max); if (snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) { snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &vol); return (PxVolume) vol / (max - min); } } return 0.0; }
static int lamixer_volbox_change(snd_mixer_elem_t *elem, unsigned int mask) { long rangevalue=0; int mutesw; MixerElem *mixer_elem; if (mask == SND_CTL_EVENT_MASK_REMOVE) return 0; if (mask & SND_CTL_EVENT_MASK_VALUE) { mixer_elem = snd_mixer_elem_get_callback_private(elem); if(mixer_elem->playback != NULL) { snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue); lamixer_volbox_check(mixer_elem->playback->volbar, mixer_elem->playback->hsignalid, rangevalue, &mixer_elem->playback->curval); if(mixer_elem->playback->rvolbar != NULL) { rangevalue=0; snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue); lamixer_volbox_check(mixer_elem->playback->rvolbar, mixer_elem->playback->hsignalidr, rangevalue, &mixer_elem->playback->rcurval); } if(mixer_elem->playback->muteswitch != NULL) { snd_mixer_selem_get_playback_switch (elem, SND_MIXER_SCHN_FRONT_LEFT, &mutesw); lamixer_switch_checkvalue(mixer_elem->playback->muteswitch, mutesw, mixer_elem->playback->hmutesignalid); } } if(mixer_elem->capture != NULL) { rangevalue=0; snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue); lamixer_volbox_check(mixer_elem->capture->volbar, mixer_elem->capture->hsignalid, rangevalue, &mixer_elem->capture->curval); if(mixer_elem->capture->rvolbar != NULL) { rangevalue=0; snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue); lamixer_volbox_check(mixer_elem->capture->rvolbar, mixer_elem->capture->hsignalidr, rangevalue, &mixer_elem->capture->rcurval); } if(mixer_elem->capture->muteswitch != NULL) { snd_mixer_selem_get_capture_switch (elem, SND_MIXER_SCHN_FRONT_LEFT, &mutesw); lamixer_switch_checkvalue(mixer_elem->capture->muteswitch, mutesw, mixer_elem->capture->hmutesignalid); } } } return 0; }
static void am_create_capture_mixer(GtkWidget *hbox, alsa_mixer_t *mixer) { GtkWidget *switch_btn = NULL, *vbox = NULL, *adv_btn = NULL, *img = NULL; GtkObject *adj = NULL; char *icon = NULL; gdouble dval = 0; long cmin, cmax, Rvol, Lvol; gboolean muted = TRUE, need_reset; char path[1024] = {0}; if(mixer->mic) muted = alsa_mixer_is_muted(mixer->mic, &need_reset); mixer->mic_muted = muted; g_snprintf(path, 1024, DVM_CONFIG_PATH"/%s", g_capture_iconset[muted ? 3: 0]); switch_btn = gtk_event_box_new(); img = gtk_image_new_from_file(path); gtk_container_add(GTK_CONTAINER(switch_btn), img); g_object_set_data(G_OBJECT(switch_btn), "iconset", g_capture_iconset); g_signal_connect(switch_btn, "enter-notify-event", G_CALLBACK(on_enter_switch_widget), mixer); g_signal_connect(switch_btn, "leave-notify-event", G_CALLBACK(on_leave_switch_widget), mixer); g_signal_connect(switch_btn, "button-press-event", G_CALLBACK(on_press_switch_widget), mixer); g_signal_connect(switch_btn, "button-release-event", G_CALLBACK(on_release_switch_widget), mixer); if(mixer->mic) { snd_mixer_selem_get_capture_volume_range(mixer->mic, &cmin, &cmax); snd_mixer_selem_get_capture_volume(mixer->mic, 0, &Rvol); snd_mixer_selem_get_capture_volume(mixer->mic, 1, &Lvol); dval = ((gdouble)(Rvol + Lvol)*50)/(cmax-cmin); adj = gtk_adjustment_new(dval, 0, 100, 1, 6, 0); snd_mixer_elem_set_callback_private(mixer->mic, adj); } else { adj = gtk_adjustment_new(0, 0, 100, 1, 6, 0); } g_object_set_data(G_OBJECT(adj), "image-obj", img); g_object_set_data(G_OBJECT(adj), "mixer-obj", mixer); DEBUG("capture set object data, img = %x, mixer = %x\n", img, mixer); //g_signal_connect(adj, "value-changed", G_CALLBACK(on_capture_mixer_changed), mixer); adv_btn = gtk_button_new_with_label("Advanced"); vbox = am_create_mixer_ui(switch_btn, "Microphone", GTK_ADJUSTMENT(adj), adv_btn); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); }
bool AlsaMixer::GetVolumePercent( const char* channel, int* value ) { LOG( Logger::LOG_DEBUG, "AlsaMixer::GetVolume( %s )", channel); bool success = false; snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_id_set_index( sid, 0); snd_mixer_selem_id_set_name( sid, channel); elem = snd_mixer_find_selem(_handle, sid); if (!elem) { LOG( Logger::LOG_ERROR, "Unable to find simple control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); goto end; } if( snd_mixer_selem_has_playback_volume(elem) ) { long min, max; if( snd_mixer_selem_get_playback_volume_range(elem, &min, &max) < 0 ) { LOG( Logger::LOG_ERROR, "Unable to get playback volume range for control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); goto end; } long volume; for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) { if (snd_mixer_selem_get_playback_volume(elem, (snd_mixer_selem_channel_id_t)chn, &volume ) >= 0) { *value = (volume - min) * 100 / ( max - min ); success = true; break; } } }else if( snd_mixer_selem_has_capture_volume(elem) ) { long min, max; if( snd_mixer_selem_get_capture_volume_range(elem, &min, &max) < 0 ) { LOG( Logger::LOG_ERROR, "Unable to get capture volume range for control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); goto end; } long volume; for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) { if (snd_mixer_selem_get_capture_volume(elem, (snd_mixer_selem_channel_id_t)chn, &volume ) >= 0) { *value = (volume - min) * 100 / ( max - min ); success = true; break; } } } if( !success ) { LOG( Logger::LOG_ERROR, "Error getting control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); } end: return success; }
void lamixer_volboxr_changed(GtkObject *adjustment, VolBox *volumebox) { long rangevalue_left,rangevalue_right,increment; rangevalue_right = gtk_range_get_value(GTK_RANGE(adjustment)); if (volumebox->type == 1) { snd_mixer_selem_set_playback_volume (volumebox->volelem, SND_MIXER_SCHN_FRONT_RIGHT, rangevalue_right); } else if (volumebox->type == 2) { snd_mixer_selem_set_capture_volume (volumebox->volelem, SND_MIXER_SCHN_FRONT_RIGHT, rangevalue_right); } if ((volumebox->lockswitch != NULL) && (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(volumebox->lockswitch)))) { if (volumebox->type == 1) { snd_mixer_selem_get_playback_volume (volumebox->volelem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); } else if (volumebox->type == 2) { snd_mixer_selem_get_capture_volume (volumebox->volelem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); } //TODO: Percent increment will be better? increment = rangevalue_right-volumebox->rcurval; if ( ((rangevalue_left<volumebox->maxrange) && (rangevalue_left>volumebox->minrange)) || \ ((rangevalue_left==volumebox->maxrange) && (increment<0)) || ((rangevalue_left==volumebox->minrange) && (increment>0)) ) { if (((rangevalue_left+increment)<=(long)volumebox->maxrange) && ((rangevalue_left+increment)>=(long)volumebox->minrange)) { rangevalue_left = rangevalue_left+increment; } else { if ((rangevalue_left+increment) < ((long)volumebox->minrange)) { rangevalue_left = volumebox->minrange; } else { rangevalue_left = volumebox->maxrange; } } g_signal_handler_block(G_OBJECT(volumebox->volbar), volumebox->hsignalid); gtk_range_set_value(GTK_RANGE(volumebox->volbar), rangevalue_left); if (volumebox->type == 1) { snd_mixer_selem_set_playback_volume (volumebox->volelem, SND_MIXER_SCHN_FRONT_LEFT, rangevalue_left); } else if (volumebox->type == 2) { snd_mixer_selem_set_capture_volume (volumebox->volelem, SND_MIXER_SCHN_FRONT_LEFT, rangevalue_left); } volumebox->curval = rangevalue_left; g_signal_handler_unblock(G_OBJECT(volumebox->volbar), volumebox->hsignalid); } } volumebox->rcurval = rangevalue_right; }
static gint gam_slider_pan_get_pan (GamSliderPan *gam_slider_pan) { glong left_chn, right_chn; if (!snd_mixer_selem_is_playback_mono (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) { if (snd_mixer_selem_has_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) snd_mixer_selem_get_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_LEFT, &left_chn); else snd_mixer_selem_get_capture_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_LEFT, &left_chn); if (snd_mixer_selem_has_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) snd_mixer_selem_get_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_RIGHT, &right_chn); else snd_mixer_selem_get_capture_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_RIGHT, &right_chn); if ((gam_slider_pan_get_volume (gam_slider_pan) != 0) && (left_chn != right_chn)) return rint (((gfloat)(right_chn - left_chn) / (gfloat)MAX(left_chn, right_chn)) * 100); } return 0; }
static enum MixerCode alsaMixerSelectCard(struct MixerSystem* system, int mixerId) { enum MixerCode code; snd_mixer_elem_t* mixerElem = NULL; AlsaMixerCard* card = (AlsaMixerCard*)system->active; if ( !card ) { if ( card == system->mixerCard->pElement[mixerId] ) { return MIXER_CODE_OK; } alsaMixerCardClose(system); } code = commonMixerSelectCard(system, mixerId); if ( code != MIXER_CODE_OK ) { GOC_DEBUG("Cannot select card by commonMixerSelectCard"); return code; } card = (AlsaMixerCard*)system->active; GOC_CHEOP_DEBUG(snd_mixer_open( &card->sndmixer, 0 ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD); GOC_CHEOP_DEBUG(snd_mixer_attach( card->sndmixer, card->physicalName ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD); GOC_CHEOP_DEBUG(snd_mixer_selem_register( card->sndmixer, NULL, NULL ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD); GOC_CHEOP_DEBUG(snd_mixer_load( card->sndmixer ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD); mixerElem = snd_mixer_first_elem( card->sndmixer ); while ( mixerElem ) { AlsaMixerElement* pMixerElement = alsaMixerElementAlloc(); for (int channel = 0; channel <= SND_MIXER_SCHN_LAST; channel++ ) { if ( snd_mixer_selem_has_playback_channel(mixerElem, channel) && snd_mixer_selem_get_playback_volume_range(mixerElem, &pMixerElement->rangemin, &pMixerElement->rangemax) == 0 && snd_mixer_selem_get_playback_volume(mixerElem, channel, &pMixerElement->volume) == 0 ) { pMixerElement->name = goc_stringCopy(NULL, snd_mixer_selem_get_name(mixerElem)); pMixerElement->type = MIXER_ELEMENT_PLAYBACK; pMixerElement->sndelement = mixerElem; card->mixerElement = goc_arrayAdd( card->mixerElement, pMixerElement ); break; } else if ( snd_mixer_selem_has_capture_channel(mixerElem, channel) && snd_mixer_selem_get_capture_volume_range(mixerElem, &pMixerElement->rangemin, &pMixerElement->rangemax) == 0 && snd_mixer_selem_get_capture_volume(mixerElem, channel, &pMixerElement->volume) == 0 ) { pMixerElement->name = goc_stringCopy(NULL, snd_mixer_selem_get_name(mixerElem)); pMixerElement->type = MIXER_ELEMENT_CAPTURE; pMixerElement->sndelement = mixerElem; card->mixerElement = goc_arrayAdd( card->mixerElement, pMixerElement ); break; } } mixerElem = snd_mixer_elem_next( mixerElem ); } return MIXER_CODE_OK; }
static int get_mixer_element(snd_mixer_t *mixer,const char *name, MixerAction action){ long value=0; const char *elemname; snd_mixer_elem_t *elem; int err; long sndMixerPMin=0; long sndMixerPMax=0; long newvol=0; elem=snd_mixer_first_elem(mixer); while (elem!=NULL){ elemname=snd_mixer_selem_get_name(elem); //ms_message("Found alsa mixer element %s.",elemname); if (strcmp(elemname,name)==0){ switch (action){ case CAPTURE: if (snd_mixer_selem_has_capture_volume(elem)){ snd_mixer_selem_get_capture_volume_range(elem, &sndMixerPMin, &sndMixerPMax); err=snd_mixer_selem_get_capture_volume(elem,SND_MIXER_SCHN_UNKNOWN,&newvol); newvol-=sndMixerPMin; value=(100*newvol)/(sndMixerPMax-sndMixerPMin); if (err<0) ms_warning("Could not get capture volume for %s:%s",name,snd_strerror(err)); //else ms_message("Successfully get capture level for %s.",elemname); break; } break; case PLAYBACK: if (snd_mixer_selem_has_playback_volume(elem)){ snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); err=snd_mixer_selem_get_playback_volume(elem,SND_MIXER_SCHN_FRONT_LEFT,&newvol); newvol-=sndMixerPMin; value=(100*newvol)/(sndMixerPMax-sndMixerPMin); if (err<0) ms_warning("Could not get playback volume for %s:%s",name,snd_strerror(err)); //else ms_message("Successfully get playback level for %s.",elemname); break; } break; case CAPTURE_SWITCH: break; case PLAYBACK_SWITCH: break; } } elem=snd_mixer_elem_next(elem); } return value; }
void gst_alsa_mixer_get_volume (GstAlsaMixer * mixer, GstMixerTrack * track, gint * volumes) { gint i; GstAlsaMixerTrack *alsa_track = GST_ALSA_MIXER_TRACK (track); g_return_if_fail (mixer->handle != NULL); g_static_rec_mutex_lock (mixer->rec_mutex); gst_alsa_mixer_track_update (alsa_track); if (track->flags & GST_MIXER_TRACK_OUTPUT) { /* return playback volume */ /* Is emulated mute flag activated? */ if (track->flags & GST_MIXER_TRACK_MUTE && !(alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_PSWITCH)) { for (i = 0; i < track->num_channels; i++) volumes[i] = alsa_track->volumes[i]; } else { for (i = 0; i < track->num_channels; i++) { long tmp = 0; snd_mixer_selem_get_playback_volume (alsa_track->element, i, &tmp); alsa_track->volumes[i] = volumes[i] = (gint) tmp; } } } else if (track->flags & GST_MIXER_TRACK_INPUT) { /* return capture volume */ /* Is emulated record flag activated? */ if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CSWITCH || track->flags & GST_MIXER_TRACK_RECORD) { for (i = 0; i < track->num_channels; i++) { long tmp = 0; snd_mixer_selem_get_capture_volume (alsa_track->element, i, &tmp); alsa_track->volumes[i] = volumes[i] = (gint) tmp; } } else { for (i = 0; i < track->num_channels; i++) volumes[i] = alsa_track->volumes[i]; } } g_static_rec_mutex_unlock (mixer->rec_mutex); }
float getRealVolume(PortControl* portControl, snd_mixer_selem_channel_id_t channel) { float fValue; long lValue = 0; long min = 0; long max = 0; if (isPlaybackFunction(portControl->portType)) { snd_mixer_selem_get_playback_volume_range(portControl->elem, &min, &max); snd_mixer_selem_get_playback_volume(portControl->elem, channel, &lValue); } else { snd_mixer_selem_get_capture_volume_range(portControl->elem, &min, &max); snd_mixer_selem_get_capture_volume(portControl->elem, channel, &lValue); } fValue = scaleVolumeValueToNormalized(lValue, min, max); return fValue; }
/* * Class: org_tritonus_lowlevel_alsa_AlsaMixerElement * Method: getCaptureVolume * Signature: (I)I */ JNIEXPORT jint JNICALL Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_getCaptureVolume (JNIEnv* env, jobject obj, jint nChannelType) { snd_mixer_elem_t* handle; int nReturn; long lValue; if (debug_flag) { (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_getCaptureVolume(): begin\n"); } handle = getHandle(env, obj); nReturn = snd_mixer_selem_get_capture_volume(handle, (snd_mixer_selem_channel_id_t) nChannelType, &lValue); if (nReturn < 0) { throwRuntimeException(env, snd_strerror(nReturn)); } if (debug_flag) { (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_getCaptureVolume(): end\n"); } return lValue; }
bool AlsaMixer::StepVolume( const char* channel, int step ) { LOG( Logger::LOG_DEBUG, "AlsaMixer::StepVolume( %s, %d )", channel, step); bool success = false; snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_id_set_index( sid, 0); snd_mixer_selem_id_set_name( sid, channel); elem = snd_mixer_find_selem(_handle, sid); if (!elem) { LOG( Logger::LOG_ERROR, "Unable to find simple control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); goto end; } if( snd_mixer_selem_has_playback_volume(elem) ) { long min, max; if( snd_mixer_selem_get_playback_volume_range(elem, &min, &max) < 0 ) { LOG( Logger::LOG_ERROR, "Unable to get playback volume range for control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); goto end; } for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) { long volume; if (snd_mixer_selem_get_playback_volume(elem, (snd_mixer_selem_channel_id_t)chn, &volume ) >= 0) { volume += step; if( volume > max )volume = max; if( volume < min )volume = min; if (snd_mixer_selem_set_playback_volume(elem, (snd_mixer_selem_channel_id_t)chn, volume ) >= 0) { success = true; } } } }else if( snd_mixer_selem_has_capture_volume(elem) ) { long min, max; if( snd_mixer_selem_get_capture_volume_range(elem, &min, &max) < 0 ) { LOG( Logger::LOG_ERROR, "Unable to get capture volume range for control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); goto end; } for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) { long volume; if (snd_mixer_selem_get_capture_volume(elem, (snd_mixer_selem_channel_id_t)chn, &volume ) >= 0) { volume += step; if( volume > max )volume = max; if( volume < min )volume = min; if (snd_mixer_selem_set_capture_volume(elem, (snd_mixer_selem_channel_id_t)chn, volume ) >= 0) { success = true; } } } } if( !success ) { LOG( Logger::LOG_ERROR, "Error setting control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); } end: return success; }
GstMixerTrack * gst_alsa_mixer_track_new (snd_mixer_elem_t * element, gint num, gint track_num, gint flags, gboolean sw, GstAlsaMixerTrack * shared_mute_track, gboolean append_capture) { GstAlsaMixerTrack *alsa_track; GstMixerTrack *track; const gchar *name; const gchar *label; gint i; long min = 0, max = 0; const struct { const gchar orig[12]; const gchar trans[12]; } alsa_track_labels[] = { { "Master", N_("Master")}, { "Bass", N_("Bass")}, { "Treble", N_("Treble")}, { "PCM", N_("PCM")}, { "Synth", N_("Synth")}, { "Line", N_("Line-in")}, { "CD", N_("CD")}, { "Mic", N_("Microphone")}, { "PC Speaker", N_("PC Speaker")}, { "Playback", N_("Playback")}, { "Capture", N_("Capture")} }; name = snd_mixer_selem_get_name (element); GST_LOG ("[%s] num=%d,track_num=%d,flags=0x%08x,sw=%s,shared_mute_track=%p", name, num, track_num, flags, (sw) ? "true" : "false", shared_mute_track); track = (GstMixerTrack *) g_object_new (GST_ALSA_MIXER_TRACK_TYPE, "untranslated-label", name, NULL); alsa_track = (GstAlsaMixerTrack *) track; GST_LOG ("[%s] created new mixer track %p", name, track); /* This reflects the assumptions used for GstAlsaMixerTrack */ if (!(!!(flags & GST_MIXER_TRACK_OUTPUT) ^ !!(flags & GST_MIXER_TRACK_INPUT))) { GST_ERROR ("Mixer track must be either output or input!"); g_return_val_if_reached (NULL); } track->flags = flags; alsa_track->element = element; alsa_track->shared_mute = shared_mute_track; alsa_track->track_num = track_num; alsa_track->alsa_channels = 0; gst_alsa_mixer_track_update_alsa_capabilities (alsa_track); if (flags & GST_MIXER_TRACK_OUTPUT) { while (alsa_track->alsa_channels < GST_ALSA_MAX_CHANNELS && snd_mixer_selem_has_playback_channel (element, alsa_track->alsa_channels)) { alsa_track->alsa_channels++; } GST_LOG ("[%s] %d output channels", name, alsa_track->alsa_channels); } else if (flags & GST_MIXER_TRACK_INPUT) { while (alsa_track->alsa_channels < GST_ALSA_MAX_CHANNELS && snd_mixer_selem_has_capture_channel (element, alsa_track->alsa_channels)) { alsa_track->alsa_channels++; } GST_LOG ("[%s] %d input channels", name, alsa_track->alsa_channels); } else { g_assert_not_reached (); } if (sw) track->num_channels = 0; else track->num_channels = alsa_track->alsa_channels; /* translate the name if we can */ label = name; for (i = 0; i < G_N_ELEMENTS (alsa_track_labels); ++i) { if (g_utf8_collate (label, alsa_track_labels[i].orig) == 0) { label = _(alsa_track_labels[i].trans); break; } } if (num == 0) { track->label = g_strdup_printf ("%s%s%s", label, append_capture ? " " : "", append_capture ? _("Capture") : ""); } else { track->label = g_strdup_printf ("%s%s%s %d", label, append_capture ? " " : "", append_capture ? _("Capture") : "", num); } /* set volume information */ if (track->num_channels > 0) { if ((flags & GST_MIXER_TRACK_OUTPUT)) snd_mixer_selem_get_playback_volume_range (element, &min, &max); else snd_mixer_selem_get_capture_volume_range (element, &min, &max); } track->min_volume = (gint) min; track->max_volume = (gint) max; for (i = 0; i < track->num_channels; i++) { long tmp = 0; if (flags & GST_MIXER_TRACK_OUTPUT) snd_mixer_selem_get_playback_volume (element, i, &tmp); else snd_mixer_selem_get_capture_volume (element, i, &tmp); alsa_track->volumes[i] = (gint) tmp; } gst_alsa_mixer_track_update (alsa_track); return track; }
void gst_alsa_mixer_track_update (GstAlsaMixerTrack * alsa_track) { GstMixerTrack *track = (GstMixerTrack *) alsa_track; gint i; gint audible = !(track->flags & GST_MIXER_TRACK_MUTE); if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_PVOLUME)) { /* update playback volume */ for (i = 0; i < track->num_channels; i++) { long vol = 0; snd_mixer_selem_get_playback_volume (alsa_track->element, i, &vol); alsa_track->volumes[i] = (gint) vol; } } if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_CVOLUME)) { /* update capture volume */ for (i = 0; i < track->num_channels; i++) { long vol = 0; snd_mixer_selem_get_capture_volume (alsa_track->element, i, &vol); alsa_track->volumes[i] = (gint) vol; } } /* Any updates in flags? */ if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_PSWITCH)) { int v = 0; audible = 0; for (i = 0; i < alsa_track->alsa_channels; ++i) { snd_mixer_selem_get_playback_switch (alsa_track->element, i, &v); audible += v; } } else if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_PVOLUME) && track->flags & GST_MIXER_TRACK_MUTE) { /* check if user has raised volume with a parallel running application */ for (i = 0; i < track->num_channels; i++) { long vol = 0; snd_mixer_selem_get_playback_volume (alsa_track->element, i, &vol); if (vol > track->min_volume) { audible = 1; break; } } } if (!!(audible) != !(track->flags & GST_MIXER_TRACK_MUTE)) { if (audible) { track->flags &= ~GST_MIXER_TRACK_MUTE; if (alsa_track->shared_mute) ((GstMixerTrack *) (alsa_track->shared_mute))->flags &= ~GST_MIXER_TRACK_MUTE; } else { track->flags |= GST_MIXER_TRACK_MUTE; if (alsa_track->shared_mute) ((GstMixerTrack *) (alsa_track->shared_mute))->flags |= GST_MIXER_TRACK_MUTE; } } if (track->flags & GST_MIXER_TRACK_INPUT) { gint recording = track->flags & GST_MIXER_TRACK_RECORD; if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_CSWITCH)) { int v = 0; recording = 0; for (i = 0; i < alsa_track->alsa_channels; ++i) { snd_mixer_selem_get_capture_switch (alsa_track->element, i, &v); recording += v; } } else if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_CVOLUME) && !(track->flags & GST_MIXER_TRACK_RECORD)) { /* check if user has raised volume with a parallel running application */ for (i = 0; i < track->num_channels; i++) { long vol = 0; snd_mixer_selem_get_capture_volume (alsa_track->element, i, &vol); if (vol > track->min_volume) { recording = 1; break; } } } if (recording) track->flags |= GST_MIXER_TRACK_RECORD; else track->flags &= ~GST_MIXER_TRACK_RECORD; } }
MixerElem *lamixer_volelem_new(snd_mixer_elem_t *elem) { MixerElem *mixer_elem; guint voltype=0, elemidx=0, mono; long minrange=0,maxrange=0,rangevalue_left=0,rangevalue_right=0; const char* selem_name = NULL; char elem_name[64]; mixer_elem = g_malloc(sizeof(MixerElem)); mixer_elem->elem = elem; mixer_elem->playback = NULL; mixer_elem->capture = NULL; mixer_elem->pswitch = NULL; mixer_elem->cswitch = NULL; mixer_elem->penum = NULL; mixer_elem->cenum = NULL; elemidx = snd_mixer_selem_get_index(elem); selem_name = snd_mixer_selem_id_get_name(sid); strcpy(elem_name, selem_name); if(elemidx > 0) { sprintf(elem_name,"%s %i",elem_name, elemidx); } if (!snd_mixer_selem_is_enumerated(elem)) { if (snd_mixer_selem_has_playback_volume(elem)) { voltype = 1; snd_mixer_selem_get_playback_volume_range (elem, &minrange, &maxrange); mono = snd_mixer_selem_is_playback_mono(elem); snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); if(!mono) snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue_right); mixer_elem->playback = lamixer_volbox_new(elem_name,mono, \ (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_playback_switch_joined(elem)), minrange, maxrange, elem, voltype); } else if (snd_mixer_selem_has_playback_switch(elem)) { voltype = 1; mixer_elem->pswitch = lamixer_switchbox_add(elem_name, elem, voltype); } if (snd_mixer_selem_has_capture_volume(elem)) { voltype = 2; snd_mixer_selem_get_capture_volume_range (elem, &minrange, &maxrange); mono = snd_mixer_selem_is_capture_mono(elem); snd_mixer_selem_get_capture_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); if(!mono) snd_mixer_selem_get_capture_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue_right); mixer_elem->capture = lamixer_volbox_new(elem_name,mono, \ (snd_mixer_selem_has_capture_switch(elem) || snd_mixer_selem_has_capture_switch_joined(elem)), minrange, maxrange, elem, voltype); } else if (snd_mixer_selem_has_capture_switch(elem)) { voltype = 2; mixer_elem->cswitch = lamixer_switchbox_add(elem_name, elem, voltype); } } else { if (snd_mixer_selem_is_enum_playback(elem)) { voltype = 1; mixer_elem->penum = lamixer_enumbox_add(elem_name, elem, voltype); } else if (snd_mixer_selem_is_enum_capture(elem)) { voltype = 2; mixer_elem->cenum = lamixer_enumbox_add(elem_name, elem, voltype); } } return mixer_elem; }