开机后扬声器无声音

问题描述:个人笔记本电脑长久以来都有一个问题,开机之后扬声器没声音,从应用层看毫无问题,所有音乐视频照常播放,能调音量,就是没声音。必须插一下耳机,耳机里有声音。然后再拔出耳机,外部扬声器也有声音了。因此使用起来并无大碍,只需要准备一个耳机,开机之后插拔一下即可。

但问题始终要解决的,我总不可能每次开机的时候旁边都有个有线耳机吧。所以要解决这个问题,可从以下两个路子着手:

  1. 彻底解决这个问题,每次开机正常有声音,插入耳机,则声音通过耳机输出;
  2. 退而求其次,能在开机之后不需要插拔耳机,也能将外部扬声器声音释放出来,比如一个 shell 命令激活。

目前我只做到了第二种,尚未完美解决。

记录一下排查问题的大致流程:

首先上网查了一下相关问题,怀疑是 pulseaudio 的问题,结果偶然某一次正常播放音频的时候,我发现杀掉 pulseaudio 的进程竟然毫无影响,因此可能不是它的问题。

然后查看 alsamixer 得知:

可以看到有两张声卡,一个是default,一个是HDA Intel PCH,但其实我只有一张声卡

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC255 Analog [ALC255 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 7: HDMI 1 [HDMI 1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 8: HDMI 2 [HDMI 2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 9: HDMI 3 [HDMI 3]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 10: HDMI 4 [HDMI 4]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

此时我观察到在无声音的状态下使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
yychi@~> speaker-test -c 2

speaker-test 1.2.6

Playback device is default
Stream parameters are 48000Hz, S16_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 96 to 1048576
Period size range from 32 to 349526
Using max buffer size 1048576
Periods = 4
was set period_size = 262144
was set buffer_size = 1048576
 0 - Front Left
 1 - Front Right
^CTime per period = 10.942892
yychi@~> speaker-test -c 2 -D hw:0

speaker-test 1.2.6

Playback device is hw:0
Stream parameters are 48000Hz, S16_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 64 to 1048576
Period size range from 32 to 524288
Using max buffer size 1048576
Periods = 4
was set period_size = 262144
was set buffer_size = 1048576
 0 - Front Left
 1 - Front Right
^CTime per period = 5.761266

测试扬声器的时候,指定 device 为hw:0总能够发出声音,此时便想到很可能是系统默认的播放设备(playback)不对,因此按照 archwiki 上的教程 设置了默认声卡。其实就是新建一个文件然后重启:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# file: ~/.asoundrc

pcm.!default {
   type hw
   card PCH
}

ctl.!default {
   type hw
   card PCH
}

重启之后果然立刻就有声音了,正当我被折腾成功的喜悦包围之时,我试着将耳机插入耳机孔,tmd 根本就没效果。这不完犊子了吗,修好了外放,耳机失效了。接着就是一顿找,

1
alsactl restore

拯救了耳机的输出,但没有完全拯救,因为这个时候耳机和外部扬声器都有声音。也就是说,他不会根据耳机的插拔而切换输出了,而是两方都有输出。

然而就是根据耳机插拔自动切换输出设备的功能,在我设置了默认声卡之后,一直得不到解决。此前,虽然需要插拔一下耳机,外部扬声器才能播放声音,好歹耳机的插拔还是能正常生效的。所以,我还是删掉了默认声卡的配置,转而寻求“开机后如何切换 sound playback”。直到我找到 参考 1.

其中提到"card-profile"这个概念,听起来像是声卡的情景模式,通过如下命令列出所有支持的 card-profiles:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
yychi@~> pacmd list-cards
1 card(s) available.
    index: 0
	name: <alsa_card.pci-0000_00_1f.3>
	driver: <module-alsa-card.c>
	owner module: 6
	properties:
		alsa.card = "0"
		alsa.card_name = "HDA Intel PCH"
		alsa.long_card_name = "HDA Intel PCH at 0xb4220000 irq 135"
		alsa.driver_name = "snd_hda_intel"
		device.bus_path = "pci-0000:00:1f.3"
		sysfs.path = "/devices/pci0000:00/0000:00:1f.3/sound/card0"
		device.bus = "pci"
		device.vendor.id = "8086"
		device.vendor.name = "Intel Corporation"
		device.product.id = "9d71"
		device.product.name = "Sunrise Point-LP HD Audio"
		device.form_factor = "internal"
		device.string = "0"
		device.description = "内置音频"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card-pci"
	profiles:
		input:analog-stereo: 模拟立体声 输入 (priority 32833, available: unknown)
		output:analog-stereo: 模拟立体声 输出 (priority 39268, available: unknown)
		output:analog-stereo+input:analog-stereo: 模拟立体声双工 (priority 39333, available: unknown)
		output:hdmi-stereo: Digital Stereo (HDMI) 输出 (priority 5900, available: no)
		output:hdmi-stereo+input:analog-stereo: Digital Stereo (HDMI) 输出 + 模拟立体声 输入 (priority 5965, available: unknown)
		output:hdmi-surround: Digital Surround 5.1 (HDMI) 输出 (priority 800, available: no)
		output:hdmi-surround+input:analog-stereo: Digital Surround 5.1 (HDMI) 输出 + 模拟立体声 输入 (priority 865, available: unknown)
		output:hdmi-surround71: Digital Surround 7.1 (HDMI) 输出 (priority 800, available: no)
		output:hdmi-surround71+input:analog-stereo: Digital Surround 7.1 (HDMI) 输出 + 模拟立体声 输入 (priority 865, available: unknown)
		output:hdmi-stereo-extra1: Digital Stereo (HDMI 2) 输出 (priority 5700, available: no)
		output:hdmi-stereo-extra1+input:analog-stereo: Digital Stereo (HDMI 2) 输出 + 模拟立体声 输入 (priority 5765, available: unknown)
		output:hdmi-surround-extra1: Digital Surround 5.1 (HDMI 2) 输出 (priority 600, available: no)
		output:hdmi-surround-extra1+input:analog-stereo: Digital Surround 5.1 (HDMI 2) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		output:hdmi-surround71-extra1: Digital Surround 7.1 (HDMI 2) 输出 (priority 600, available: no)
		output:hdmi-surround71-extra1+input:analog-stereo: Digital Surround 7.1 (HDMI 2) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		output:hdmi-stereo-extra2: Digital Stereo (HDMI 3) 输出 (priority 5700, available: no)
		output:hdmi-stereo-extra2+input:analog-stereo: Digital Stereo (HDMI 3) 输出 + 模拟立体声 输入 (priority 5765, available: unknown)
		output:hdmi-surround-extra2: Digital Surround 5.1 (HDMI 3) 输出 (priority 600, available: no)
		output:hdmi-surround-extra2+input:analog-stereo: Digital Surround 5.1 (HDMI 3) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		output:hdmi-surround71-extra2: Digital Surround 7.1 (HDMI 3) 输出 (priority 600, available: no)
		output:hdmi-surround71-extra2+input:analog-stereo: Digital Surround 7.1 (HDMI 3) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		output:hdmi-stereo-extra3: Digital Stereo (HDMI 4) 输出 (priority 5700, available: no)
		output:hdmi-stereo-extra3+input:analog-stereo: Digital Stereo (HDMI 4) 输出 + 模拟立体声 输入 (priority 5765, available: unknown)
		output:hdmi-surround-extra3: Digital Surround 5.1 (HDMI 4) 输出 (priority 600, available: no)
		output:hdmi-surround-extra3+input:analog-stereo: Digital Surround 5.1 (HDMI 4) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		output:hdmi-surround71-extra3: Digital Surround 7.1 (HDMI 4) 输出 (priority 600, available: no)
		output:hdmi-surround71-extra3+input:analog-stereo: Digital Surround 7.1 (HDMI 4) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		output:hdmi-stereo-extra4: Digital Stereo (HDMI 5) 输出 (priority 5700, available: no)
		output:hdmi-stereo-extra4+input:analog-stereo: Digital Stereo (HDMI 5) 输出 + 模拟立体声 输入 (priority 5765, available: unknown)
		output:hdmi-surround-extra4: Digital Surround 5.1 (HDMI 5) 输出 (priority 600, available: no)
		output:hdmi-surround-extra4+input:analog-stereo: Digital Surround 5.1 (HDMI 5) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		output:hdmi-surround71-extra4: Digital Surround 7.1 (HDMI 5) 输出 (priority 600, available: no)
		output:hdmi-surround71-extra4+input:analog-stereo: Digital Surround 7.1 (HDMI 5) 输出 + 模拟立体声 输入 (priority 665, available: unknown)
		off: 关 (priority 0, available: unknown)
	active profile: <output:hdmi-stereo-extra1+input:analog-stereo>
	sinks:
		alsa_output.pci-0000_00_1f.3.hdmi-stereo-extra1/#0: 内置音频 Digital Stereo (HDMI 2)
	sources:
		alsa_output.pci-0000_00_1f.3.hdmi-stereo-extra1.monitor/#0: Monitor of 内置音频 Digital Stereo (HDMI 2)
		alsa_input.pci-0000_00_1f.3.analog-stereo/#1: 内置音频 模拟立体声
	ports:
		analog-input-mic: Microphone (priority 8700, latency offset 0 usec, available: unknown)
			properties:
				device.icon_name = "audio-input-microphone"
		analog-output-speaker: Speakers (priority 10000, latency offset 0 usec, available: unknown)
			properties:
				device.icon_name = "audio-speakers"
		analog-output-headphones: Headphones (priority 9900, latency offset 0 usec, available: no)
			properties:
				device.icon_name = "audio-headphones"
		hdmi-output-0: HDMI / DisplayPort (priority 5900, latency offset 0 usec, available: no)  # available: yes if headphone plugged
			properties:
				device.icon_name = "video-display"
		hdmi-output-1: HDMI / DisplayPort 2 (priority 5800, latency offset 0 usec, available: no)
			properties:
				device.icon_name = "video-display"
		hdmi-output-2: HDMI / DisplayPort 3 (priority 5700, latency offset 0 usec, available: no)
			properties:
				device.icon_name = "video-display"
		hdmi-output-3: HDMI / DisplayPort 4 (priority 5600, latency offset 0 usec, available: no)
			properties:
				device.icon_name = "video-display"
		hdmi-output-4: HDMI / DisplayPort 5 (priority 5500, latency offset 0 usec, available: no)
			properties:
				device.icon_name = "video-display"

接着

1
pacmd set-card-profile alsa_card.pci-0000_00_1f.3 output:analog-stereo+input:analog-stereo

设置声卡的情景模式,敲完之后外部扬声器就有声音了,而且耳机插拔也是正常生效的。值得注意的是,插入耳机后,上述注释处就变成 yes 了。

这个问题暂时解决到这里,等以后有时间看能否完全解决!

当天更新:重启之后发现不用重新再走一遍上述流程,可以看到"active profile: <output:hdmi-stereo-extra1+input:analog-stereo>“已经持久化改变了。那么这个问题就算解决啦!

USB 耳机无声音

起因:入了个 usb 耳机,然后插上电脑(archlinux)无效果。电脑自带扬声器和 3.5mm 耳机孔都是好好工作的,然而插了 usb 耳机后好像没插一样。

先看下 lsusb 排除下物理连接问题

1
2
3
4
5
6
7
yychi@~> lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 04f2:b5a3 Chicony Electronics Co., Ltd XiaoMi USB 2.0 Webcam
Bus 001 Device 003: ID 04f3:0c1a Elan Microelectronics Corp. ELAN:Fingerprint
Bus 001 Device 004: ID 8087:0a2b Intel Corp. Bluetooth wireless interface
Bus 001 Device 009: ID 0b0e:0313 GN Netcom Jabra EVOLVE 30 II # usb headphone
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

按照上述经验怀疑是 card-profile 的问题。是不是情景模式不对呢?最后发现和上次不一样,上次普通耳机和外置扬声器用的一张声卡。这次 usb 耳机用的自带声卡,所以需要切换成自带声卡,且调对情景模式。

现在用 pipewire 替代 pulse-audio,其对应的配置命令行为pactl

1
2
3
4
5
6
7
8
yychi@~> pactl list cards short
45	alsa_card.pci-0000_00_1f.3	alsa # 自带声卡
576	alsa_card.usb-GN_Audio_A_S_Jabra_EVOLVE_30_II_0005EDED3F4A09-00	alsa # usb耳机声卡

pactl set-card-profile alsa_card.usb-GN_Audio_A_S_Jabra_EVOLVE_30_II_0005EDED3F4A09-00 pro-audio  # 设置正确的情景模式
# 切换声卡,即设置默认输入输出
pactl set-default-sink alsa_output.usb-GN_Audio_A_S_Jabra_EVOLVE_30_II_0005EDED3F4A09-00.pro-output-0 # 设置默认输出
pactl set-default-source alsa_input.usb-GN_Audio_A_S_Jabra_EVOLVE_30_II_0005EDED3F4A09-00.pro-input-0 # 设置默认输入

一番折腾,最终成功让 usb 耳机出声。

一些命令:

命令含义
pactl list cards [short]列出可用声卡
pactl get-default-sink/source获取默认输出/输入
pactl set-card-profile <card-name/index> <card-profile>给指定声卡设置情景模式

References

  1. How can I switch between different audio output hardware using the shell?
  2. Archwiki: Advanced Linux Sound Architecture
  3. [SOLVED] sound not working