前言

在幽兰代码本上使用Waydroid时,可能会遇到声音无法播放的问题时,可以通过下面步骤进行解决。

问题原因

PipeWire简介

幽兰代码本上使用的多媒体服务器是PipeWire,它的主要作用是处理由硬件或应用程序提供的视音频流。

从Ubuntu的22.04版本开始,它已经替代了原有的PulseAudio,作为新的多媒体服务器。

ps -A | grep pipewire
   1438 ?        00:00:00 pipewire-pulse
   1485 ?        00:00:00 pipewire

在幽兰代码本上,PipWire运行了两个后台服务进程,其中pipewire-pulse是PulseAudio的替代程序,用于兼容原有的PulseAudio。

常用工具

PipeWire提供了一系列的工具,这些工具可以帮助开发人员快速的获取所需信息并对问题进行排查。

PipeWire的工具均使用pw-spa-作为工具名的前缀,下面列出了幽兰代码本上PipeWire相关的全部工具。

pw-cat pw-cli pw-dot pw-dsdplay pw-dump pw-jack
pw-link pw-loopback pw-metadata pw-mididump pw-midiplay pw-midirecord
pw-mon pw-play pw-profiler pw-record pw-reserve pw-top

spa-acp-tool spa-inspect spa-json-dump spa-monitor spa-resample

硬件设备获取

在PipeWire中,硬件设备被抽象成了节点,它通过读取配置文件提供的信息,获取硬件设备的相关属性,进而将它们抽象成节点,并进行操控。

在幽兰代码本中,硬件设备的配置信息由ALSA和WirePlumber两个部分提供,并通过WirePlumber对配置文件进行管理。

下面列举出了幽兰代码本上WirePlumber中的脚本文件信息。

/usr/share/wireplumber/
|-- bluetooth.conf
|-- bluetooth.lua.d
|   |-- 00-functions.lua
|   |-- 30-bluez-monitor.lua
|   |-- 50-bluez-config.lua
|   `-- 90-enable-all.lua
|-- common
|   `-- 00-functions.lua
|-- main.conf
|-- main.lua.d
|   |-- 00-functions.lua
|   |-- 20-default-access.lua
|   |-- 30-alsa-monitor.lua
|   |-- 30-libcamera-monitor.lua
|   |-- 30-v4l2-monitor.lua
|   |-- 40-device-defaults.lua
|   |-- 40-stream-defaults.lua
|   |-- 50-alsa-config.lua
|   |-- 50-default-access-config.lua
|   |-- 50-libcamera-config.lua
|   |-- 50-v4l2-config.lua
|   `-- 90-enable-all.lua
|-- policy.conf
|-- policy.lua.d
|   |-- 00-functions.lua
|   |-- 10-default-policy.lua
|   |-- 50-endpoints-config.lua
|   `-- 90-enable-all.lua
|-- scripts
|   |-- access
|   |   |-- access-default.lua
|   |   `-- access-portal.lua
|   |-- create-item.lua
|   |-- fallback-sink.lua
|   |-- intended-roles.lua
|   |-- monitors
|   |   |-- alsa-midi.lua
|   |   |-- alsa.lua
|   |   |-- bluez.lua
|   |   |-- libcamera.lua
|   |   `-- v4l2.lua
|   |-- policy-bluetooth.lua
|   |-- policy-device-profile.lua
|   |-- policy-device-routes.lua
|   |-- policy-endpoint-client-links.lua
|   |-- policy-endpoint-client.lua
|   |-- policy-endpoint-device.lua
|   |-- policy-node.lua
|   |-- restore-stream.lua
|   |-- static-endpoints.lua
|   `-- suspend-node.lua
`-- wireplumber.conf

其中ALSA是为了兼容PulseAudio而存在的,它通过读取UCM和UCM2(PulseAudio-14.2之后的版本使用)中的配置文件,获取硬件的属性信息。

在WirePlumber中,可以通过设置/usr/share/wireplumber/main.lua.d/50-alsa-config.lua文件中的alsa_monitor.enabled属性,决定PipeWire是否从ALSA中获取硬件的配置信息。

下面列举出了幽兰代码本上ALSA中的配置文件信息。

