为什么ALSA经常读不到声卡状态

为什么ALSA经常读不到声卡状态

我在 PI5 上使用 ALSA 的经历很糟糕。它会播放和录制声音,但控制界面似乎只能在某些时候工作。我找不到原因。我需要一些帮助来了解正在发生的事情。

我的目标是让 USB 扬声器 (Polycom P3200M) 将其音量重置为启动时的最后一个音量设置。这应该与 alsactl rdaemon.此外,有一个罐装服务alsa-state.service可以做到这一点。它不起作用。我已经/etc/asla/state-daemon.conf就位,所以该rdaemon选项应该正在运行。

一看ps -ef就知道:

root         660       1  0 20:06 ?        00:00:00 /usr/sbin/alsactl -E HOME=/run/alsa -E XDG_RUNTIME_DIR=/run/alsa/runtime -s -n 19 -c rdaemon

因此,我必须假设该服务运行正常。问题是,如果我执行,amixer -c2我不会得到正确的输出。例如它将显示:

Simple mixer control 'PCM',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined
  Playback channels: Mono
  Limits: Playback 0 - 20
  Mono: Playback 9 [45%] [-22.00dB] [on]
Simple mixer control 'Headset',0
  Capabilities: cswitch cswitch-joined
  Capture channels: Mono
  Mono: Capture [on]

如果我然后通过按下按钮更改扬声器的音量,然后重新运行axmixer -c2,我会得到完全相同的输出。

通过查看时间戳,/var/lib/alsa/asound.state我可以看到该文件仅在启动时被触及,然后再也不会被触及。

最后,在一阵沮丧中,我编写了自己的代码来监视设备,并确定音量何时改变。

#include <stdio.h>
#include <alsa/asoundlib.h>

int elem_callback(snd_mixer_elem_t *elem,unsigned int mask);

int main(int argc, char* argv[])
{
    long min, max;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;
        const char *selem_name = "PCM";
    long curVolume;
    int res;
    
    if(argc!=2)
    {
        return(1);
    }
    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, argv[1]);
    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);

    printf("Name: %s\n",snd_mixer_selem_get_name(elem));


    snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
    printf("max: %d\nmin:%d\n",max,min);
    snd_mixer_selem_get_playback_volume(elem,SND_MIXER_SCHN_MONO,&curVolume);
    printf("Current Volume: %d\n",curVolume);

    snd_mixer_elem_set_callback(elem,elem_callback);

    while(1)
    {
        res=snd_mixer_wait(handle,-1);
        res=snd_mixer_handle_events(handle);
    }
        snd_mixer_close(handle);

    return(0);
}


int elem_callback(snd_mixer_elem_t *elem,unsigned int mask)
{
    long curVolume;

    switch(mask)
    {
        case 1:
            snd_mixer_selem_get_playback_volume(elem,SND_MIXER_SCHN_MONO,&curVolume);
            printf("Current Volume: %d\n",curVolume);
            printf("\tmask:  %d\n",mask);
            break;
        default:
            printf("Unrecognized mask: %d\n",mask);
            break;
    }
    return (0);
}

我从以下代码中提取了大部分代码关联

真正麻烦的是上面的代码有效。我可以按下扬声器上的音量按钮,回调就会被触发。一切都很好。然后我重新启动系统并在一天后回来。现在代码什么也没做。它将输出它认为当前设置的内容(不正确),但不会对按钮按下做出反应。

我不知所措。为什么 ALSA 有时会起作用?

相关内容