Skip to content

Commit d773796

Browse files
committed
fix(audio): honor manual output selection
1. Track pending manual port switches when a profile change is required. 2. Complete manual output device selection after the card becomes ready. 3. Avoid losing manual port selection when automatic port switching is disabled. Log: Fix manual output device selection not taking effect when automatic port switching is disabled. fix(audio): 修复手动输出设备选择失效 1. 在需要切换配置文件时记录待处理的手动端口切换。 2. 在声卡就绪后继续完成手动输出设备选择。 3. 避免关闭自动端口切换后丢失手动端口选择。 Log: 修复关闭自动端口切换后设置输出设备不生效的问题。
1 parent d970a19 commit d773796

2 files changed

Lines changed: 98 additions & 12 deletions

File tree

audio1/audio.go

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ type Audio struct {
190190
noRestartPulseAudio bool
191191
// 自动端口切换
192192
enableAutoSwitchPort bool
193+
pendingManualPortMu sync.Mutex
194+
pendingManualPort *pendingManualPortSwitch
193195

194196
// 控制中心-声音-设备管理 是否显示
195197
controlCenterDeviceManager dconfig.Bool
@@ -204,13 +206,19 @@ type Audio struct {
204206
}
205207
}
206208

209+
type pendingManualPortSwitch struct {
210+
cardId uint32
211+
portName string
212+
direction int
213+
}
214+
207215
func newAudio(service *dbusutil.Service) *Audio {
208216
a := &Audio{
209-
service: service,
210-
meters: make(map[string]*Meter),
211-
MaxUIVolume: pulse.VolumeUIMax,
217+
service: service,
218+
meters: make(map[string]*Meter),
219+
MaxUIVolume: pulse.VolumeUIMax,
212220
AudioServerState: AudioStateChanged,
213-
cardFixGroup: newCardFixGroup(),
221+
cardFixGroup: newCardFixGroup(),
214222
}
215223

216224
var err error
@@ -1032,17 +1040,83 @@ func (a *Audio) setPort(cardId uint32, portName string, direction int, auto bool
10321040
}
10331041

10341042
if card.ActiveProfile.Name == profile {
1043+
if !auto {
1044+
return a.setManualPortDirectly(cardId, portName, direction)
1045+
}
10351046
return a.setPortDirectly(cardId, portName, direction)
10361047
} else {
10371048
// 暂不设置端口,先切换配置文件
1038-
// 等待事件完成后,再自动设置端口
1049+
// 等待事件完成后,自动切换通过 autoSwitchPort 继续;手动切换通过 pendingManualPort 继续
10391050
logger.Info("modify card profile:", card.core.Name, "from", card.ActiveProfile.Name, "to", profile)
1051+
if !auto {
1052+
a.setPendingManualPort(cardId, portName, direction)
1053+
}
10401054
card.core.SetProfile(profile)
10411055
}
10421056

10431057
return nil
10441058
}
10451059

