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가 때때로 작동하는 이유는 무엇입니까?

관련 정보