Beispiel #1
0
void
moko_alsa_volume_control_set_element_from_name (MokoAlsaVolumeControl *control,
					       const gchar *name)
{
	MokoAlsaVolumeControlPrivate *priv =
		ALSA_VOLUME_CONTROL_PRIVATE (control);

	if (!priv->device) return;
	
	detach_mixer (control);
	
	if (!name) {
		moko_alsa_volume_control_set_element (control, NULL);
		return;
	}
	
	open_mixer (control);
	if ((snd_mixer_attach (priv->mixer_handle, priv->device) == 0) &&
	    (snd_mixer_selem_register (priv->mixer_handle, NULL, NULL) == 0) &&
	    (snd_mixer_load (priv->mixer_handle) == 0)) {
		snd_mixer_elem_t *elem;
		
		elem = snd_mixer_first_elem (priv->mixer_handle);
		while (elem) {
			const char *elem_name = snd_mixer_selem_get_name (elem);
			if (strcmp (elem_name, name) == 0)
				break;
			elem = snd_mixer_elem_next (elem);
		}
		
		if (!elem) {
			snd_mixer_detach (priv->mixer_handle, priv->device);
			close_mixer (control);
			g_warning ("Mixer element '%s' not found", name);
			attach_mixer (control);
		} else {
			snd_mixer_selem_id_t *id;
			if (snd_mixer_selem_id_malloc (&id) != 0) {
				g_warning ("Unable to allocate element id");
				snd_mixer_detach (
					priv->mixer_handle, priv->device);
				close_mixer (control);
			} else {
				snd_mixer_selem_get_id (elem, id);
				snd_mixer_detach (
					priv->mixer_handle, priv->device);
				close_mixer (control);
				g_debug ("Setting element ID");
				moko_alsa_volume_control_set_element (
					control, id);
				snd_mixer_selem_id_free (id);
			}
		}
	} else
		g_warning ("Unable to open mixer on card '%s'", priv->device);
}
Beispiel #2
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);
	}
}
Beispiel #3
0
static void
detach_mixer (MokoAlsaVolumeControl *self)
{
	MokoAlsaVolumeControlPrivate *priv = ALSA_VOLUME_CONTROL_PRIVATE (self);
	
	if (priv->mixer_handle && priv->device &&
	    priv->element && priv->mixer_elem) {
		snd_mixer_detach (priv->mixer_handle, priv->device);
		priv->mixer_elem = NULL;
		g_debug ("Detached from mixer");
		close_mixer (self);
	}
}
Beispiel #4
0
/**
 * Deinitializes the alsa system by
 * closing the mixer.
 */
static void
alsaunset(void)
{
    if (active_card == NULL)
        return;

    unset_io_watch();

    // 'elem' must be set to NULL at last, because alsa_cb()
    // is invoked when closing mixer, and elem is needed.
    close_mixer(handle, active_card->dev);
    handle = NULL;
    elem = NULL;
    active_card = NULL;
}
Beispiel #5
0
/**
 * Get all playable channels for a single alsa card and
 * return them as a GSList.
 *
 * @param card HCTL name of the alsa card
 * @return the GSList of channels
 */
static GSList *
get_channels(const char *card)
{
    int ccount, i;
    snd_mixer_t *mixer;
    snd_mixer_elem_t *telem;
    GSList *channels = NULL;

    mixer = open_mixer(card, NULL, 0);
    if (mixer == NULL)
        return NULL;

    ccount = snd_mixer_get_count(mixer);
    telem = snd_mixer_first_elem(mixer);

    for (i = 0; i < ccount; i++) {
        if (snd_mixer_selem_has_playback_volume(telem))
            channels = g_slist_append(channels,
                                      strdup(snd_mixer_selem_get_name(telem)));
        telem = snd_mixer_elem_next(telem);
    }

#ifdef DEBUG
    GSList *tmp = channels;
    if (tmp) {
        printf("Card %s: available channels\n", card);
        while (tmp) {
            printf("\t%s\n", (char *) tmp->data);
            tmp = tmp->next;
        }
    } else {
        printf("Card %s: no playable channels\n", card);
    }
#endif

    close_mixer(mixer, card);

    return channels;
}