1060+
func (a *Audio) setPendingManualPort(cardId uint32, portName string, direction int) {
1061+
logger.Debugf("setPendingManualPort: cardId=%d, portName=%s, direction=%d", cardId, portName, direction)
1062+
1063+
a.pendingManualPortMu.Lock()
1064+
defer a.pendingManualPortMu.Unlock()
1065+
1066+
a.pendingManualPort = &pendingManualPortSwitch{
1067+
cardId: cardId,
1068+
portName: portName,
1069+
direction: direction,
1070+
}
1071+
}
1072+
1073+
func (a *Audio) setManualPortDirectly(cardId uint32, portName string, direction int) error {
1074+
a.clearPendingManualPort(cardId, direction)
1075+
return a.setPortDirectly(cardId, portName, direction)
1076+
}
1077+
1078+
func (a *Audio) clearPendingManualPort(cardId uint32, direction int) {
1079+
logger.Debugf("clearPendingManualPort: cardId=%d, direction=%d", cardId, direction)
1080+
1081+
a.pendingManualPortMu.Lock()
1082+
defer a.pendingManualPortMu.Unlock()
1083+
1084+
if a.pendingManualPort != nil &&
1085+
a.pendingManualPort.cardId == cardId &&
1086+
a.pendingManualPort.direction == direction {
1087+
a.pendingManualPort = nil
1088+
}
1089+
}
1090+
1091+
func (a *Audio) completePendingManualPort(cardId uint32) (handled bool, applied bool) {
1092+
logger.Debugf("completePendingManualPort: cardId=%d", cardId)
1093+
1094+
a.pendingManualPortMu.Lock()
1095+
if a.pendingManualPort == nil || a.pendingManualPort.cardId != cardId {
1096+
a.pendingManualPortMu.Unlock()
1097+
return false, false
1098+
}
1099+
pending := *a.pendingManualPort
1100+
a.pendingManualPortMu.Unlock()
1101+
1102+
err := a.setPortDirectly(pending.cardId, pending.portName, pending.direction)
1103+
if err != nil {
1104+
logger.Warningf("failed to complete pending manual port: cardId=%d, portName=%s, direction=%d, err=%v",
1105+
pending.cardId, pending.portName, pending.direction, err)
1106+
return true, false
1107+
}
1108+
1109+
a.pendingManualPortMu.Lock()
1110+
if a.pendingManualPort != nil &&
1111+
a.pendingManualPort.cardId == pending.cardId &&
1112+
a.pendingManualPort.portName == pending.portName &&
1113+
a.pendingManualPort.direction == pending.direction {
1114+
a.pendingManualPort = nil
1115+
}
1116+
a.pendingManualPortMu.Unlock()
1117+
return true, true
1118+
}
1119+
10461120
// setPortDirectly 直接设置端口,无需切换配置文件
10471121
func (a *Audio) setPortDirectly(cardId uint32, portName string, direction int) error {
10481122
if direction == pulse.DirectionSink {

audio1/audio_events.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,18 @@ func (a *Audio) autoSwitchPort() {
274274
a.autoSwitchInputPort()
275275
}
276276

277+
func (a *Audio) switchPortAfterCardReady(cardId uint32) {
278+
handledPending, applied := a.completePendingManualPort(cardId)
279+
if !handledPending {
280+
a.autoSwitchPort()
281+
return
282+
}
283+
if !applied {
284+
logger.Warningf("pending manual switch for cardId=%d was not applied, skip auto switch", cardId)
285+
return
286+
}
287+
}
288+
277289
func (a *Audio) handleCardEvent(eventType int, idx uint32) {
278290
var shouldAutoSwitch = false
279291
switch eventType {
@@ -298,7 +310,7 @@ func (a *Audio) handleCardEvent(eventType int, idx uint32) {
298310
GetPriorityManager().refreshPorts(a.cards)
299311
GetPriorityManager().Save()
300312
if a.checkCardIsReady(idx) {
301-
a.autoSwitchPort()
313+
a.switchPortAfterCardReady(idx)
302314
}
303315
}
304316
}
@@ -425,7 +437,7 @@ func (a *Audio) handleSinkAdded(idx uint32) {
425437
} else if a.checkCardIsReady(sink.Card) {
426438
// 只有新增sink或端口列表/活跃端口变化时才触发自动切换
427439
if isNewSink || portChanged {
428-
a.autoSwitchPort()
440+
a.switchPortAfterCardReady(sink.Card)
429441
}
430442
}
431443
}
@@ -453,7 +465,7 @@ func (a *Audio) handleSinkRemoved(idx uint32) {
453465
return
454466
}
455467
if isPhy && a.checkCardIsReady(cardId) {
456-
a.autoSwitchPort()
468+
a.switchPortAfterCardReady(cardId)
457469
}
458470
}
459471

@@ -473,7 +485,7 @@ func (a *Audio) handleSinkChanged(idx uint32) {
473485
// cardchange事件也会触发,但是处理不了,因为这时sink可能还没更新,无可用端口
474486
// 只有当端口列表或活跃端口发生变化时,才触发自动切换
475487
if portChanged && isPhysicalDevice(sink.Name) && a.checkCardIsReady(sink.Card) {
476-
a.autoSwitchPort()
488+
a.switchPortAfterCardReady(sink.Card)
477489
}
478490

479491
if a.defaultSink != nil && a.defaultSink.index == idx && isBluezAudio(sink.Name) {
@@ -529,7 +541,7 @@ func (a *Audio) handleSourceAdded(idx uint32) {
529541
} else if a.checkCardIsReady(source.Card) {
530542
// 只有新增source或端口列表/活跃端口变化时才触发自动切换
531543
if isNewSource || portChanged {
532-
a.autoSwitchPort()
544+
a.switchPortAfterCardReady(source.Card)
533545
}
534546
}
535547

@@ -557,7 +569,7 @@ func (a *Audio) handleSourceRemoved(idx uint32) {
557569
a.defaultSource = nil
558570
}
559571
if isPhy && a.checkCardIsReady(cardId) {
560-
a.autoSwitchPort()
572+
a.switchPortAfterCardReady(cardId)
561573
}
562574
}
563575

@@ -578,7 +590,7 @@ func (a *Audio) handleSourceChanged(idx uint32) {
578590
// cardchange事件也会触发,但是处理不了,因为这时source可能还没更新,无可用端口
579591
// 只有当端口列表或活跃端口发生变化时,才触发自动切换
580592
if portChanged && isPhysicalDevice(source.Name) && a.checkCardIsReady(source.Card) {
581-
a.autoSwitchPort()
593+
a.switchPortAfterCardReady(source.Card)
582594
}
583595
}
584596

0 commit comments

Comments
 (0)