Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions audio1/audio.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,11 +788,10 @@ func (a *Audio) init() error {
}
// 加载module-null-sink,噪音抑制时,将sink-input端口Echo-Cancel Playback引入到null-sink
a.LoadNullSinkModule()
GetConfigKeeper().Load()

// 更新本地数据
a.refresh()
GetConfigKeeper().Load()

logger.Debug("init cards")
a.PropsMu.Lock()
a.setPropCards(a.cards.string())
Expand All @@ -813,17 +812,7 @@ func (a *Audio) init() error {
go a.handleStateChanged()
logger.Debug("init done")

if !a.autoSwitchOutputPort() || a.defaultSink != nil {
a.resumeSinkConfig(a.defaultSink)
}
if !a.autoSwitchInputPort() || a.defaultSource != nil {
a.resumeSourceConfig(a.defaultSource)
}

a.moveSinkInputsToSink(nil)

// 蓝牙支持的模式
a.refreshBluetoothOpts()
a.autoSwitchPort()

return nil
}
Expand Down Expand Up @@ -1245,8 +1234,13 @@ func (a *Audio) resumeSinkConfig(s *Sink) {
}

logger.Debugf("set %v mute %v", s.Name, GetConfigKeeper().Mute.MuteOutput || !portConfig.Enabled)
s.setMute(GetConfigKeeper().Mute.MuteOutput || !portConfig.Enabled)
s.setMono(a.Mono)
s.setMute(GetConfigKeeper().Mute.MuteOutput)
// 即将切换通道,就不要设置单声道了,避免触发多次切换
auto, _, _ := a.checkAutoSwitchOutputPort()
if !auto {
s.setMono(a.Mono)
}

}

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

