Skip to content

Commit 35cb2b1

Browse files
committed
fix: 优化了音频逻辑
1. 优化了音频初始化配置设置 2. 优化了音频切换端口检查的逻辑 3. 优化了音频音量静音的设置 Log: 音频优化 PMS: BUG-350057 Influence: audio
1 parent a82ad8a commit 35cb2b1

4 files changed

Lines changed: 98 additions & 162 deletions

File tree

audio1/audio.go

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -788,11 +788,10 @@ func (a *Audio) init() error {
788788
}
789789
// 加载module-null-sink,噪音抑制时,将sink-input端口Echo-Cancel Playback引入到null-sink
790790
a.LoadNullSinkModule()
791+
GetConfigKeeper().Load()
791792

792793
// 更新本地数据
793794
a.refresh()
794-
GetConfigKeeper().Load()
795-
796795
logger.Debug("init cards")
797796
a.PropsMu.Lock()
798797
a.setPropCards(a.cards.string())
@@ -813,17 +812,7 @@ func (a *Audio) init() error {
813812
go a.handleStateChanged()
814813
logger.Debug("init done")
815814

816-
if !a.autoSwitchOutputPort() || a.defaultSink != nil {
817-
a.resumeSinkConfig(a.defaultSink)
818-
}
819-
if !a.autoSwitchInputPort() || a.defaultSource != nil {
820-
a.resumeSourceConfig(a.defaultSource)
821-
}
822-
823-
a.moveSinkInputsToSink(nil)
824-
825-
// 蓝牙支持的模式
826-
a.refreshBluetoothOpts()
815+
a.autoSwitchPort()
827816

828817
return nil
829818
}
@@ -1245,8 +1234,13 @@ func (a *Audio) resumeSinkConfig(s *Sink) {
12451234
}
12461235

12471236
logger.Debugf("set %v mute %v", s.Name, GetConfigKeeper().Mute.MuteOutput || !portConfig.Enabled)
1248-
s.setMute(GetConfigKeeper().Mute.MuteOutput || !portConfig.Enabled)
1249-
s.setMono(a.Mono)
1237+
s.setMute(GetConfigKeeper().Mute.MuteOutput || portConfig.Volume == 0)
1238+
// 即将切换通道,就不要设置单声道了,避免触发多次切换
1239+
auto, _, _ := a.checkAutoSwitchOutputPort()
1240+
if !auto {
1241+
s.setMono(a.Mono)
1242+
}
1243+
12501244
}
12511245