/usr/share/alsa
|-- alsa.conf
|-- alsa.conf.d
|   |-- 10-samplerate.conf
|   |-- 10-speexrate.conf
|   |-- 50-arcam-av-ctl.conf
|   |-- 50-jack.conf
|   |-- 50-oss.conf
|   |-- 50-pipewire.conf
|   |-- 50-pulseaudio.conf
|   |-- 60-upmix.conf
|   |-- 60-vdownmix.conf
|   |-- 98-usb-stream.conf
|   |-- 99-pipewire-default.conf
|   `-- pulse.conf
|-- cards
|   |-- AACI.conf
|   |-- ATIIXP-MODEM.conf
|   |-- ATIIXP-SPDMA.conf
|   |-- ATIIXP.conf
|   |-- AU8810.conf
|   |-- AU8820.conf
|   |-- AU8830.conf
|   |-- Audigy.conf
|   |-- Audigy2.conf
|   |-- Aureon51.conf
|   |-- Aureon71.conf
|   |-- CA0106.conf
|   |-- CMI8338-SWIEC.conf
|   |-- CMI8338.conf
|   |-- CMI8738-MC6.conf
|   |-- CMI8738-MC8.conf
|   |-- CMI8788.conf
|   |-- CS46xx.conf
|   |-- EMU10K1.conf
|   |-- EMU10K1X.conf
|   |-- ENS1370.conf
|   |-- ENS1371.conf
|   |-- ES1968.conf
|   |-- Echo_Echo3G.conf
|   |-- FM801.conf
|   |-- FWSpeakers.conf
|   |-- FireWave.conf
|   |-- GUS.conf
|   |-- HDA-Intel.conf
|   |-- HdmiLpeAudio.conf
|   |-- ICE1712.conf
|   |-- ICE1724.conf
|   |-- ICH-MODEM.conf
|   |-- ICH.conf
|   |-- ICH4.conf
|   |-- Loopback.conf
|   |-- Maestro3.conf
|   |-- NFORCE.conf
|   |-- PC-Speaker.conf
|   |-- PMac.conf
|   |-- PMacToonie.conf
|   |-- PS3.conf
|   |-- RME9636.conf
|   |-- RME9652.conf
|   |-- SB-XFi.conf
|   |-- SI7018.conf
|   |-- TRID4DWAVENX.conf
|   |-- USB-Audio.conf
|   |-- VIA686A.conf
|   |-- VIA8233.conf
|   |-- VIA8233A.conf
|   |-- VIA8237.conf
|   |-- VX222.conf
|   |-- VXPocket.conf
|   |-- VXPocket440.conf
|   |-- YMF744.conf
|   |-- aliases.conf
|   |-- pistachio-card.conf
|   `-- vc4-hdmi.conf
|-- init
|   |-- 00main
|   |-- ca0106
|   |-- default
|   |-- ens1371
|   |-- hda
|   |-- help
|   |-- info
|   |-- rk809
|   |-- rt5616
|   |-- rt5640
|   |-- rt5651
|   `-- test
|-- pcm
|   |-- center_lfe.conf
|   |-- default.conf
|   |-- dmix.conf
|   |-- dpl.conf
|   |-- dsnoop.conf
|   |-- front.conf
|   |-- hdmi.conf
|   |-- iec958.conf
|   |-- modem.conf
|   |-- rear.conf
|   |-- side.conf
|   |-- surround21.conf
|   |-- surround40.conf
|   |-- surround41.conf
|   |-- surround50.conf
|   |-- surround51.conf
|   `-- surround71.conf
|-- pulse-alsa.conf
|-- speaker-test
|   `-- sample_map.csv
|-- topology
|   |-- broadwell
|   |   `-- broadwell.conf
|   |-- bxtrt298
|   |   `-- bxt_i2s.conf
|   `-- sklrt286
|       `-- skl_i2s.conf
|-- ucm
|   |-- README.md
|   |-- realtek,rt5651-codec
|   |   |-- HiFi.conf
|   |   `-- realtek,rt5651-codec.conf
|   |-- rockchip,rk809-codec
|   |   |-- HiFi.conf
|   |   `-- rockchip,rk809-codec.conf
|   |-- rockchip,rt5616-codec
|   |   |-- HiFi
|   |   `-- rockchip,rt5616-codec.conf
|   `-- rockchip,rt5640-codec
|       |-- HiFi.conf
|       `-- rockchip,rt5640-codec.conf
|-- ucm2
|   |-- DAISY-I2S
|   |   |-- DAISY-I2S.conf
|   |   `-- HiFi.conf
|   |-- DB410c
|   |   |-- DB410c.conf
|   |   |-- HDMI.conf
|   |   `-- HiFi.conf
|   |-- DB820c
|   |   |-- DB820c.conf
|   |   |-- HDMI.conf
|   |   `-- HiFi.conf
|   |-- GoogleNyan
|   |   |-- GoogleNyan.conf
|   |   `-- HiFi.conf
|   |-- HDA
|   |   |-- DualCodecs
|   |   |   |-- DualCodecs.conf
|   |   |   `-- HiFi.conf
|   |   |-- HDA-Capture-value.conf
|   |   |-- HDA.conf
|   |   |-- Hdmi.conf
|   |   |-- HiFi-acp.conf
|   |   |-- HiFi-analog.conf
|   |   |-- HiFi.conf
|   |   `-- init.conf
|   |-- HDA-Intel
|   |   |-- HDA-Capture-value.conf
|   |   |-- HDA-Intel.conf
|   |   |-- HDAudio-DualCodecs.conf
|   |   |-- HDAudio-Gigabyte-ALC1220DualCodecs.conf -> HDAudio-DualCodecs.conf
|   |   |-- HDAudio-Lenovo-DualCodecs.conf -> HDAudio-DualCodecs.conf
|   |   |-- Hdmi.conf
|   |   |-- HiFi-acp.conf
|   |   |-- HiFi-analog.conf
|   |   |-- HiFi-dual.conf
|   |   |-- HiFi.conf
|   |   `-- init.conf
|   |-- Intel
|   |   |-- SOF
|   |   |   |-- HiFi.conf
|   |   |   `-- SOF.conf
|   |   |-- bdw-rt5677
|   |   |   |-- HiFi.conf
|   |   |   `-- bdw-rt5677.conf
|   |   |-- broadwell-rt286
|   |   |   |-- HiFi.conf
|   |   |   `-- broadwell-rt286.conf
|   |   |-- broxton-rt298
|   |   |   |-- Hdmi.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- broxton-rt298.conf
|   |   |-- bytcht-cx2072x
|   |   |   |-- HiFi.conf
|   |   |   `-- bytcht-cx2072x.conf
|   |   |-- bytcht-es8316
|   |   |   |-- HiFi-Components.conf
|   |   |   |-- HiFi-LongName.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- bytcht-es8316.conf
|   |   |-- bytcr-rt5640
|   |   |   |-- HiFi-Components.conf
|   |   |   |-- HiFi-LongName.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- bytcr-rt5640.conf
|   |   |-- bytcr-rt5651
|   |   |   |-- HiFi-Components.conf
|   |   |   |-- HiFi-LongName.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- bytcr-rt5651.conf
|   |   |-- bytcr-wm5102
|   |   |   |-- HiFi.conf
|   |   |   `-- bytcr-wm5102.conf
|   |   |-- cht-bsw-rt5672
|   |   |   |-- HiFi.conf
|   |   |   `-- cht-bsw-rt5672.conf
|   |   |-- chtmax98090
|   |   |   |-- HiFi.conf
|   |   |   `-- chtmax98090.conf
|   |   |-- chtnau8824
|   |   |   |-- HiFi.conf
|   |   |   `-- chtnau8824.conf
|   |   |-- chtrt5645
|   |   |   |-- HiFi.conf
|   |   |   `-- chtrt5645.conf
|   |   |-- chtrt5650
|   |   |   |-- HiFi.conf
|   |   |   `-- chtrt5650.conf
|   |   |-- hda-dsp
|   |   |   |-- Hdmi1.conf
|   |   |   |-- Hdmi2.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- hda-dsp.conf
|   |   |-- kblrt5660
|   |   |   |-- Hdmi1.conf
|   |   |   |-- Hdmi2.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- kblrt5660.conf
|   |   |-- skylake-rt286
|   |   |   |-- Hdmi1.conf
|   |   |   |-- Hdmi2.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- skylake-rt286.conf
|   |   |-- sof-ehl-rt5660
|   |   |   |-- Hdmi.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- sof-ehl-rt5660.conf
|   |   `-- sof-hda-dsp
|   |       |-- Hdmi.conf
|   |       |-- HiFi.conf
|   |       `-- sof-hda-dsp.conf
|   |-- Librem_5
|   |   |-- HiFi.conf
|   |   |-- Librem_5.conf
|   |   `-- wm8962.conf -> Librem_5.conf
|   |-- MediaTek
|   |   |-- mt8365-evk
|   |   |   |-- HiFi.conf
|   |   |   `-- mt8365-evk.conf
|   |   |-- mt8390-evk
|   |   |   |-- HiFi.conf
|   |   |   `-- mt8390-evk.conf
|   |   |-- mt8395-evk
|   |   |   |-- HiFi.conf
|   |   |   `-- mt8395-evk.conf
|   |   `-- mtk-rt5650
|   |       |-- HDMI.conf
|   |       |-- HiFi.conf
|   |       |-- init.conf
|   |       `-- mtk-rt5650.conf
|   |-- NXP
|   |   `-- iMX8
|   |       `-- Librem_5_Devkit
|   |           |-- HiFi.conf
|   |           `-- Librem\ 5\ Devkit.conf
|   |-- OMAP
|   |   `-- abe-twl6040
|   |       |-- Pandaboard
|   |       |   |-- FMAnalog.conf
|   |       |   |-- HiFi.conf
|   |       |   |-- HiFiLP.conf
|   |       |   |-- Pandaboard.conf
|   |       |   |-- Record.conf
|   |       |   |-- Voice.conf
|   |       |   `-- VoiceCall.conf
|   |       |-- SDP4430
|   |       |   |-- FMAnalog.conf
|   |       |   |-- HiFi.conf
|   |       |   |-- HiFiLP.conf
|   |       |   |-- Record.conf
|   |       |   |-- SDP4430.conf
|   |       |   |-- Voice.conf
|   |       |   `-- VoiceCall.conf
|   |       `-- abe-twl6040.conf
|   |-- PAZ00
|   |   |-- HiFi.conf
|   |   |-- PAZ00.conf
|   |   `-- Record.conf
|   |-- PandaBoard
|   |   |-- FMAnalog.conf
|   |   |-- HiFi.conf
|   |   |-- HiFiLP.conf
|   |   |-- PandaBoard.conf
|   |   |-- Record.conf
|   |   |-- Voice.conf
|   |   `-- VoiceCall.conf
|   |-- PandaBoardES
|   |   |-- FMAnalog.conf
|   |   |-- HiFi.conf
|   |   |-- HiFiLP.conf
|   |   |-- PandaBoardES.conf
|   |   |-- Record.conf
|   |   |-- Voice.conf
|   |   `-- VoiceCall.conf
|   |-- PinePhone
|   |   |-- HiFi.conf
|   |   |-- PinePhone.conf
|   |   `-- VoiceCall.conf
|   |-- PineTab
|   |   |-- HiFi.conf
|   |   `-- PineTab.conf
|   |-- Qualcomm
|   |   |-- apq8016-sbc
|   |   |   |-- HDMI.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- apq8016-sbc.conf
|   |   |-- apq8096
|   |   |   |-- HDMI.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- apq8096.conf
|   |   |-- sc7180
|   |   |   `-- rt5682-max98357a
|   |   |       |-- HiFi.conf
|   |   |       |-- init.conf
|   |   |       `-- sc7180-rt5682-max98357a-1mic.conf
|   |   |-- sdm845
|   |   |   |-- HDMI.conf
|   |   |   |-- HiFi.conf
|   |   |   `-- sdm845.conf
|   |   `-- sm8250
|   |       |-- HDMI.conf
|   |       |-- HiFi.conf
|   |       `-- Qualcomm-RB5-WSA8815-Speakers-DMIC0.conf
|   |-- README.md
|   |-- Rockchip
|   |   |-- es8316
|   |   |   |-- HiFi.conf
|   |   |   `-- es8316.conf
|   |   |-- max98090
|   |   |   |-- HiFi.conf
|   |   |   `-- max98090.conf
|   |   `-- rk3399-gru-sound
|   |       |-- HiFi.conf
|   |       `-- rk3399-gru-sound.conf
|   |-- SDP4430
|   |   |-- FMAnalog.conf
|   |   |-- HiFi.conf
|   |   |-- HiFiLP.conf
|   |   |-- Record.conf
|   |   |-- SDP4430.conf
|   |   |-- Voice.conf
|   |   `-- VoiceCall.conf
|   |-- Samsung
|   |   `-- snow
|   |       |-- HiFi.conf
|   |       `-- snow.conf
|   |-- Tegra
|   |   |-- alc5632
|   |   |   |-- HiFi.conf
|   |   |   |-- Record.conf
|   |   |   `-- alc5632.conf
|   |   |-- max98090
|   |   |   |-- HiFi.conf
|   |   |   `-- max98090.conf
|   |   |-- rt5640
|   |   |   |-- Google-Nexus-7-HiFi.conf
|   |   |   `-- Google-Nexus-7.conf
|   |   |-- tegra-hda
|   |   |   |-- tegra-hda-HiFi.conf
|   |   |   `-- tegra-hda.conf
|   |   `-- wm8903
|   |       |-- Acer-A500-HiFi.conf
|   |       `-- Acer-A500.conf
|   |-- USB-Audio
|   |   |-- Dell
|   |   |   |-- Desktop-Front-Speaker-Headset.conf
|   |   |   |-- Desktop-Front.conf
|   |   |   |-- Desktop-Rear-Line.conf
|   |   |   |-- Desktop-Rear.conf
|   |   |   |-- WD15-Dock-HiFi.conf
|   |   |   `-- WD15-Dock.conf
|   |   |-- Dell-Desktop-Front-Headset.conf
|   |   |-- Dell-Desktop-Front-Speaker.conf
|   |   |-- Dell-Desktop-Front.conf
|   |   |-- Dell-Desktop-Rear-Line.conf
|   |   |-- Dell-Desktop-Rear.conf
|   |   |-- Dell-WD15-Dock-HiFi.conf
|   |   |-- Dell-WD15-Dock.conf
|   |   |-- Gigabyte
|   |   |   |-- Aorus-Master-Main-Audio-HiFi.conf
|   |   |   `-- Aorus-Master-Main-Audio.conf
|   |   |-- GoXLR
|   |   |   |-- GoXLR-HiFi.conf
|   |   |   `-- GoXLR.conf
|   |   |-- Lenovo
|   |   |   |-- ThinkStation-P620-Main-HiFi.conf
|   |   |   |-- ThinkStation-P620-Main.conf
|   |   |   |-- ThinkStation-P620-Rear-HiFi.conf
|   |   |   `-- ThinkStation-P620-Rear.conf
|   |   |-- Lenovo-ThinkStation-P620-Main-HiFi.conf
|   |   |-- Lenovo-ThinkStation-P620-Main.conf
|   |   |-- Lenovo-ThinkStation-P620-Rear-HiFi.conf
|   |   |-- Lenovo-ThinkStation-P620-Rear.conf
|   |   |-- Realtek
|   |   |   |-- ALC1220-VB-Desktop-HiFi.conf
|   |   |   `-- ALC1220-VB-Desktop.conf
|   |   `-- USB-Audio.conf
|   |-- VEYRON-I2S
|   |   |-- HiFi.conf
|   |   `-- VEYRON-I2S.conf
|   |-- broadwell-rt286
|   |   |-- HiFi.conf
|   |   `-- broadwell-rt286.conf
|   |-- broxton-rt298
|   |   |-- Hdmi.conf
|   |   |-- HiFi.conf
|   |   `-- broxton-rt298.conf
|   |-- bytcht-cx2072x
|   |   |-- HiFi.conf
|   |   `-- bytcht-cx2072x.conf
|   |-- bytcht-es8316
|   |   |-- HiFi-Components.conf
|   |   |-- HiFi-LongName.conf
|   |   |-- HiFi.conf
|   |   `-- bytcht-es8316.conf
|   |-- bytcr-rt5640
|   |   |-- HiFi-Components.conf
|   |   |-- HiFi-LongName.conf
|   |   |-- HiFi.conf
|   |   `-- bytcr-rt5640.conf
|   |-- bytcr-rt5651
|   |   |-- HiFi-Components.conf
|   |   |-- HiFi-LongName.conf
|   |   |-- HiFi.conf
|   |   `-- bytcr-rt5651.conf
|   |-- cht-bsw-rt5672
|   |   |-- HiFi-stereo-dmic2.conf
|   |   |-- HiFi.conf
|   |   |-- LENOVO-20BN002QGE-ThinkPad8-20BN002QGE.conf -> cht-bsw-rt5672-stereo-dmic2.conf
|   |   |-- LENOVO-20BN002QGE-ThinkPad8.conf -> cht-bsw-rt5672-stereo-dmic2.conf
|   |   |-- cht-bsw-rt5672-stereo-dmic2.conf
|   |   `-- cht-bsw-rt5672.conf
|   |-- chtnau8824
|   |   |-- HiFi-mono.conf
|   |   |-- HiFi.conf
|   |   |-- PIPO-W2S-Defaultstring-CherryTrailCR.conf -> chtnau8824-mono.conf
|   |   |-- chtnau8824-mono.conf
|   |   |-- chtnau8824.conf
|   |   `-- cube-i1_TF-Defaultstring-CherryTrailCR.conf -> chtnau8824-mono.conf
|   |-- chtrt5645
|   |   |-- ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN.conf -> chtrt5645-dmic1.conf
|   |   |-- HiFi-dmic1.conf
|   |   |-- HiFi-dmic2.conf
|   |   |-- HiFi-mono-speaker-analog-mic.conf
|   |   |-- HiFi.conf
|   |   |-- LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216.conf -> chtrt5645-dmic2.conf
|   |   |-- TECLAST-X80Pro-Defaultstring-CherryTrailCR.conf -> chtrt5645-mono-speaker-analog-mic.conf
|   |   |-- chtrt5645-dmic1.conf
|   |   |-- chtrt5645-dmic2.conf
|   |   |-- chtrt5645-mono-speaker-analog-mic.conf
|   |   |-- chtrt5645.conf
|   |   `-- gpd-win-pocket-rt5645.conf -> chtrt5645-mono-speaker-analog-mic.conf
|   |-- chtrt5650
|   |   |-- HiFi.conf
|   |   `-- chtrt5650.conf
|   |-- codecs
|   |   |-- cx2072x
|   |   |   |-- DisableSeq.conf
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HeadPhones.conf
|   |   |   |-- HeadsetMic.conf
|   |   |   |-- InternalMic.conf
|   |   |   `-- Speaker.conf
|   |   |-- es8316
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HeadPhones.conf
|   |   |   |-- IN1-HeadsetMic.conf
|   |   |   |-- IN1-InternalMic.conf
|   |   |   |-- IN2-HeadsetMic.conf
|   |   |   |-- IN2-InternalMic.conf
|   |   |   |-- MonoSpeaker.conf
|   |   |   `-- Speaker.conf
|   |   |-- hda
|   |   |   `-- hdmi.conf
|   |   |-- max98090
|   |   |   |-- EnableSeq.conf
|   |   |   |-- Headphones.conf
|   |   |   |-- HeadsetMic.conf
|   |   |   |-- InternalMic.conf
|   |   |   `-- Speaker.conf
|   |   |-- nau8824
|   |   |   |-- DMIC1_2.conf
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HeadPhones.conf
|   |   |   |-- HeadsetMic.conf
|   |   |   |-- InternalMic.conf
|   |   |   |-- MonoSpeaker.conf
|   |   |   `-- Speaker.conf
|   |   |-- qcom-lpass
|   |   |   |-- va-macro
|   |   |   |   |-- DMIC0DisableSeq.conf
|   |   |   |   `-- DMIC0EnableSeq.conf
|   |   |   `-- wsa-macro
|   |   |       |-- SpeakerDisableSeq.conf
|   |   |       `-- SpeakerEnableSeq.conf
|   |   |-- rt5640
|   |   |   |-- DigitalMics.conf
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HeadPhones.conf
|   |   |   |-- HeadPhones2.conf
|   |   |   |-- HeadsetMic.conf
|   |   |   |-- HeadsetMic2-IN1.conf
|   |   |   |-- IN1-InternalMic.conf
|   |   |   |-- IN3-InternalMic.conf
|   |   |   |-- MonoSpeaker.conf
|   |   |   |-- Speaker.conf
|   |   |   `-- init.conf
|   |   |-- rt5645
|   |   |   |-- AnalogMic.conf
|   |   |   |-- DigitalMicDisableSeq.conf
|   |   |   |-- DigitalMicEnableSeq.conf
|   |   |   |-- DisableSeq.conf
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HSMicDisableSeq.conf
|   |   |   |-- HSMicEnableSeq.conf
|   |   |   |-- HeadphonesEnableSeq.conf
|   |   |   |-- SpeakerEnableSeq.conf
|   |   |   `-- init.conf
|   |   |-- rt5651
|   |   |   |-- DigitalMic.conf
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HeadPhones-swapped.conf
|   |   |   |-- HeadPhones.conf
|   |   |   |-- IN1-InternalMic.conf
|   |   |   |-- IN12-InternalMic.conf
|   |   |   |-- IN2-HeadsetMic.conf
|   |   |   |-- IN2-InternalMic.conf
|   |   |   |-- IN3-HeadsetMic.conf
|   |   |   |-- MonoSpeaker.conf
|   |   |   |-- Speaker.conf
|   |   |   `-- init.conf
|   |   |-- rt5672
|   |   |   |-- DMIC1.conf
|   |   |   |-- DMIC2.conf
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HeadPhones.conf
|   |   |   |-- HeadsetMic.conf
|   |   |   |-- MonoSpeaker.conf
|   |   |   `-- Speaker.conf
|   |   |-- rt5682
|   |   |   `-- init.conf
|   |   |-- rt700
|   |   |   `-- init.conf
|   |   |-- rt711
|   |   |   `-- init.conf
|   |   |-- rt711-sdca
|   |   |   `-- init.conf
|   |   |-- rt713-dmic
|   |   |   `-- init.conf
|   |   |-- rt713-sdca
|   |   |   `-- init.conf
|   |   |-- rt715
|   |   |   `-- init.conf
|   |   |-- rt715-sdca
|   |   |   `-- init.conf
|   |   |-- wcd934x
|   |   |   |-- DefaultDisableSeq.conf
|   |   |   |-- DefaultEnableSeq.conf
|   |   |   |-- HeadphoneDisableSeq.conf
|   |   |   |-- HeadphoneEnableSeq.conf
|   |   |   |-- HeadphoneMicDisableSeq.conf
|   |   |   |-- HeadphoneMicEnableSeq.conf
|   |   |   |-- SpeakerDisableSeq.conf
|   |   |   `-- SpeakerEnableSeq.conf
|   |   |-- wm5102
|   |   |   |-- EnableSeq.conf
|   |   |   |-- HeadPhones.conf
|   |   |   |-- IN1-HeadsetMic.conf
|   |   |   |-- IN3-InternalMic.conf
|   |   |   `-- Speaker.conf
|   |   `-- wsa881x
|   |       |-- DefaultEnableSeq.conf
|   |       |-- SpeakerDisableSeq.conf
|   |       `-- SpeakerEnableSeq.conf
|   |-- common
|   |   |-- linked-card.conf
|   |   `-- linked.conf
|   |-- conf.d
|   |   |-- DB410c
|   |   |   `-- DB410c.conf -> ../../Qualcomm/apq8016-sbc/apq8016-sbc.conf
|   |   |-- DB820c
|   |   |   `-- DB820c.conf -> ../../Qualcomm/apq8096/apq8096.conf
|   |   |-- HDA-Intel
|   |   |   `-- HDA-Intel.conf -> ../../HDA/HDA.conf
|   |   |-- SC7180
|   |   |   `-- sc7180-rt5682-max98357a-1mic.conf -> ../../Qualcomm/sc7180/rt5682-max98357a/sc7180-rt5682-max98357a-1mic.conf
|   |   |-- SOF
|   |   |   `-- SOF.conf -> ../../Intel/SOF/SOF.conf
|   |   |-- USB-Audio
|   |   |   `-- USB-Audio.conf -> ../../USB-Audio/USB-Audio.conf
|   |   |-- acp
|   |   |   `-- acp.conf -> ../../common/linked-card.conf
|   |   |-- acp62
|   |   |   `-- acp62.conf -> ../../common/linked-card.conf
|   |   |-- acp63
|   |   |   `-- acp63.conf -> ../../common/linked-card.conf
|   |   |-- acp6x
|   |   |   `-- acp6x.conf -> ../../common/linked-card.conf
|   |   |-- bdw-rt5677
|   |   |   `-- bdw-rt5677.conf -> ../../Intel/bdw-rt5677/bdw-rt5677.conf
|   |   |-- broadwell-rt286
|   |   |   `-- broadwell-rt286.conf -> ../../Intel/broadwell-rt286/broadwell-rt286.conf
|   |   |-- broxton-rt298
|   |   |   `-- broxton-rt298.conf -> ../../Intel/broxton-rt298/broxton-rt298.conf
|   |   |-- bytcht-cx2072x
|   |   |   `-- bytcht-cx2072x.conf -> ../../Intel/bytcht-cx2072x/bytcht-cx2072x.conf
|   |   |-- bytcht-es8316
|   |   |   `-- bytcht-es8316.conf -> ../../Intel/bytcht-es8316/bytcht-es8316.conf
|   |   |-- bytcr-rt5640
|   |   |   `-- bytcr-rt5640.conf -> ../../Intel/bytcr-rt5640/bytcr-rt5640.conf
|   |   |-- bytcr-rt5651
|   |   |   `-- bytcr-rt5651.conf -> ../../Intel/bytcr-rt5651/bytcr-rt5651.conf
|   |   |-- bytcr-wm5102
|   |   |   `-- bytcr-wm5102.conf -> ../../Intel/bytcr-wm5102/bytcr-wm5102.conf
|   |   |-- cht-bsw-rt5672
|   |   |   `-- cht-bsw-rt5672.conf -> ../../Intel/cht-bsw-rt5672/cht-bsw-rt5672.conf
|   |   |-- chtmax98090
|   |   |   `-- chtmax98090.conf -> ../../Intel/chtmax98090/chtmax98090.conf
|   |   |-- chtnau8824
|   |   |   `-- chtnau8824.conf -> ../../Intel/chtnau8824/chtnau8824.conf
|   |   |-- chtrt5645
|   |   |   `-- chtrt5645.conf -> ../../Intel/chtrt5645/chtrt5645.conf
|   |   |-- chtrt5650
|   |   |   `-- chtrt5650.conf -> ../../Intel/chtrt5650/chtrt5650.conf
|   |   |-- hda-dsp
|   |   |   `-- hda-dsp.conf -> ../../Intel/hda-dsp/hda-dsp.conf
|   |   |-- kblrt5660
|   |   |   `-- kblrt5660.conf -> ../../Intel/kblrt5660/kblrt5660.conf
|   |   |-- mt8365-evk
|   |   |   `-- mt8365-evk.conf -> ../../MediaTek/mt8365-evk/mt8365-evk.conf
|   |   |-- mt8390-evk
|   |   |   `-- mt8390-evk.conf -> ../../MediaTek/mt8390-evk/mt8390-evk.conf
|   |   |-- mt8395-evk
|   |   |   `-- mt8395-evk.conf -> ../../MediaTek/mt8395-evk/mt8395-evk.conf
|   |   |-- mtk-rt5650
|   |   |   `-- mtk-rt5650.conf -> ../../MediaTek/mtk-rt5650/mtk-rt5650.conf
|   |   |-- rockchip_es8316
|   |   |   `-- rockchip_es8316.conf -> ../../Rockchip/es8316/es8316.conf
|   |   |-- sdm845
|   |   |   `-- DB845c.conf -> ../../Qualcomm/sdm845/sdm845.conf
|   |   |-- simple-card
|   |   |   `-- Librem\ 5\ Devkit.conf -> ../../NXP/iMX8/Librem_5_Devkit/Librem\ 5\ Devkit.conf
|   |   |-- skylake-rt286
|   |   |   `-- skylake-rt286.conf -> ../../Intel/skylake-rt286/skylake-rt286.conf
|   |   |-- sm8250
|   |   |   `-- Qualcomm-RB5-WSA8815-Speakers-DMIC0.conf -> ../../Qualcomm/sm8250/Qualcomm-RB5-WSA8815-Speakers-DMIC0.conf
|   |   |-- sof-ehl-rt5660
|   |   |   `-- sof-ehl-rt5660.conf -> ../../Intel/sof-ehl-rt5660/sof-ehl-rt5660.conf
|   |   |-- sof-hda-dsp
|   |   |   |-- sof-hda-dsp.conf -> ../../Intel/sof-hda-dsp/sof-hda-dsp.conf
|   |   |   `-- sof-skl_hda_card.conf -> ../../Intel/sof-hda-dsp/sof-hda-dsp.conf
|   |   |-- sof-skl_hda_card -> sof-hda-dsp
|   |   |-- sof-soundwire
|   |   |   `-- sof-soundwire.conf -> ../../sof-soundwire/sof-soundwire.conf
|   |   |-- tegra
|   |   |   |-- ASUS\ Google\ Nexus\ 7\ ALC5642.conf -> ../../Tegra/rt5640/Google-Nexus-7.conf
|   |   |   |-- Acer\ Iconia\ Tab\ A500\ WM8903.conf -> ../../Tegra/wm8903/Acer-A500.conf
|   |   |   |-- Compal\ PAZ00.conf -> ../../Tegra/alc5632/alc5632.conf
|   |   |   |-- GoogleNyanBig.conf -> ../../Tegra/max98090/max98090.conf
|   |   |   `-- GoogleNyanBlaze.conf -> ../../Tegra/max98090/max98090.conf
|   |   `-- tegra-hda
|   |       `-- tegra-hda.conf -> ../../Tegra/tegra-hda/tegra-hda.conf
|   |-- conf.virt.d
|   |-- kblrt5660
|   |   |-- Hdmi1.conf
|   |   |-- Hdmi2.conf
|   |   |-- HiFi.conf
|   |   `-- kblrt5660.conf
|   |-- lib
|   |   |-- card-init.conf
|   |   |-- ctl-remap.conf
|   |   `-- generic.conf
|   |-- module
|   |   |-- acp_pdm_mach.conf
|   |   |-- lib
|   |   |   `-- linked.conf
|   |   |-- snd_acp3x_rn.conf -> lib/linked.conf
|   |   |-- snd_soc_apq8016_sbc.conf -> ../Qualcomm/apq8016-sbc/apq8016-sbc.conf
|   |   |-- snd_soc_apq8096.conf -> ../Qualcomm/apq8096/apq8096.conf
|   |   |-- snd_soc_omap_abe_twl6040.conf -> ../OMAP/abe-twl6040/abe-twl6040.conf
|   |   |-- snd_soc_rk3399_gru_sound.conf -> ../Rockchip/rk3399-gru-sound/rk3399-gru-sound.conf
|   |   |-- snd_soc_rockchip_max98090.conf -> ../Rockchip/max98090/max98090.conf
|   |   |-- snd_soc_sdm845.conf -> ../Qualcomm/sdm845/sdm845.conf
|   |   |-- snd_soc_snow.conf -> ../Samsung/snow/snow.conf
|   |   |-- snd_soc_tegra_alc5632.conf -> ../Tegra/alc5632/alc5632.conf
|   |   `-- snd_soc_tegra_max98090.conf -> ../Tegra/max98090/max98090.conf
|   |-- platforms
|   |   `-- bytcr
|   |       |-- PlatformDisableSeq.conf
|   |       `-- PlatformEnableSeq.conf
|   |-- rockchip-es8326
|   |   |-- HiFi.conf
|   |   `-- rockchip-es8326.conf
|   |-- rockchip-es8388
|   |   |-- HiFi.conf
|   |   `-- rockchip-es8388.conf
|   |-- rockchip-hdmi0
|   |   |-- Hdmi.conf
|   |   `-- rockchip-hdmi0.conf
|   |-- rockchip-hdmi1
|   |   |-- Hdmi.conf
|   |   `-- rockchip-hdmi1.conf
|   |-- skylake-rt286
|   |   |-- Hdmi1.conf
|   |   |-- Hdmi2.conf
|   |   |-- HiFi.conf
|   |   `-- skylake-rt286.conf
|   |-- sof-hda-dsp
|   |   |-- HDA-Capture-value.conf
|   |   |-- Hdmi.conf
|   |   |-- HiFi.conf
|   |   `-- sof-hda-dsp.conf
|   |-- sof-soundwire
|   |   |-- Hdmi.conf
|   |   |-- HiFi.conf
|   |   |-- dmic.conf
|   |   |-- rt1308-1.conf
|   |   |-- rt1308-2.conf
|   |   |-- rt1316-1.conf
|   |   |-- rt1316-2.conf
|   |   |-- rt1318-1.conf
|   |   |-- rt1318-2.conf
|   |   |-- rt5682.conf
|   |   |-- rt700.conf
|   |   |-- rt711-sdca.conf
|   |   |-- rt711.conf
|   |   |-- rt713-dmic.conf
|   |   |-- rt713-sdca.conf
|   |   |-- rt715-sdca.conf
|   |   |-- rt715.conf
|   |   `-- sof-soundwire.conf
|   |-- tegraalc5632
|   |   `-- tegraalc5632.conf
|   |-- ucm.conf
|   `-- wm8962 -> Librem_5
`-- utils.sh

对于pipewire后台进程来讲,它并不是通过读取ALSA获取硬件的属性信息的,而是通过读取/usr/share/pipewire/目录下的配置文件获取硬件信息。

下面列举出了幽兰代码本上pipewire中的配置文件信息。

/usr/share/pipewire/
|-- client-rt.conf
|-- client.conf
|-- jack.conf
|-- minimal.conf
|-- pipewire-avb.conf
|-- pipewire-pulse.conf
|-- pipewire.conf
`-- with-alsa

