我在 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 有时会起作用?