// 虚拟通道不需要恢复配置
auto, _, _ := a.checkAutoSwitchOutputPort()
if isPhysicalDevice(sinkName) && !auto {
if isPhysicalDevice(sinkName) {
a.resumeSinkConfig(sink)
}

Expand Down
160 changes: 45 additions & 115 deletions audio1/audio_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,57 +115,6 @@ func (a *Audio) isCardIdValid(cardId uint32) bool {
return false
}

func (a *Audio) needAutoSwitchInputPort() bool {
// 不支持自动切换端口
if !a.canAutoSwitchPort() {
return false
}

firstPort, _ := GetPriorityManager().GetTheFirstPort(pulse.DirectionSource)

// 没有可用端口
if firstPort == nil || firstPort.PortType == PortTypeInvalid {
logger.Debug("no input port")
return false
}

// 检查当前profile是否是配置文件中设置的profile
card, err := a.cards.getByName(firstPort.CardName)
if err != nil {
logger.Warning(err)
return false
}
cp := card.core.ActiveProfile
port, err := card.Ports.Get(firstPort.PortName, pulse.DirectionSource)
if err != nil {
logger.Warning(err)
return false
}

// 输入端口不应该主动切换配置文件,会导致输入端口不可用或者发生变化
// 如果当前端口和当前配置文件匹配,不需要切换端口
if port.Profiles.Exists(cp.Name) {
return false
}

// 当前端口就是优先级最高的端口
var currentCardName, currentPortName string
if a.defaultSource != nil {
currentCardName = a.getCardNameById(a.defaultSource.Card)
currentPortName = a.defaultSource.ActivePort.Name
}

if currentCardName == firstPort.CardName && currentPortName == firstPort.PortName {
logger.Debugf("current input<%s,%s> is already the first port",
currentCardName, currentPortName)
return false
}

logger.Debugf("will auto switch from input<%s,%s> to input<%s,%s>",
currentCardName, currentPortName, firstPort.CardName, firstPort.PortName)
return true
}

func (a *Audio) checkAutoSwitchOutputPort() (auto bool, cardId uint32, portName string) {
// 不支持自动切换端口
if !a.canAutoSwitchPort() {
Expand All @@ -181,13 +130,28 @@ func (a *Audio) checkAutoSwitchOutputPort() (auto bool, cardId uint32, portName
currentPortName = a.defaultSink.ActivePort.Name
}
}
prefer, pos := GetPriorityManager().GetTheFirstPort(pulse.DirectionSink)
if pos.tp != PortTypeInvalid {
logger.Debug("loop prefer port:", *prefer)
var prefer *PriorityPort
var pos *Position
for {
prefer, pos = GetPriorityManager().LoopAvaiablePort(pulse.DirectionSink, pos)
if prefer == nil || pos == nil || pos.tp == PortTypeInvalid {
break
}
logger.Debugf("loop prefer output port: %+v", prefer)
card, err := a.cards.getByName(prefer.CardName)
if err != nil {
logger.Warning(err)
return
continue
}
// 配置同步可能有滞后性,需要查询声卡和端口是否存在
var pc *pulse.Card
if pc, err = a.ctx.GetCard(card.Id); err != nil {
logger.Warning(err)
continue
}
if _, err = pc.Ports.Get(prefer.PortName, pulse.DirectionSink); err != nil {
logger.Warning(err)
continue
}
mode := GetConfigKeeper().GetMode(card, prefer.PortName)
if currentCardName != prefer.CardName ||
Expand All @@ -196,11 +160,11 @@ func (a *Audio) checkAutoSwitchOutputPort() (auto bool, cardId uint32, portName
logger.Debugf("will auto switch from output<%s,%s> to output<%s,%s>",
currentCardName, currentPortName, prefer.CardName, prefer.PortName)
return true, card.Id, prefer.PortName
} else {
return false, 0, ""
}
} else {
return true, 0, ""
}
return
return true, 0, ""
}

func (a *Audio) autoSwitchOutputPort() bool {
Expand All @@ -209,10 +173,10 @@ func (a *Audio) autoSwitchOutputPort() bool {
if cardId == 0 || portName == "" {
if !strings.Contains(a.ctx.GetDefaultSink(), "null-sink") {
a.LoadNullSinkModule()
logger.Info("no prefer port, set default sink to", nullSinkName)
logger.Info("no prefer output port, set default sink to", nullSinkName)
a.ctx.SetDefaultSink(nullSinkName)
} else {
logger.Info("no prefer port, default sink is null-sink already")
logger.Info("no prefer output port, default sink is null-sink already")
}
return true
} else {
Expand All @@ -239,20 +203,32 @@ func (a *Audio) checkAutoSwitchInputPort() (auto bool, cardId uint32, portName s
currentCardName = a.getCardNameById(a.defaultSource.Card)
currentPortName = a.defaultSource.ActivePort.Name
}
prefer, pos := GetPriorityManager().GetTheFirstPort(pulse.DirectionSource)
for pos.tp != PortTypeInvalid {
logger.Debug("loop prefer port:", *prefer)

var prefer *PriorityPort
var pos *Position
for {
prefer, pos = GetPriorityManager().LoopAvaiablePort(pulse.DirectionSource, pos)
if prefer == nil || pos == nil || pos.tp == PortTypeInvalid {
break
}
logger.Debugf("loop prefer input port: %+v", prefer)
card, err := a.cards.getByName(prefer.CardName)
if err != nil {
logger.Warning(err)
return
continue
}
port, err := card.Ports.Get(prefer.PortName, pulse.DirectionSource)
// 配置同步可能有滞后性,需要查询声卡和端口是否存在
var pc *pulse.Card
if pc, err = a.ctx.GetCard(card.Id); err != nil {
logger.Warning(err)
continue
}
port, err := pc.Ports.Get(prefer.PortName, pulse.DirectionSource)
if err != nil {
logger.Warning(err)
return
continue
}
if port.Profiles.Exists(card.ActiveProfile.Name) {
if card.ActiveProfile != nil && port.Profiles.Exists(card.ActiveProfile.Name) {
if currentCardName != prefer.CardName ||
currentPortName != prefer.PortName {
logger.Debugf("will auto switch from input<%s,%s> to input<%s,%s>",
Expand All @@ -262,7 +238,6 @@ func (a *Audio) checkAutoSwitchInputPort() (auto bool, cardId uint32, portName s
return false, 0, ""
}
}
prefer, pos = GetPriorityManager().GetNextPort(pulse.DirectionSource, pos)
}
return true, 0, ""
}
Expand All @@ -273,10 +248,10 @@ func (a *Audio) autoSwitchInputPort() bool {
if cardId == 0 || portName == "" {
if !strings.Contains(a.ctx.GetDefaultSource(), "null-sink") {
a.LoadNullSinkModule()
logger.Info("no prefer port, set default source to", nullSinkName)
logger.Info("no prefer input port, set default source to", nullSinkName)
a.ctx.SetDefaultSource(nullSinkName + ".monitor")
} else {
logger.Info("no prefer port, default source is null-sink already")
logger.Info("no prefer input port, default source is null-sink already")
}
return true
} else {
Expand All @@ -291,51 +266,6 @@ func (a *Audio) autoSwitchInputPort() bool {
return true
}

func (a *Audio) needAutoSwitchOutputPort() bool {
// 不支持自动切换端口
if !a.canAutoSwitchPort() {
return false
}
logger.Debug("check need auto switch output")
firstPort, _ := GetPriorityManager().GetTheFirstPort(pulse.DirectionSink)

// 没有可用端口
if firstPort == nil || firstPort.PortType == PortTypeInvalid {
logger.Debug("no output port")
return false
}

// 检查当前profile是否是配置文件中设置的profile
card, err := a.cards.getByName(firstPort.CardName)
if err != nil {
logger.Warning(err)
return false
}
cp := card.core.ActiveProfile
profile := GetConfigKeeper().GetMode(card, firstPort.PortName)
if profile != "" && cp.Name != profile {
logger.Warningf("output profile not match, current: %s, prefer: %s", cp.Name, profile)
return true
}

var currentCardName, currentPortName string
if a.defaultSink != nil {
currentCardName = a.getCardNameById(a.defaultSink.Card)
currentPortName = a.defaultSink.ActivePort.Name
}

// 当前端口就是优先级最高的端口
if currentCardName == firstPort.CardName && currentPortName == firstPort.PortName {
logger.Debugf("current output<%s,%s> is already the first",
currentCardName, currentPortName)
return false
}

logger.Debugf("will auto switch from output<%s,%s> to output<%s,%s>",
currentCardName, currentPortName, firstPort.CardName, firstPort.PortName)
return true
}

// 自动切换端口,至少要保证声卡的profile是配置文件中设置的profile
// 如果不是,可能还在切换中,等待一下
func (a *Audio) autoSwitchPort() {
Expand Down
24 changes: 14 additions & 10 deletions audio1/priority_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,16 +190,20 @@ func (pm *PriorityManager) SetTheFirstPort(cardName string, portName string, dir
pm.Save()
}

func (pm *PriorityManager) GetNextPort(direction int, pos *Position) (*PriorityPort, *Position) {
switch direction {
case pulse.DirectionSink:
if len(pm.Output.Ports) > 0 {
return pm.Output.GetNextPort(pm.availablePort, pos)
}
case pulse.DirectionSource:
if len(pm.Input.Ports) > 0 {
return pm.Input.GetNextPort(pm.availablePort, pos)
func (pm *PriorityManager) LoopAvaiablePort(direction int, pos *Position) (*PriorityPort, *Position) {
if pos == nil {
return pm.GetTheFirstPort(direction)
} else {
switch direction {
case pulse.DirectionSink:
if len(pm.Output.Ports) > 0 {
return pm.Output.GetNextPort(pm.availablePort, pos)
}
case pulse.DirectionSource:
if len(pm.Input.Ports) > 0 {
return pm.Input.GetNextPort(pm.availablePort, pos)
}
}
return nil, &Position{tp: PortTypeInvalid, index: -1}
}
return nil, &Position{tp: PortTypeInvalid, index: -1}
}
23 changes: 15 additions & 8 deletions audio1/sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ func (s *Sink) SetVolume(value float64, isPlay bool) *dbus.Error {

if value == 0 {
value = 0.001
s.SetMute(true)
s.setMute(true)
} else {
s.setMute(GetConfigKeeper().Mute.MuteOutput)
}
s.PropsMu.Lock()
cv := s.cVolume.SetAvg(value)
Expand Down Expand Up @@ -235,14 +237,24 @@ func (s *Sink) setVBF(v, b, f float64) *dbus.Error {
func (s *Sink) SetMute(value bool) *dbus.Error {
logger.Infof("dbus call SetMute with value %t, the sink name is %s", value, s.Name)

if err := s.setMute(value); err != nil {
return dbusutil.ToError(err)

}
GetConfigKeeper().SetMuteOutput(value)
return nil
}

func (s *Sink) setMute(value bool) error {
err := s.CheckPort()
if err != nil {
logger.Warning(err.Body...)
return err
}

if !s.setPropMute(value) {
return nil
}
s.audio.context().SetSinkMuteByIndex(s.index, value)
GetConfigKeeper().SetMuteOutput(value)

if !value {
s.playFeedback()
Expand Down Expand Up @@ -314,8 +326,3 @@ func (s *Sink) playFeedback() {
s.PropsMu.RUnlock()
playFeedbackWithDevice(name)
}

func (s *Sink) setMute(v bool) {
logger.Debugf("Sink #%d setMute %v", s.index, v)
s.audio.context().SetSinkMuteByIndex(s.index, v)
}
Loading