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 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 snd_mixer_elem_t * gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle) { snd_mixer_elem_t *element; gint i, count; count = snd_mixer_get_count (handle); /* Check if we have a playback mixer labelled as 'Master' */ element = snd_mixer_first_elem (handle); for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && strcmp (snd_mixer_selem_get_name (element), "Master") == 0) { return element; } element = snd_mixer_elem_next (element); } /* If not, check if we have a playback mixer labelled as 'Front' */ element = snd_mixer_first_elem (handle); for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && strcmp (snd_mixer_selem_get_name (element), "Front") == 0) { return element; } element = snd_mixer_elem_next (element); } /* If not, check if we have a playback mixer labelled as 'PCM' */ element = snd_mixer_first_elem (handle); for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && strcmp (snd_mixer_selem_get_name (element), "PCM") == 0) { return element; } element = snd_mixer_elem_next (element); } /* If not, check if we have a playback mixer with both volume and switch */ element = snd_mixer_first_elem (handle); for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element) && snd_mixer_selem_has_playback_switch (element)) { return element; } element = snd_mixer_elem_next (element); } /* If not, take any playback mixer with a volume control */ element = snd_mixer_first_elem (handle); for (i = 0; i < count; i++) { if (snd_mixer_selem_has_playback_volume (element)) { return element; } element = snd_mixer_elem_next (element); } /* Looks like we're out of luck ... */ return NULL; }
static void gam_slider_pan_update_volume (GamSliderPan *gam_slider_pan) { GamSliderPanPrivate *priv; gint left_chn = 0, right_chn = 0; glong pmin, pmax; priv = GAM_SLIDER_PAN_GET_PRIVATE (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_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); left_chn = right_chn = rint ((100 - GTK_ADJUSTMENT (priv->vol_adjustment)->value) / (100 / (gfloat)pmax)); if (!snd_mixer_selem_is_playback_mono (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) { if (GTK_ADJUSTMENT (priv->pan_adjustment)->value < 0) { right_chn = rint (left_chn - ((gfloat)ABS(GTK_ADJUSTMENT (priv->pan_adjustment)->value) / 100) * left_chn); } else if (GTK_ADJUSTMENT (priv->pan_adjustment)->value > 0) { left_chn = rint (right_chn - ((gfloat)GTK_ADJUSTMENT (priv->pan_adjustment)->value / 100) * right_chn); } } if (snd_mixer_selem_has_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)))) { snd_mixer_selem_set_playback_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)))) snd_mixer_selem_set_playback_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_RIGHT, right_chn); } else { snd_mixer_selem_set_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)))) snd_mixer_selem_set_capture_volume (gam_slider_get_elem (GAM_SLIDER (gam_slider_pan)), SND_MIXER_SCHN_FRONT_RIGHT, right_chn); } }
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; }
int sa_stream_set_volume_abs(sa_stream_t *s, float vol) { snd_mixer_t* mixer = 0; snd_mixer_elem_t* elem = 0; if (s == NULL || s->output_unit == NULL) { return SA_ERROR_NO_INIT; } if (snd_mixer_open(&mixer, 0) < 0) { return SA_ERROR_SYSTEM; } if (snd_mixer_attach(mixer, "default") < 0) { snd_mixer_close(mixer); return SA_ERROR_SYSTEM; } if (snd_mixer_selem_register(mixer, NULL, NULL) < 0) { snd_mixer_close(mixer); return SA_ERROR_SYSTEM; } if (snd_mixer_load(mixer) < 0) { snd_mixer_close(mixer); return SA_ERROR_SYSTEM; } #if 0 snd_mixer_elem_t* elem = 0; for (elem = snd_mixer_first_elem(mixer); elem != NULL; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_selem_has_playback_volume(elem)) { printf("Playback %s\n", snd_mixer_selem_get_name(elem)); } else { printf("No Playback: %s\n", snd_mixer_selem_get_name(elem)); } } #endif elem = snd_mixer_first_elem(mixer); if (elem && snd_mixer_selem_has_playback_volume(elem)) { long min = 0; long max = 0; if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) >= 0) { snd_mixer_selem_set_playback_volume_all(elem, (max-min)*vol + min); } } snd_mixer_close(mixer); return SA_SUCCESS; }
static int alsa_mixer_set_muted(snd_mixer_elem_t *elem, gboolean muted) { long val, min, max; /**if switch is available, get switch status directly*/ if(snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_set_playback_switch(elem, 0, !muted); snd_mixer_selem_set_playback_switch(elem, 1, !muted); return 0; } else if(snd_mixer_selem_has_capture_switch(elem)) { snd_mixer_selem_set_capture_switch(elem, 0, !muted); snd_mixer_selem_set_capture_switch(elem, 1, !muted); return 0; } if(snd_mixer_selem_has_playback_volume(elem)) { snd_mixer_selem_get_playback_volume_range(elem, &min, &max); val = muted ? min : max; snd_mixer_selem_set_playback_volume(elem, 0, val); snd_mixer_selem_set_playback_volume(elem, 1, val); return 0; } else if(snd_mixer_selem_has_capture_volume(elem)) { snd_mixer_selem_get_capture_volume_range(elem, &min, &max); val = muted ? min : max; snd_mixer_selem_set_capture_volume(elem, 0, val); snd_mixer_selem_set_capture_volume(elem, 1, val); return 0; } return -1; }
static void elem_set_vol_percent(snd_mixer_elem_t *elem, int vol_percent) { int i; long pmin, pmax, value; //sdbg("%s: set mixer element volume\n", __func__); for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { 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); /* playback volume */ if (snd_mixer_selem_has_playback_volume(elem)) { value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin)); snd_mixer_selem_set_playback_volume(elem, i, value); } } else if (snd_mixer_selem_has_capture_channel(elem, i) && !snd_mixer_selem_has_common_volume(elem)) { /* capture volume */ snd_mixer_selem_get_capture_volume_range(elem, &pmin, &pmax); if (snd_mixer_selem_has_capture_volume(elem)) { value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin)); snd_mixer_selem_set_capture_volume(elem, i, value); } } else { /* Misc. ex: Boost */ snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax); value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin)); snd_mixer_selem_set_playback_volume(elem, i, value); snd_mixer_selem_get_capture_volume_range(elem, &pmin, &pmax); value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin)); snd_mixer_selem_set_capture_volume(elem, i, value); } } }
static void gst_alsa_mixer_track_update_alsa_capabilities (GstAlsaMixerTrack * alsa_track) { alsa_track->alsa_flags = 0; alsa_track->capture_group = -1; if (snd_mixer_selem_has_common_volume (alsa_track->element)) alsa_track->alsa_flags |= GST_ALSA_MIXER_TRACK_VOLUME; if (snd_mixer_selem_has_playback_volume (alsa_track->element)) alsa_track->alsa_flags |= GST_ALSA_MIXER_TRACK_PVOLUME; if (snd_mixer_selem_has_capture_volume (alsa_track->element)) alsa_track->alsa_flags |= GST_ALSA_MIXER_TRACK_CVOLUME; if (snd_mixer_selem_has_common_switch (alsa_track->element)) alsa_track->alsa_flags |= GST_ALSA_MIXER_TRACK_SWITCH; if (snd_mixer_selem_has_playback_switch (alsa_track->element)) alsa_track->alsa_flags |= GST_ALSA_MIXER_TRACK_PSWITCH; if (snd_mixer_selem_has_capture_switch (alsa_track->element)) { alsa_track->alsa_flags |= GST_ALSA_MIXER_TRACK_CSWITCH; if (snd_mixer_selem_has_capture_switch_exclusive (alsa_track->element)) { alsa_track->alsa_flags |= GST_ALSA_MIXER_TRACK_CSWITCH_EXCL; alsa_track->capture_group = snd_mixer_selem_get_capture_group (alsa_track->element); } } GST_LOG ("[%s] alsa_flags=0x%08x, capture_group=%d", snd_mixer_selem_get_name (alsa_track->element), alsa_track->alsa_flags, alsa_track->capture_group); }
SIDInfo::SIDInfo(snd_mixer_t* handle, snd_mixer_selem_id_t* sid) : min(0), max(0), globalMax(0), hasMute(false), hasVolume(false), _isEmulMuted(false), _lastVol(0), _handle(handle), _sid(sid) { if (!_sid) return; snd_mixer_elem_t *elem; elem = snd_mixer_find_selem(_handle, _sid); if (!elem) return; if (snd_mixer_selem_has_playback_volume(elem)) { snd_mixer_selem_get_playback_volume_range(elem, &min, &max); if (max > min) hasVolume = true; else min = max = 0; } _lastVol = min; if (snd_mixer_selem_has_playback_switch(elem)) { hasMute = true; } }
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; }
void gam_app_update_visibility (GamApp *gam_app, GtkWidget *widget, snd_mixer_elem_t *elem, gboolean saved_state){ g_return_if_fail (GAM_IS_APP (gam_app)); GamMixer *gam_mixer=gam_app_get_current_mixer(gam_app); int is_playback= snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_playback_switch(elem) || (snd_mixer_selem_is_enumerated(elem) && snd_mixer_selem_is_enum_playback(elem)); int is_capture = snd_mixer_selem_has_capture_volume(elem) || snd_mixer_selem_has_capture_switch(elem) || (snd_mixer_selem_is_enumerated(elem) && snd_mixer_selem_is_enum_capture(elem)); //If nothing showed set show all if(!(gam_mixer_get_show_playback_elements(gam_mixer)||gam_mixer_get_show_capture_elements(gam_mixer))) gam_mixer_set_capture_playback(gam_app_get_current_mixer(gam_app), TRUE, TRUE); if(saved_state && ((is_playback && gam_mixer_get_show_playback_elements(gam_mixer)) || (is_capture && gam_mixer_get_show_capture_elements(gam_mixer)))) gtk_widget_show(widget); else gtk_widget_hide(widget); }
void mixerGuiAlsaMix::cardChanged( int card ) { #ifdef HAVE_ALSA channelSelect->clear(); // get the cards channels snd_mixer_t* alsaDev; snd_mixer_open( &alsaDev, 0); char device[16]; sprintf(device, "hw:%i", card); snd_mixer_attach(alsaDev, device ); snd_mixer_selem_register(alsaDev, NULL, NULL); snd_mixer_load(alsaDev); //load up the mixer snd_mixer_elem_t* mixerElem = snd_mixer_first_elem(alsaDev); while( mixerElem != snd_mixer_last_elem(alsaDev) ) { if(snd_mixer_selem_has_playback_volume(mixerElem) || snd_mixer_selem_has_capture_volume(mixerElem)) channelSelect->addItem( QString( snd_mixer_selem_get_name(mixerElem)), QVariant( snd_mixer_selem_get_name(mixerElem)) ); mixerElem=snd_mixer_elem_next( mixerElem ); } for(int i=0; i<= channelSelect->count(); i++ ) if( channelSelect->itemData(i) == settings["alsa_channel"].toString() ) channelSelect->setCurrentIndex( i ); #endif }
static snd_mixer_elem_t *alsa_init_mixer_channel (const char *name, long *vol_min, long *vol_max) { snd_mixer_selem_id_t *sid; snd_mixer_elem_t *elem = NULL; snd_mixer_selem_id_malloc (&sid); snd_mixer_selem_id_set_index (sid, 0); snd_mixer_selem_id_set_name (sid, name); if (!(elem = snd_mixer_find_selem(mixer_handle, sid))) error ("Can't find mixer %s", name); else if (!snd_mixer_selem_has_playback_volume(elem)) { error ("Mixer device has no playback volume (%s).", name); elem = NULL; } else { snd_mixer_selem_get_playback_volume_range (elem, vol_min, vol_max); logit ("Opened mixer (%s), volume range: %ld-%ld", name, *vol_min, *vol_max); } snd_mixer_selem_id_free (sid); return elem; }
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; } }
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 asound_setup(const gchar * card, const gchar * channel, void (*volume_changed)(int,gboolean)) { // Make sure (for now) that the setup function only gets called once static int asound_setup_called = 0; assert(asound_setup_called == 0); asound_setup_called++; // Save card, volume_changed strcpy(m_card, card); m_volume_changed = volume_changed; // Load the mixer for the provided cardname snd_mixer_open(&m_mixer, 0); snd_mixer_attach(m_mixer, m_card); snd_mixer_selem_register(m_mixer, NULL, NULL); snd_mixer_load(m_mixer); // Setup g_io_watch for the mixer int count = snd_mixer_poll_descriptors_count(m_mixer); if(count >= 1) { struct pollfd pfd; count = snd_mixer_poll_descriptors(m_mixer, &pfd, 1); if(count == 1) { GIOChannel * giochannel = g_io_channel_unix_new(pfd.fd); g_io_add_watch_full(giochannel, G_PRIORITY_DEFAULT, G_IO_IN, asound_poll_cb, NULL, NULL); } } // Iterate over the elements in the mixer and store them in m_channel_names int elemcount = snd_mixer_get_count(m_mixer); snd_mixer_elem_t * elem = snd_mixer_first_elem(m_mixer); int loop; for(loop = 0; loop < elemcount; loop++) { const char * elemname = snd_mixer_selem_get_name(elem); if(snd_mixer_selem_has_playback_volume(elem)) { m_channel_names = g_list_append(m_channel_names, (gpointer)g_strdup(elemname)); } elem = snd_mixer_elem_next(elem); } // Setup m_elem using the provided channelname if(channel != NULL && asound_channel_exists(channel)) asound_set_channel(channel); else if(m_channel_names != NULL) asound_set_channel((const gchar*)m_channel_names->data); }
snd_mixer_elem_t* AlsaMixer::get_first_playback_elem() { snd_mixer_elem_t* elem; for (elem = snd_mixer_first_elem(this->handle); elem; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_selem_is_active(elem) && snd_mixer_selem_has_playback_volume(elem)) return elem; } }
static void set_mixer_element(snd_mixer_t *mixer,const char *name, int level,MixerAction action){ const char *elemname; snd_mixer_elem_t *elem; 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); newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin; snd_mixer_selem_set_capture_volume_all(elem,newvol); //ms_message("Successfully set capture level for %s.",elemname); return; } break; case PLAYBACK: if (snd_mixer_selem_has_playback_volume(elem)){ snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin; snd_mixer_selem_set_playback_volume_all(elem,newvol); //ms_message("Successfully set playback level for %s.",elemname); return; } break; case CAPTURE_SWITCH: if (snd_mixer_selem_has_capture_switch(elem)){ snd_mixer_selem_set_capture_switch_all(elem,level); //ms_message("Successfully set capture switch for %s.",elemname); } break; case PLAYBACK_SWITCH: if (snd_mixer_selem_has_playback_switch(elem)){ snd_mixer_selem_set_playback_switch_all(elem,level); //ms_message("Successfully set capture switch for %s.",elemname); } break; } } elem=snd_mixer_elem_next(elem); } return ; }
snd_mixer_elem_t* AlsaMixer::get_playback_elem(const std::string name) { snd_mixer_elem_t* elem; for (elem = snd_mixer_first_elem(this->handle); elem; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_selem_is_active(elem) && snd_mixer_selem_has_playback_volume(elem) && (name == snd_mixer_selem_get_name(elem))) return elem; } }
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 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 void attach_mixer (MokoAlsaVolumeControl *self) { MokoAlsaVolumeControlPrivate *priv = ALSA_VOLUME_CONTROL_PRIVATE (self); g_debug ("Trying to attach... %p, %s, %p", priv->mixer_handle, priv->device, priv->element); open_mixer (self); if (priv->mixer_handle && priv->device && priv->element && (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)) { priv->mixer_elem = snd_mixer_find_selem ( priv->mixer_handle, priv->element); if (!priv->mixer_elem) { g_warning ("Unable to find mixer element"); snd_mixer_detach (priv->mixer_handle, priv->device); close_mixer (self); } else { g_debug ("Attached to mixer"); if (snd_mixer_selem_has_playback_volume ( priv->mixer_elem)) { priv->control_type = PLAYBACK; snd_mixer_selem_get_playback_volume_range ( priv->mixer_elem, &priv->min, &priv->max); } else if (snd_mixer_selem_has_capture_volume ( priv->mixer_elem)) { priv->control_type = CAPTURE; snd_mixer_selem_get_capture_volume_range ( priv->mixer_elem, &priv->min, &priv->max); } else priv->control_type = CONTROL; snd_mixer_elem_set_callback ( priv->mixer_elem, mixer_elem_event_cb); snd_mixer_elem_set_callback_private ( priv->mixer_elem, self); start_polling (self); update_volume (self); } } else { close_mixer (self); } }
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; }
/* openmoko_mixer_open */ static int _openmoko_mixer_open(Openmoko * openmoko) { #ifdef __linux__ PhonePluginHelper * helper = openmoko->helper; char const * audio_device; snd_mixer_elem_t * elem; openmoko->mixer_elem = NULL; openmoko->mixer_elem_headphone = NULL; openmoko->mixer_elem_speaker = NULL; if((audio_device = helper->config_get(helper->phone, "openmoko", "audio_device")) == NULL) audio_device = "hw:0"; if(snd_mixer_open(&openmoko->mixer, 0) != 0) { openmoko->mixer = NULL; return -1; } if(snd_mixer_attach(openmoko->mixer, audio_device) != 0 || snd_mixer_selem_register(openmoko->mixer, NULL, NULL) || snd_mixer_load(openmoko->mixer) != 0) { _openmoko_mixer_close(openmoko); return -1; } for(elem = snd_mixer_first_elem(openmoko->mixer); elem != NULL; elem = snd_mixer_elem_next(elem)) if(strcmp(snd_mixer_selem_get_name(elem), "Headphone") == 0 && snd_mixer_selem_has_playback_volume(elem)) openmoko->mixer_elem_headphone = elem; else if(strcmp(snd_mixer_selem_get_name(elem), "Speaker") == 0 && snd_mixer_selem_has_playback_volume(elem)) openmoko->mixer_elem_speaker = elem; #endif /* __linux__ */ return 0; }
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); }
/* * Class: org_tritonus_lowlevel_alsa_AlsaMixerElement * Method: hasPlaybackVolume * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackVolume (JNIEnv* env, jobject obj) { snd_mixer_elem_t* handle; int nReturn; if (debug_flag) { (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackVolume(): begin\n"); } handle = getHandle(env, obj); nReturn = snd_mixer_selem_has_playback_volume(handle); if (debug_flag) { (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackVolume(): end\n"); } return (jboolean) nReturn; }
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); }
static snd_mixer_elem_t* find_playback_mixer_element(snd_mixer_t *mixer, const char *name) { snd_mixer_elem_t *mixer_elem; for (mixer_elem = snd_mixer_first_elem(mixer); mixer_elem != NULL; mixer_elem = snd_mixer_elem_next(mixer_elem)) { const char *elem_name = snd_mixer_selem_get_name(mixer_elem); if ((elem_name != NULL) && snd_mixer_selem_has_playback_volume(mixer_elem) && (!strcmp(name, elem_name))) { return mixer_elem; } } return NULL; }
INT32 PORT_GetPortCount(void* id) { PortMixer* portMixer; snd_mixer_elem_t *elem; TRACE0("> PORT_GetPortCount\n"); if (id == NULL) { // $$mp: Should become a descriptive error code (invalid handle). return -1; } portMixer = (PortMixer*) id; if (portMixer->numElems == 0) { for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) { if (!snd_mixer_selem_is_active(elem)) continue; TRACE2("Simple mixer control '%s',%i\n", snd_mixer_selem_get_name(elem), snd_mixer_selem_get_index(elem)); if (snd_mixer_selem_has_playback_volume(elem)) { portMixer->elems[portMixer->numElems] = elem; portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN; portMixer->numElems++; } // to prevent buffer overflow if (portMixer->numElems >= MAX_ELEMS) { break; } /* If an element has both playback an capture volume, it is put into the arrays twice. */ if (snd_mixer_selem_has_capture_volume(elem)) { portMixer->elems[portMixer->numElems] = elem; portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN; portMixer->numElems++; } // to prevent buffer overflow if (portMixer->numElems >= MAX_ELEMS) { break; } } } TRACE0("< PORT_GetPortCount\n"); return portMixer->numElems; }