对于硬件信息可以通过pw-link进行获取,下面通过-i-o参数,列出了幽兰代码本上全部的输入输出设备。

pw-link -i
alsa_output.platform-es8326-sound.stereo-fallback:playback_FL
alsa_output.platform-es8326-sound.stereo-fallback:playback_FR
alsa_output.platform-hdmi0-sound.stereo-fallback:playback_FL
alsa_output.platform-hdmi0-sound.stereo-fallback:playback_FR

pw-link -o
alsa_input.platform-es8326-sound.stereo-fallback:capture_FL
alsa_input.platform-es8326-sound.stereo-fallback:capture_FR
alsa_output.platform-es8326-sound.stereo-fallback:monitor_FL
alsa_output.platform-es8326-sound.stereo-fallback:monitor_FR
alsa_output.platform-hdmi0-sound.stereo-fallback:monitor_FL
alsa_output.platform-hdmi0-sound.stereo-fallback:monitor_FR
v4l2_input.platform-fc800000.usb-usb-0_1_1.0:out_0

与应用程序交互

播放音频的应用程序通过pipewire后台服务创建的pipewire-0或pipewire-pulse创建的native接口进行通信。

/run/user/1000/
|-- ICEauthority
|-- at-spi
|   `-- bus
|-- bus
|-- dbus-1
|   `-- services
|-- dconf
|   `-- user
|-- doc
|   `-- by-app
|-- gcr
|   `-- ssh
|-- gnome-session-leader-fifo
|-- gnome-shell
|   `-- runtime-state-LE.
|-- gnupg
|   |-- S.dirmngr
|   |-- S.gpg-agent
|   |-- S.gpg-agent.browser
|   |-- S.gpg-agent.extra
|   `-- S.gpg-agent.ssh
|-- gvfs
|-- gvfsd
|-- keyring
|   |-- control
|   |-- pkcs11
|   `-- ssh
|-- openssh_agent
|-- pipewire-0
|-- pipewire-0.lock
|-- pk-debconf-socket
|-- pulse
|   |-- native
|   `-- pid
......

WayDroid的问题

WayDroid中的音频模块并没有使用PipWire或PulseAudio,而是使用了audio.service作为后台服务,作为应用程序的接口。

通过查看audio.serive的maps文件可以看到,audio.service使用ALSA的模块。

f60a7000-f60a9000 r--p 00000000 07:01 3464                               /system/lib/libtinyalsa.so
f60a9000-f60ac000 r-xp 00001000 07:01 3464                               /system/lib/libtinyalsa.so
f60ac000-f60ae000 r--p 00003000 07:01 3464                               /system/lib/libtinyalsa.so
f60ae000-f60af000 rw-p 00004000 07:01 3464                               /system/lib/libtinyalsa.so
f60e2000-f60e4000 r--p 00000000 07:02 421                                /vendor/lib/libalsautils.so
f60e4000-f60e6000 r-xp 00001000 07:02 421                                /vendor/lib/libalsautils.so
f60e6000-f60e8000 r--p 00002000 07:02 421                                /vendor/lib/libalsautils.so

顺着这个线索不难发现,在Waydroid的文件系统中存在/run/user/1000/pulse/native文件和/vendor/usr/share/alsa/两个目录。

通过pw-top工具,可以看到与PipeWire传输音频流的应用程序、PipeWire使用的硬件设备及音频流的属性信息等情况。

当WayDroid系统播放视频时,虽然pw-top正常列举了幽兰代码本上的硬件设备信息,但是却并没有看到WayDroid与PipeWire进行音频流的传输信息。

这说明WayDriod没有和PipeWire完成对接,导致音频无法播放。

S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME
S   28      0      0    ---     ---   ---   ---     0                  Dummy-Driver
S   29      0      0    ---     ---   ---   ---     0                  Freewheel-Driver
S   30      0      0    ---     ---   ---   ---     0                  alsa_input.platform-es8326-sound.stereo-fallback
S   31      0      0    ---     ---   ---   ---     0                  alsa_output.platform-es8326-sound.stereo-fallback
S   32      0      0    ---     ---   ---   ---     0                  alsa_output.platform-hdmi0-sound.stereo-fallback
S   41      0      0    ---     ---   ---   ---     0                  v4l2_input.platform-fc800000.usb-usb-0_1_1.0

考虑到硬件设备枚举的任务已经由幽兰本机中的WirePlumber完成了,所以WayDroid中audio.service主要作用就应该是与WayDroid中的视频媒体播放程序对接,然后将音频流发送给pipewire-pulse后台程序。

对于PulseAudio来讲,他需要通过脉冲编码调制 (PCM)技术获取数字格式的音频流信号后再继续播放。

通过查看WarDroid上的/usr/share/alsa目录情况可以指定,在这些配置文件中缺少真的PCM的相关配置,因此需要将这一块缺陷补齐。

alsa.confdefaults.pcm.device 0
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
defaults.pcm.compat 0
defaults.pcm.minperiodtime 5000         # in us
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
defaults.pcm.tstamp_type default
defaults.pcm.dmix.max_periods 0
defaults.pcm.dmix.channels 2
defaults.pcm.dmix.rate 48000
defaults.pcm.dmix.format unchanged
defaults.pcm.dmix.card defaults.pcm.card
defaults.pcm.dmix.device defaults.pcm.device
defaults.pcm.dsnoop.card defaults.pcm.card
defaults.pcm.dsnoop.device defaults.pcm.device
defaults.pcm.front.card defaults.pcm.card
defaults.pcm.front.device defaults.pcm.device
defaults.pcm.rear.card defaults.pcm.card
defaults.pcm.rear.device defaults.pcm.device
defaults.pcm.center_lfe.card defaults.pcm.card
defaults.pcm.center_lfe.device defaults.pcm.device
defaults.pcm.side.card defaults.pcm.card
defaults.pcm.side.device defaults.pcm.device
defaults.pcm.surround21.card defaults.pcm.card
defaults.pcm.surround21.device defaults.pcm.device
defaults.pcm.surround40.card defaults.pcm.card
defaults.pcm.surround40.device defaults.pcm.device
defaults.pcm.surround41.card defaults.pcm.card
defaults.pcm.surround41.device defaults.pcm.device
defaults.pcm.surround50.card defaults.pcm.card
defaults.pcm.surround50.device defaults.pcm.device
defaults.pcm.surround51.card defaults.pcm.card
defaults.pcm.surround51.device defaults.pcm.device
defaults.pcm.surround71.card defaults.pcm.card
defaults.pcm.surround71.device defaults.pcm.device
defaults.pcm.iec958.card defaults.pcm.card
defaults.pcm.iec958.device defaults.pcm.device
defaults.pcm.modem.card defaults.pcm.card
defaults.pcm.modem.device defaults.pcm.device
defaults.pcm.file_format raw
defaults.pcm.file_truncate true

在alsa目录下添加PCM的定义之后,再将Linux下PCM相关的配置文件复制过去后,就可以让WayDroid正常的播放音频了。

问题解决步骤

如果在幽兰代码本中遇到了WayDroid声音无法播放是情况,可以参照下方的步骤进行更新。

更新文件获取

通过下方的链接下载文件,并将其解压放到幽兰代码本上。

https://gedu.oss-cn-beijing.aliyuncs.com/Products/YourLand/Release/Patches/Waydroid/alsa/alsa4waydroid.tar.gz

WayDroid权限设置

/usr/lib/waydroid/tools/helpers/mount.py文件内中def mount函数内的opt_args.append("ro")改成opt_args.append("rw"),使得Waydroid的文件系统具有可修改权限。

def mount(args, source, destination, create_folders=True, umount=False,
          readonly=True, mount_type=None, options=None, force=True):
    """
    Mount and create necessary directory structure.
    :param umount: when destination is already a mount point, umount it first.
    :param force: attempt mounting even if the mount point already exists.
    """
    # Check/umount destination
    if ismount(destination):
        if umount:
            umount_all(args, destination)
        else:
            if not force:
                return

    # Check/create folders
    if not os.path.exists(destination):
        if create_folders:
            tools.helpers.run.user(args, ["mkdir", "-p", destination])
        else:
            raise RuntimeError("Mount failed, folder does not exist: " +
                            destination)

    extra_args = []
    opt_args = []
    if mount_type:
        extra_args.extend(["-t", mount_type])
    if readonly:
        opt_args.append("rw")
    if options:
        opt_args.extend(options)
    if opt_args:
        extra_args.extend(["-o", ",".join(opt_args)])

    # Actually mount the folder
    tools.helpers.run.user(args, ["mount", *extra_args, source, destination])

    # Verify, that it has worked
    if not ismount(destination):
        raise RuntimeError("Mount failed: " + source + " -> " + destination)

更新完文件后,需要重启Waydroid或幽兰,保证Waydroid的文件系统被重新挂载为可修改模式。

更新文件

首先启动Waydoird,使得文件系统加载,然后将前面下载并解压好的文件复制到/var/lib/waydroid/rootfs/vendor/usr/share/目录下,文件名应该为alsa

删除原文件:
sudo rm -rf /var/lib/waydroid/rootfs/vendor/usr/share/alsa/

复制新文件:
cp -r ./alsa4waydroid /var/lib/waydroid/rootfs/vendor/usr/share/alsa

确认新复制文件存在:
ls /var/lib/waydroid/rootfs/vendor/usr/share/
alsa

重启Waydroid

更新好alsa后,需要需要重启Waydroid或幽兰,完成重启之后就通过Waydroid播放音频了。

其他问题

如果更新完成后Waydroid仍没有声音,请检查幽兰本机是否可以正常播放音频,如果不行,请参考下方链接内的文章解决幽兰本机的声音问题。

https://www.nanocode.cn/wiki/docs/youlan/sound-conf

作者:admin  创建时间:2024-03-07 17:37
最后编辑:Zhang Yinkui  更新时间:2024-05-07 11:11