12521246
func (a *Audio) resumeSourceConfig(s *Source) {
@@ -1369,9 +1363,7 @@ func (a *Audio) updateDefaultSink(sinkName string) {
13691363
defaultSinkPath := sink.getPath()
13701364
logger.Debugf("set default sink %s", defaultSinkPath)
13711365

1372-
// 虚拟通道不需要恢复配置
1373-
auto, _, _ := a.checkAutoSwitchOutputPort()
1374-
if isPhysicalDevice(sinkName) && !auto {
1366+
if isPhysicalDevice(sinkName) {
13751367
a.resumeSinkConfig(sink)
13761368
}
13771369

audio1/audio_events.go

Lines changed: 46 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -115,57 +115,6 @@ func (a *Audio) isCardIdValid(cardId uint32) bool {
115115
return false
116116
}
117117

118-
func (a *Audio) needAutoSwitchInputPort() bool {
119-
// 不支持自动切换端口
120-
if !a.canAutoSwitchPort() {
121-
return false
122-
}
123-
124-
firstPort, _ := GetPriorityManager().GetTheFirstPort(pulse.DirectionSource)
125-
126-
// 没有可用端口
127-
if firstPort == nil || firstPort.PortType == PortTypeInvalid {
128-
logger.Debug("no input port")
129-
return false
130-
}
131-
132-
// 检查当前profile是否是配置文件中设置的profile
133-
card, err := a.cards.getByName(firstPort.CardName)
134-
if err != nil {
135-
logger.Warning(err)
136-
return false
137-
}
138-
cp := card.core.ActiveProfile
139-
port, err := card.Ports.Get(firstPort.PortName, pulse.DirectionSource)
140-
if err != nil {
141-
logger.Warning(err)
142-
return false
143-
}
144-
145-
// 输入端口不应该主动切换配置文件,会导致输入端口不可用或者发生变化
146-
// 如果当前端口和当前配置文件匹配,不需要切换端口
147-
if port.Profiles.Exists(cp.Name) {
148-
return false
149-
}
150-
151-
// 当前端口就是优先级最高的端口
152-
var currentCardName, currentPortName string
153-
if a.defaultSource != nil {
154-
currentCardName = a.getCardNameById(a.defaultSource.Card)
155-
currentPortName = a.defaultSource.ActivePort.Name
156-
}
157-
158-
if currentCardName == firstPort.CardName && currentPortName == firstPort.PortName {
159-
logger.Debugf("current input<%s,%s> is already the first port",
160-
currentCardName, currentPortName)
161-
return false
162-
}
163-
164-
logger.Debugf("will auto switch from input<%s,%s> to input<%s,%s>",
165-
currentCardName, currentPortName, firstPort.CardName, firstPort.PortName)
166-
return true
167-
}
168-
169118
func (a *Audio) checkAutoSwitchOutputPort() (auto bool, cardId uint32, portName string) {
170119
// 不支持自动切换端口
171120
if !a.canAutoSwitchPort() {
@@ -181,13 +130,28 @@ func (a *Audio) checkAutoSwitchOutputPort() (auto bool, cardId uint32, portName
181130
currentPortName = a.defaultSink.ActivePort.Name
182131
}
183132
}
184-
prefer, pos := GetPriorityManager().GetTheFirstPort(pulse.DirectionSink)
185-
if pos.tp != PortTypeInvalid {
186-
logger.Debug("loop prefer port:", *prefer)
133+
var prefer *PriorityPort
134+
var pos *Position
135+
for {
136+
prefer, pos = GetPriorityManager().LoopAvaiablePort(pulse.DirectionSink, pos)
137+
if prefer == nil || pos == nil || pos.tp == PortTypeInvalid {
138+
break
139+
}
140+
logger.Debugf("loop prefer output port: %+v", prefer)
187141
card, err := a.cards.getByName(prefer.CardName)
188142
if err != nil {
189143
logger.Warning(err)
190-
return
144+
continue
145+
}
146+
// 配置同步可能有滞后性,需要查询声卡和端口是否存在
147+
var pc *pulse.Card
148+
if pc, err = a.ctx.GetCard(card.Id); err != nil {
149+
logger.Warning(err)
150+
continue
151+
}
152+
if _, err = pc.Ports.Get(prefer.PortName, pulse.DirectionSink); err != nil {
153+
logger.Warning(err)
154+
continue
191155
}
192156
mode := GetConfigKeeper().GetMode(card, prefer.PortName)
193157
if currentCardName != prefer.CardName ||
@@ -196,11 +160,11 @@ func (a *Audio) checkAutoSwitchOutputPort() (auto bool, cardId uint32, portName
196160
logger.Debugf("will auto switch from output<%s,%s> to output<%s,%s>",
197161
currentCardName, currentPortName, prefer.CardName, prefer.PortName)
198162
return true, card.Id, prefer.PortName
163+
} else {
164+
return false, 0, ""
199165
}
200-
} else {
201-
return true, 0, ""
202166
}
203-
return
167+
return true, 0, ""
204168
}
205169

206170
func (a *Audio) autoSwitchOutputPort() bool {
@@ -209,10 +173,10 @@ func (a *Audio) autoSwitchOutputPort() bool {
209173
if cardId == 0 || portName == "" {
210174
if !strings.Contains(a.ctx.GetDefaultSink(), "null-sink") {
211175
a.LoadNullSinkModule()
212-
logger.Info("no prefer port, set default sink to", nullSinkName)
176+
logger.Info("no prefer output port, set default sink to", nullSinkName)
213177
a.ctx.SetDefaultSink(nullSinkName)
214178
} else {
215-
logger.Info("no prefer port, default sink is null-sink already")
179+
logger.Info("no prefer output port, default sink is null-sink already")
216180
}
217181
return true
218182
} else {
@@ -239,20 +203,32 @@ func (a *Audio) checkAutoSwitchInputPort() (auto bool, cardId uint32, portName s
239203
currentCardName = a.getCardNameById(a.defaultSource.Card)
240204
currentPortName = a.defaultSource.ActivePort.Name
241205
}
242-
prefer, pos := GetPriorityManager().GetTheFirstPort(pulse.DirectionSource)
243-
for pos.tp != PortTypeInvalid {
244-
logger.Debug("loop prefer port:", *prefer)
206+
207+
var prefer *PriorityPort
208+
var pos *Position
209+
for {
210+
prefer, pos = GetPriorityManager().LoopAvaiablePort(pulse.DirectionSource, pos)
211+
if prefer == nil || pos == nil || pos.tp == PortTypeInvalid {
212+
break
213+
}
214+
logger.Debugf("loop prefer input port: %+v", prefer)
245215
card, err := a.cards.getByName(prefer.CardName)
246216
if err != nil {
247217
logger.Warning(err)
248-
return
218+
continue
249219
}
250-
port, err := card.Ports.Get(prefer.PortName, pulse.DirectionSource)
220+
// 配置同步可能有滞后性,需要查询声卡和端口是否存在
221+
var pc *pulse.Card
222+
if pc, err = a.ctx.GetCard(card.Id); err != nil {
223+
logger.Warning(err)
224+
continue
225+
}
226+
port, err := pc.Ports.Get(prefer.PortName, pulse.DirectionSource)
251227
if err != nil {
252228
logger.Warning(err)
253-
return
229+
continue
254230
}
255-
if port.Profiles.Exists(card.ActiveProfile.Name) {
231+
if card.ActiveProfile != nil && port.Profiles.Exists(card.ActiveProfile.Name) {
256232
if currentCardName != prefer.CardName ||
257233
currentPortName != prefer.PortName {
258234
logger.Debugf("will auto switch from input<%s,%s> to input<%s,%s>",
@@ -262,7 +238,6 @@ func (a *Audio) checkAutoSwitchInputPort() (auto bool, cardId uint32, portName s
262238
return false, 0, ""
263239
}
264240
}
265-
prefer, pos = GetPriorityManager().GetNextPort(pulse.DirectionSource, pos)
266241
}
267242
return true, 0, ""
268243
}
@@ -273,10 +248,10 @@ func (a *Audio) autoSwitchInputPort() bool {
273248
if cardId == 0 || portName == "" {
274249
if !strings.Contains(a.ctx.GetDefaultSource(), "null-sink") {
275250
a.LoadNullSinkModule()
276-
logger.Info("no prefer port, set default source to", nullSinkName)
251+
logger.Info("no prefer input port, set default source to", nullSinkName)
277252
a.ctx.SetDefaultSource(nullSinkName + ".monitor")
278253
} else {
279-
logger.Info("no prefer port, default source is null-sink already")
254+
logger.Info("no prefer input port, default source is null-sink already")
280255
}
281256
return true
282257
} else {
@@ -291,51 +266,6 @@ func (a *Audio) autoSwitchInputPort() bool {
291266
return true
292267
}
293268

294-
func (a *Audio) needAutoSwitchOutputPort() bool {
295-
// 不支持自动切换端口
296-
if !a.canAutoSwitchPort() {
297-
return false
298-
}
299-
logger.Debug("check need auto switch output")
300-
firstPort, _ := GetPriorityManager().GetTheFirstPort(pulse.DirectionSink)
301-
302-
// 没有可用端口
303-
if firstPort == nil || firstPort.PortType == PortTypeInvalid {
304-
logger.Debug("no output port")
305-
return false
306-
}
307-
308-
// 检查当前profile是否是配置文件中设置的profile
309-
card, err := a.cards.getByName(firstPort.CardName)
310-
if err != nil {
311-
logger.Warning(err)
312-
return false
313-
}
314-
cp := card.core.ActiveProfile
315-
profile := GetConfigKeeper().GetMode(card, firstPort.PortName)
316-
if profile != "" && cp.Name != profile {
317-
logger.Warningf("output profile not match, current: %s, prefer: %s", cp.Name, profile)
318-
return true
319-
}
320-
321-
var currentCardName, currentPortName string
322-
if a.defaultSink != nil {
323-
currentCardName = a.getCardNameById(a.defaultSink.Card)
324-
currentPortName = a.defaultSink.ActivePort.Name
325-
}
326-
327-
// 当前端口就是优先级最高的端口
328-
if currentCardName == firstPort.CardName && currentPortName == firstPort.PortName {
329-
logger.Debugf("current output<%s,%s> is already the first",
330-
currentCardName, currentPortName)
331-
return false
332-
}
333-
334-
logger.Debugf("will auto switch from output<%s,%s> to output<%s,%s>",
335-
currentCardName, currentPortName, firstPort.CardName, firstPort.PortName)
336-
return true
337-
}
338-
339269
// 自动切换端口,至少要保证声卡的profile是配置文件中设置的profile
340270
// 如果不是,可能还在切换中,等待一下
341271
func (a *Audio) autoSwitchPort() {

audio1/priority_manager.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -190,16 +190,20 @@ func (pm *PriorityManager) SetTheFirstPort(cardName string, portName string, dir
190190
pm.Save()
191191
}
192192

193-
func (pm *PriorityManager) GetNextPort(direction int, pos *Position) (*PriorityPort, *Position) {
194-
switch direction {
195-
case pulse.DirectionSink:
196-
if len(pm.Output.Ports) > 0 {
197-
return pm.Output.GetNextPort(pm.availablePort, pos)
198-
}
199-
case pulse.DirectionSource:
200-
if len(pm.Input.Ports) > 0 {
201-
return pm.Input.GetNextPort(pm.availablePort, pos)
193+
func (pm *PriorityManager) LoopAvaiablePort(direction int, pos *Position) (*PriorityPort, *Position) {
194+
if pos == nil {
195+
return pm.GetTheFirstPort(direction)
196+
} else {
197+
switch direction {
198+
case pulse.DirectionSink:
199+
if len(pm.Output.Ports) > 0 {
200+
return pm.Output.GetNextPort(pm.availablePort, pos)
201+
}
202+
case pulse.DirectionSource:
203+
if len(pm.Input.Ports) > 0 {
204+
return pm.Input.GetNextPort(pm.availablePort, pos)
205+
}
202206
}
207+
return nil, &Position{tp: PortTypeInvalid, index: -1}
203208
}
204-
return nil, &Position{tp: PortTypeInvalid, index: -1}
205209
}

0 commit comments

Comments
 (0)