Ejemplo n.º 1
0
double getnormvolume(snd_mixer_elem_t *elem) {
    long min=0, max=0, value = 0;
	double normalized=0, min_norm = 0;
    int err;

	err = snd_mixer_selem_get_playback_dB_range(elem, &min, &max);
    if (err < 0 || min >= max) {
        err = snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
        if (err < 0 || min == max)
            return 0;

        err = snd_mixer_selem_get_playback_volume(elem, channel, &value);
        if (err < 0)
            return 0;

        return (value - min) / (double)(max - min);
    }

	err = snd_mixer_selem_get_playback_dB(elem, channel, &value);
    if (err < 0)
        return 0;

    if (use_linear_dB_scale(min, max))
        return (value - min) / (double)(max - min);

	normalized = exp10((value - max) / 6000.0);
	if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
		min_norm = exp10((min - max) / 6000.0);
		normalized = (normalized - min_norm) / (1 - min_norm);
	}

	return normalized;
}
Ejemplo n.º 2
0
static int set_normalized_volume(snd_mixer_elem_t *elem,
				 snd_mixer_selem_channel_id_t channel,
				 double volume,
				 int dir,
				 enum ctl_dir ctl_dir)
{
	long min, max, value;
	double min_norm;
	int err;

	err = get_dB_range[ctl_dir](elem, &min, &max);
	if (err < 0 || min >= max) {
		err = get_raw_range[ctl_dir](elem, &min, &max);
		if (err < 0)
			return err;

		value = lrint_dir(volume * (max - min), dir) + min;
		return set_raw[ctl_dir](elem, channel, value);
	}

	if (use_linear_dB_scale(min, max)) {
		value = lrint_dir(volume * (max - min), dir) + min;
		return set_dB[ctl_dir](elem, channel, value, dir);
	}

	if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
		min_norm = exp10((min - max) / 6000.0);
		volume = volume * (1 - min_norm) + min_norm;
	}
	value = lrint_dir(6000.0 * log10(volume), dir) + max;
	return set_dB[ctl_dir](elem, channel, value, dir);
}
Ejemplo n.º 3
0
/**
 * Adjusts the current volume and sends a notification (if enabled).
 *
 * @param vol new volume value
 * @param dir select direction (-1 = accurate or first bellow, 0 = accurate,
 * 1 = accurate or first above)
 * @param notify whether to send notification
 * @return 0 on success otherwise negative error code
 */
int
setvol(int vol, int dir, gboolean notify)
{
    long min = 0, max = 0, value;
    int cur_perc = getvol();
    double dvol = 0.01 * vol;

    int err = snd_mixer_selem_get_playback_dB_range(elem, &min, &max);
    if (err < 0 || min >= max || !normalize_vol()) {
        err = snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
        value = lrint_dir(dvol * (max - min), dir) + min;
        snd_mixer_selem_set_playback_volume_all(elem, value);
        if (enable_noti && notify && cur_perc != getvol())
            do_notify_volume(getvol(), FALSE);
        // intentionally set twice
        return snd_mixer_selem_set_playback_volume_all(elem, value);
    }

    if (use_linear_dB_scale(min, max)) {
        value = lrint_dir(dvol * (max - min), dir) + min;
        return snd_mixer_selem_set_playback_dB_all(elem, value, dir);
    }

    if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
        double min_norm = exp10((min - max) / 6000.0);
        dvol = dvol * (1 - min_norm) + min_norm;
    }

    value = lrint_dir(6000.0 * log10(dvol), dir) + max;
    snd_mixer_selem_set_playback_dB_all(elem, value, dir);
    if (enable_noti && notify && cur_perc != getvol())
        do_notify_volume(getvol(), FALSE);
    // intentionally set twice
    return snd_mixer_selem_set_playback_dB_all(elem, value, dir);
}
Ejemplo n.º 4
0
static double get_normalized_volume(snd_mixer_elem_t *elem,
				    snd_mixer_selem_channel_id_t channel,
				    enum ctl_dir ctl_dir)
{
	long min, max, value;
	double normalized, min_norm;
	int err;

	err = get_dB_range[ctl_dir](elem, &min, &max);
	if (err < 0 || min >= max) {
		err = get_raw_range[ctl_dir](elem, &min, &max);
		if (err < 0 || min == max)
			return 0;

		err = get_raw[ctl_dir](elem, channel, &value);
		if (err < 0)
			return 0;

		return (value - min) / (double)(max - min);
	}

	err = get_dB[ctl_dir](elem, channel, &value);
	if (err < 0)
		return 0;

	if (use_linear_dB_scale(min, max))
		return (value - min) / (double)(max - min);

	normalized = exp10((value - max) / 6000.0);
	if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
		min_norm = exp10((min - max) / 6000.0);
		normalized = (normalized - min_norm) / (1 - min_norm);
	}

	return normalized;
}