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

ほとんどのコードを次から抽出しました。協会

本当の問題は、上記のコードが機能することです。スピーカーの音量ボタンを押すとコールバックが実行されます。みんな大丈夫です。その後、システムを再起動し、1日後に戻ってきました。今、コードは何もしません。現在設定されていると思うもの(間違ったもの)を出力しますが、ボタンを押しても反応しません。

私は迷っています。 ALSAが時々機能するのはなぜですか?

関連情報