Смеситель Alsa и GtkVolumeButton

Я делаю код, чтобы получить и установить alsa mixer volume:

snd_mixer_elem_t *elem = NULL;
long alsa_min, alsa_max, alsa_vol;

int alsa_get_volume( void )
{
    long val;
    assert (elem);

    if (snd_mixer_selem_is_playback_mono(elem)) {
        snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
        return val;
    } else {
        int c, n = 0;
        long sum = 0;
        for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
                if (snd_mixer_selem_has_playback_channel(elem, c)) {
                        snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
                        sum += val;
                        n++;
                }
        }
        if (! n) {
                return 0;
        }
        val = sum/n;
        sum = (long)((double)(alsa_vol * (alsa_max - alsa_min))/100. + 0.5);
        if (sum != val) {
           alsa_vol = (long)(((val * 100.)/(alsa_max - alsa_min)) + 0.5);
        }
        return alsa_vol;
    }
}

int alsa_set_volume( int percentdiff )
{
    long volume;

    alsa_get_volume();

    alsa_vol += percentdiff;
    if( alsa_vol > 100 ) alsa_vol = 100;
    if( alsa_vol < 0 ) alsa_vol = 0;

    volume = (long)((alsa_vol * (alsa_max - alsa_min)/100.) + 0.5);

    snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
    snd_mixer_selem_set_playback_switch_all(elem, 1);
    muted = 0;
    mutecount = 0;

    return alsa_vol;
}

Я привык к тому, чтобы громкость миксера alsa изменилась на GtkVolumeButton. Пробовал это, но когда значение из кнопки gtk было изменено вверх или вниз, alsa mixer всегда перескакивает до 100%:

int gtk_volume_button_get_value (GtkWidget *button)
{
    return (int) (gtk_scale_button_get_value(GTK_SCALE_BUTTON(button)) * 100);
}

void gtk_volume_button_set_value (GtkWidget *button, int value)
{
    gtk_scale_button_set_value(GTK_SCALE_BUTTON(button), (gdouble) value/100);
}

void volume_value_changed_cb(GtkVolumeButton *button, gpointer user_data)
{
    int vol = (int)(gtk_volume_button_get_value(volume_button) + 0.5);

    alsa_set_volume(vol);
}

Пожалуйста, помогите мне написать текстовый код для GtkVolumeButton.

0
nl ja de

1 ответы

Ваша проблема не имеет ничего общего с GtkVolume. Фактически, он исходит от вас, используя два разных подхода к обработке тома. alsa_get_volume дает вам абсолютный уровень звука, который является целым числом. Можно было бы ожидать, что alsa_set_volume примет тот же диапазон значений. Вот как вы его используете в volume_value_changed_cb : «получите уровень громкости регулятора громкости от 0 до 100 и установите его как текущий том. ».

Однако реализация полностью отличается. Он реализован так, как будто вы хотели сказать «добавить или вычесть x% текущего объема звука». Вы получаете текущий уровень громкости и добавляете этот процент, поэтому вы вычисляете относительный уровень звука, а не абсолютный. Итак, если ваш начальный уровень звука составляет 50%, и вы хотите снизить его до 45%, можно было бы ожидать, что вы вызовете alsa_set_volume (45) , чтобы сделать это. Но в настоящее время вызов alsa_set_volume (45) установит alsa_vol в 50 + 45 = 95%.

Поэтому вам нужно использовать абсолютный том, а не относительный.

/* newvol: Desired volume level in the [0;100] range */
int alsa_set_volume (int newvol)
{
    long volume;

    alsa_vol = CLAMP(absvol, 0, 100);

    volume = (long)((alsa_vol * (alsa_max - alsa_min)/100.) + alsa_min);

    snd_mixer_selem_set_playback_volume_all(elem, volume);
    snd_mixer_selem_set_playback_switch_all(elem, 1);
    muted = 0;
    mutecount = 0;

    return alsa_vol;
}
0
добавлено