Example #1
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);
}
Example #2
0
static void volume(double vol) {
  set_volume = vol;
  double vol_setting = vol2attn(vol, alsa_mix_maxdb, alsa_mix_mindb);
  // debug(1,"Setting volume db to %f, for volume input of %f.",vol_setting/100,vol);
  if (snd_mixer_selem_set_playback_dB_all(alsa_mix_elem, vol_setting, -1) != 0)
    die("Failed to set playback dB volume");
  if (has_mute)
    snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, (vol != -144.0));
}
Example #3
0
/* Set volume with given volume_type.
 * round_direction: >0 to round up, <0 to round down, 0 to use default lrint
 *                  rounding direction (see fsetround(3)).*/
void set_vol(
        snd_mixer_elem_t* elem,
        enum Volume_type volume_type,
        long int new_vol,
        int round_direction)
{
    // TODO: possibly add new_vol range check
    int err = 0;

    if (volume_type == hardware) {
        err = snd_mixer_selem_set_playback_volume_all(elem, new_vol);
    }
    else if (volume_type == decibels) {
        err = snd_mixer_selem_set_playback_dB_all(elem, new_vol, round_direction);
    }
    else if (volume_type == alsa_percentage) {
        double new_vol_norm = (double) new_vol / 100;
        PD_M("Setting alsa_percentage volume: %g\n", new_vol_norm);
        err = set_normalized_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, new_vol_norm, round_direction);
        if (err == 0) {
            err = set_normalized_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, new_vol_norm, round_direction);
        }
    }
    else if (volume_type == hardware_percentage) {
        long int min, max;
        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
        change_range(&new_vol, 0, 100, min, max, false);

        err = snd_mixer_selem_set_playback_volume_all(elem, new_vol);
    }
    else {
        fprintf(stderr, "avolt ERROR: set_vol: Unknown volume_type '%i'.\n", volume_type);
        err = -1;
    }

    if (err != 0) {
        fprintf(stderr, "avolt ERROR: snd mixer set playback volume failed with new vol '%li' and volume type '%i'.\n", new_vol, volume_type);
    }
}