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; }
bool AmeSystemSound::mixerHasSwitch() { if (snd_mixer_selem_has_playback_switch(mixer_element)) return true; else return false; }
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); }
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_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 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 SetAlsaSwitchMute(const char* card, const char* selem_name) { // long min, max; snd_mixer_t *handle; snd_mixer_selem_id_t *sid; snd_mixer_open(&handle, 0); snd_mixer_attach(handle, card); snd_mixer_selem_register(handle, NULL, NULL); snd_mixer_load(handle); snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_id_set_index(sid, 0); snd_mixer_selem_id_set_name(sid, selem_name); snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid); int* muted; snd_mixer_selem_channel_id_t channel; snd_mixer_selem_get_playback_switch(elem,channel,muted); printf("Muted: %d\n",*muted); if (snd_mixer_selem_has_playback_switch(elem)) { snd_mixer_selem_set_playback_switch_all(elem, !*muted); } snd_mixer_close(handle); }
void gam_toggle_set_state (GamToggle *gam_toggle, gboolean state) { GamTogglePrivate *priv; const gboolean internal_state = gam_toggle_get_state (gam_toggle); int err; priv = GAM_TOGGLE_GET_PRIVATE (gam_toggle); if (state == internal_state) return; if (snd_mixer_selem_has_playback_switch (priv->elem)) { err = snd_mixer_selem_set_playback_switch_all (priv->elem, state); } else if (snd_mixer_selem_has_capture_switch (priv->elem)) { err = snd_mixer_selem_set_capture_switch_all (priv->elem, state); } else { g_warning ("%s (). No idea what to do for mixer element \"%s\"!", __FUNCTION__, snd_mixer_selem_get_name (priv->elem)); err = 0; } if (err) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gam_toggle), internal_state); }
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; }
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); }
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; } }
void AmeSystemSound::mute() { int sw; if (snd_mixer_selem_has_playback_switch(mixer_element)) { snd_mixer_selem_get_playback_switch(mixer_element, SND_MIXER_SCHN_FRONT_LEFT, &sw); snd_mixer_selem_set_playback_switch_all(mixer_element, !sw); } }
/** * Check whether sound is currently muted. * * @return 0 if mixer is muted, 1 otherwise */ int ismuted(void) { int muted = 1; if (snd_mixer_selem_has_playback_switch(elem)) snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, &muted); return muted; }
bool AmeSystemSound::isMuted() { int sw; if (snd_mixer_selem_has_playback_switch(mixer_element)) { snd_mixer_selem_get_playback_switch(mixer_element, SND_MIXER_SCHN_FRONT_LEFT, &sw); return !sw; } else return false; }
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 ; }
gboolean asound_get_mute() { assert(m_elem != NULL); gboolean mute = FALSE; if(snd_mixer_selem_has_playback_switch(m_elem)) { int pswitch; snd_mixer_selem_get_playback_switch(m_elem, 0, &pswitch); mute = pswitch ? FALSE : TRUE; } return mute; }
void asound_set_mute(gboolean mute) { assert(m_elem != NULL); if(snd_mixer_selem_has_playback_switch(m_elem)) { snd_mixer_selem_set_playback_switch_all(m_elem, !mute); } else if(mute) { asound_set_volume(0); } }
void AlsaMixer::unmute_volume() { if (!snd_mixer_selem_has_playback_switch(this->active_elem)) { this->set_volume(this->muted_volume); } else { snd_mixer_handle_events(this->handle); // TODO: write actual playback switch logic snd_mixer_selem_set_playback_switch(this->active_elem, LEFT, 1); snd_mixer_selem_set_playback_switch(this->active_elem, RIGHT, 1); } }
/** * Mutes or unmutes playback and sends a notification (if enabled). * * @param notify whether to send notification */ void setmute(gboolean notify) { if (!snd_mixer_selem_has_playback_switch(elem)) return; if (ismuted()) { snd_mixer_selem_set_playback_switch_all(elem, 0); if (enable_noti && notify) do_notify_volume(getvol(), TRUE); } else { snd_mixer_selem_set_playback_switch_all(elem, 1); if (enable_noti && notify) do_notify_volume(getvol(), FALSE); } }
static int elem_get_status(snd_mixer_elem_t *elem) { int i, psw = -1; for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { if (snd_mixer_selem_has_playback_channel(elem, i) && snd_mixer_selem_has_playback_switch(elem)) snd_mixer_selem_get_playback_switch(elem, i, &psw); else if (snd_mixer_selem_has_capture_channel(elem, i) && snd_mixer_selem_has_capture_switch(elem)) snd_mixer_selem_get_capture_switch(elem, i, &psw); } return psw; }
/* * Class: org_tritonus_lowlevel_alsa_AlsaMixerElement * Method: hasPlaybackSwitch * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackSwitch (JNIEnv* env, jobject obj) { snd_mixer_elem_t* handle; int nReturn; if (debug_flag) { (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackSwitch(): begin\n"); } handle = getHandle(env, obj); nReturn = snd_mixer_selem_has_playback_switch(handle); if (debug_flag) { (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackSwitch(): end\n"); } return (jboolean) nReturn; }
bool AlsaMixer::GetChannelSwitch( const char* channel, bool* on ) { 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_switch(elem) ) { for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) { int value; if (snd_mixer_selem_get_playback_switch(elem, (snd_mixer_selem_channel_id_t)chn, &value) >= 0) { *on = value != 0; success = true; break; } } }else if( snd_mixer_selem_has_capture_switch(elem) ) { for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) { int value; if (snd_mixer_selem_get_capture_switch(elem, (snd_mixer_selem_channel_id_t)chn, &value ) >= 0) { *on = value != 0; 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; }
bool AlsaMixer::get_mute() { if (snd_mixer_selem_has_playback_switch(this->active_elem)) { int muted; snd_mixer_handle_events(this->handle); // TODO: write actual playback switch logic if (snd_mixer_selem_get_playback_switch(this->active_elem, UNKN, &muted) < 0) snd_mixer_selem_get_playback_switch(this->active_elem, LEFT, &muted); return !(bool)muted; } else { return (this->get_volume() == 0 ? true : false); } }
gboolean gam_toggle_get_state (GamToggle *gam_toggle) { GamTogglePrivate *priv; gint value = 0; priv = GAM_TOGGLE_GET_PRIVATE (gam_toggle); if (snd_mixer_selem_has_playback_switch (priv->elem)) { snd_mixer_selem_get_playback_switch (priv->elem, 0, &value); } else if (snd_mixer_selem_has_capture_switch (priv->elem)) { snd_mixer_selem_get_capture_switch (priv->elem, 0, &value); } else { g_warning ("%s (). No idea what to do for mixer element \"%s\"!", __FUNCTION__, snd_mixer_selem_get_name (priv->elem)); } return value; }
/* mute: 0 -> mute, 1 -> unmute */ void sound_mixer_mute(const char *mixer, MUTEST mute) { int i; snd_mixer_t *handle = NULL; snd_mixer_elem_t *elem = NULL; elem = sound_get_elem(mixer, &handle); if (!elem) return; for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { if (snd_mixer_selem_has_playback_channel(elem, i) && snd_mixer_selem_has_playback_switch(elem)) snd_mixer_selem_set_playback_switch(elem, i, mute); else if (snd_mixer_selem_has_capture_channel(elem, i) && snd_mixer_selem_has_capture_switch(elem)) snd_mixer_selem_set_capture_switch(elem, i, mute); } snd_mixer_close(handle); }
/* Gets the current sound profile in use */ struct sound_profile* get_current_sound_profile() { struct sound_profile* current = NULL; for (int i = 0; i < SOUND_PROFILES_SIZE; ++i) { // Skip sound profiles which have not been successfully installed. if (!SOUND_PROFILES[i]->init_ok) { continue; } snd_mixer_elem_t* e = SOUND_PROFILES[i]->mixer_element; if (snd_mixer_selem_has_playback_switch(e) && is_mixer_elem_playback_switch_on(e)) { if (!current || ( strcmp(SOUND_PROFILES[i]->volume_cntrl_mixer_element_name, SOUND_PROFILES[i]->mixer_element_name) != 0 && is_mixer_elem_playback_switch_on(SOUND_PROFILES[i]->volume_cntrl_mixer_element))) current = SOUND_PROFILES[i]; } } assert(current); return current; }
status_t ALSAMixer::setPlaybackMuteState(uint32_t device, bool state) { for (int j = 0; mixerProp[j][SND_PCM_STREAM_PLAYBACK].device; j++) if (mixerProp[j][SND_PCM_STREAM_PLAYBACK].device & device) { mixer_info_t *info = mixerProp[j][SND_PCM_STREAM_PLAYBACK].mInfo; if (!info || !info->elem) return INVALID_OPERATION; if (snd_mixer_selem_has_playback_switch (info->elem)) { int err = snd_mixer_selem_set_playback_switch_all (info->elem, static_cast<int>(!state)); if (err < 0) { ALOGE("Unable to %s playback mixer switch %s", state ? "enable" : "disable", info->name); return INVALID_OPERATION; } } info->mute = state; } return NO_ERROR; }
static void _j4status_alsa_section_update(J4statusAlsaSection *section, snd_mixer_elem_t *elem) { if ( ( ! snd_mixer_selem_has_playback_volume(elem) ) || ( ! snd_mixer_selem_has_playback_switch(elem) ) || ( ! snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) ) ) return; int error; gboolean pswitch = TRUE; error = snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, &pswitch); if ( error < 0 ) g_warning("Couldn't get muted status: %s", snd_strerror(error)); else { if ( pswitch ) j4status_section_set_state(section->section, J4STATUS_STATE_GOOD); else j4status_section_set_state(section->section, J4STATUS_STATE_BAD); } glong volume = 0; if ( section->use_dB ) error = snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_FRONT_LEFT, &volume); else error = snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &volume); if ( error < 0 ) g_warning("Couldn't get volume: %s", snd_strerror(error)); else { guint8 vol; gchar *v; vol = _j4status_alsa_get_normalized_volume(volume, section->min, section->max, section->use_dB); v = g_strdup_printf("%hu%%", vol); j4status_section_set_value(section->section, v); } }
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; }
static void gst_alsa_mixer_ensure_track_list (GstAlsaMixer * mixer) { gint i, count; snd_mixer_elem_t *element, *master; GList *item; g_return_if_fail (mixer->handle != NULL); if (mixer->tracklist) return; g_static_rec_mutex_lock (mixer->rec_mutex); master = gst_alsa_mixer_find_master_mixer (mixer, mixer->handle); count = snd_mixer_get_count (mixer->handle); element = snd_mixer_first_elem (mixer->handle); /* build track list * * Some ALSA tracks may have playback and capture capabilities. * Here we model them as two separate GStreamer tracks. */ for (i = 0; i < count; i++) { GstMixerTrack *play_track = NULL; GstMixerTrack *cap_track = NULL; const gchar *name; GList *item; gint samename = 0; name = snd_mixer_selem_get_name (element); /* prevent dup names */ for (item = mixer->tracklist; item != NULL; item = item->next) { snd_mixer_elem_t *temp; if (GST_IS_ALSA_MIXER_OPTIONS (item->data)) temp = GST_ALSA_MIXER_OPTIONS (item->data)->element; else temp = GST_ALSA_MIXER_TRACK (item->data)->element; if (strcmp (name, snd_mixer_selem_get_name (temp)) == 0) samename++; } GST_LOG ("[%s] probing element #%u, mixer->dir=%u", name, i, mixer->dir); if (mixer->dir & GST_ALSA_MIXER_PLAYBACK) { gboolean has_playback_switch, has_playback_volume; has_playback_switch = snd_mixer_selem_has_playback_switch (element); has_playback_volume = snd_mixer_selem_has_playback_volume (element); GST_LOG ("[%s] PLAYBACK: has_playback_volume=%d, has_playback_switch=%d" "%s", name, has_playback_volume, has_playback_switch, (element == master) ? " MASTER" : ""); if (has_playback_volume) { gint flags = GST_MIXER_TRACK_OUTPUT; if (element == master) flags |= GST_MIXER_TRACK_MASTER; play_track = gst_alsa_mixer_track_new (element, samename, i, flags, FALSE, NULL, FALSE); } else if (has_playback_switch) { /* simple mute switch */ play_track = gst_alsa_mixer_track_new (element, samename, i, GST_MIXER_TRACK_OUTPUT, TRUE, NULL, FALSE); } if (snd_mixer_selem_is_enumerated (element)) { GstMixerOptions *opts = gst_alsa_mixer_options_new (element, i); GST_LOG ("[%s] is enumerated (%d)", name, i); mixer->tracklist = g_list_append (mixer->tracklist, opts); } } if (mixer->dir & GST_ALSA_MIXER_CAPTURE) { gboolean has_capture_switch, has_common_switch; gboolean has_capture_volume, has_common_volume; has_capture_switch = snd_mixer_selem_has_capture_switch (element); has_common_switch = snd_mixer_selem_has_common_switch (element); has_capture_volume = snd_mixer_selem_has_capture_volume (element); has_common_volume = snd_mixer_selem_has_common_volume (element); GST_LOG ("[%s] CAPTURE: has_capture_volume=%d, has_common_volume=%d, " "has_capture_switch=%d, has_common_switch=%d, play_track=%p", name, has_capture_volume, has_common_volume, has_capture_switch, has_common_switch, play_track); if (has_capture_volume && !(play_track && has_common_volume)) { cap_track = gst_alsa_mixer_track_new (element, samename, i, GST_MIXER_TRACK_INPUT, FALSE, NULL, play_track != NULL); } else if (has_capture_switch && !(play_track && has_common_switch)) { cap_track = gst_alsa_mixer_track_new (element, samename, i, GST_MIXER_TRACK_INPUT, TRUE, NULL, play_track != NULL); } } if (play_track && cap_track) { GST_ALSA_MIXER_TRACK (play_track)->shared_mute = GST_ALSA_MIXER_TRACK (cap_track); GST_ALSA_MIXER_TRACK (cap_track)->shared_mute = GST_ALSA_MIXER_TRACK (play_track); } if (play_track) mixer->tracklist = g_list_append (mixer->tracklist, play_track); if (cap_track) mixer->tracklist = g_list_append (mixer->tracklist, cap_track); element = snd_mixer_elem_next (element); } for (item = mixer->tracklist; item != NULL; item = item->next) { snd_mixer_elem_t *temp; if (GST_IS_ALSA_MIXER_OPTIONS (item->data)) temp = GST_ALSA_MIXER_OPTIONS (item->data)->element; else temp = GST_ALSA_MIXER_TRACK (item->data)->element; snd_mixer_elem_set_callback (temp, gst_alsa_mixer_elem_handle_callback); snd_mixer_elem_set_callback_private (temp, mixer); } g_static_rec_mutex_unlock (mixer->rec_mutex); }