从C代码设置ALSA主音量(以dB为单位)

时间:2013-10-21 08:17:43

标签: c linux alsa mixer

我似乎无法在我的机器上以dB为单位设置音量。

我在VirtualBox中运行Ubuntu 13.04系统(用于开发)。

我按照这些说明操作set the volume as scalarcontrol the mute state,一切正常。

但是当我尝试使用此功能将其设置为dB时

  

snd_mixer_selem_set_playback_dB_all(elem,volume,0)

或使用该功能

  

snd_mixer_selem_set_playback_dB(elem,chn,volume,0)

它始终失败,错误代码 -22 (无效参数)

在您提出问题之前:我已尝试设置各种音量级别(从-20000到20000),我还将最后一个参数更改为三个定义的值[-1,0,1]

这是我现在完整的测试代码:

#include <alsa/asoundlib.h>
#include <stdbool.h>
#include <stdlib.h>

void SetAlsaMasterVolume(long volume) {
    long min, max;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;
    const char *card = "default";
    const char *selem_name = "Master";
    int x, mute_state;
    long i;

    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);

    //snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
    //snd_mixer_selem_set_playback_volume_all(elem, volume * max / 100);

    snd_mixer_selem_get_playback_dB_range(elem, &min, &max);
    printf("min: %ld, max: %ld\n", min, max);

    snd_mixer_selem_channel_id_t chn;
    for (chn = 0; chn < 32; chn++) {
        for (i = -1000; i <= 1000; i++)
            if (x = snd_mixer_selem_set_playback_dB(elem, chn, i, 0)) {
                ;//printf("%d: %d %s\n", chn, x, snd_strerror(x));
            } else {
                printf("Volume successfully set in dB!\n");
            }
    }

    if (snd_mixer_selem_has_playback_switch(elem)) {
        snd_mixer_selem_set_playback_switch_all(elem, true);
        snd_mixer_selem_get_playback_switch(elem, 0, &mute_state);
        if (!mute_state) {
            printf("System Muted.\n");
        } else {
            printf("System unmuted.\n");
        }
    }

    snd_mixer_close(handle);
}

int main() {
    SetAlsaMasterVolume(100);
    return 0;
}

正如你在本例中所见,我尝试自己设置每个频道,这与“snd_mixer_selem_set_playback_dB_all”相同,但我想尝试一下,看看我是否得到不同的结果。

此示例的输出如下所示:

  

min:15774463,max:191

     

系统取消静音。

因为我扩大了我测试的dB值范围,输出是:

  

min:1,max:191

也许我在这里遗漏了一些东西...... 我希望你能帮助我!

修改

要编译此脚本,请使用以下命令:

  

gcc test.c -lasound -o test

1 个答案:

答案 0 :(得分:1)

我遇到了类似的问题。原因似乎是来自pulseaudio的干扰。但是,要杀人有点困难。一旦我跑了

mkdir -p ~/.pulse
echo autospawn=no > ~/.pulse/client.conf
killall pulseaudio

pulseaudio死了并且死了,我写的ALSA程序能够从调音台获得dB信息。

或者,您可以通过直接与卡片对话来完成pulseaudio的最终运行。变化

const char *card = "default";

const char *card = "hw:0";

看看它对你有什么影响。