Files
i3status-go/vendor/github.com/mafik/pulseaudio/outputs.go
2024-01-06 18:33:44 +03:00

154 lines
2.9 KiB
Go

package pulseaudio
import "fmt"
// Output represents PulseAudio output.
type Output struct {
client *Client
CardID string
PortID string
CardName string
PortName string
Available bool
}
// Activate sets this output as the main one.
func (o Output) Activate() error {
c := o.client
cards, err := c.Cards()
if err != nil {
return err
}
if o.CardID == "all" && o.PortID == "none" {
for _, otherCard := range cards {
err = c.SetCardProfile(otherCard.Index, "off")
if err != nil {
return err
}
}
return nil
}
var found bool
var card Card
for _, card = range cards {
if card.Name == o.CardID {
found = true
break
}
}
if !found {
return fmt.Errorf("PulseAudio error: card %s is no longer available", o.CardID)
}
found = false
var port port
for _, port = range card.Ports {
if port.Name == o.PortID {
found = true
break
}
}
if !found {
return fmt.Errorf("PulseAudio error: port %s is no longer available", o.PortID)
}
for _, otherCard := range cards {
if otherCard.Index == card.Index {
continue
}
err = c.SetCardProfile(otherCard.Index, "off")
if err != nil {
return err
}
}
bestProfile := port.Profiles[0]
for _, profile := range port.Profiles {
if profile.Priority > bestProfile.Priority {
bestProfile = profile
}
}
err = c.SetCardProfile(card.Index, bestProfile.Name)
if err != nil {
return err
}
sinks, err := c.sinks()
if err != nil {
return err
}
s, err := c.ServerInfo()
if err != nil {
return err
}
for _, sink := range sinks {
if sink.CardIndex != card.Index {
continue
}
if s.DefaultSink == sink.Name {
continue
}
return c.setDefaultSink(sink.Name)
}
return nil
}
// Outputs returns a list of all audio outputs and an index of the active audio output.
//
// The last audio output is always called "None" and indicates that audio is disabled.
func (c *Client) Outputs() (outputs []Output, activeIndex int, err error) {
s, err := c.ServerInfo()
if err != nil {
return nil, 0, err
}
sinks, err := c.sinks()
if err != nil {
return nil, 0, err
}
cards, err := c.Cards()
if err != nil {
return nil, 0, err
}
activeIndex = -1
for _, card := range cards {
for _, port := range card.Ports {
if port.Direction != 1 {
continue
}
for _, sink := range sinks {
if sink.Name != s.DefaultSink {
continue
}
if sink.CardIndex != card.Index {
continue
}
if sink.ActivePortName != port.Name {
continue
}
activeIndex = len(outputs)
}
outputs = append(outputs, Output{
client: c,
CardID: card.Name,
CardName: card.PropList["device.description"],
PortID: port.Name,
PortName: port.Description,
Available: port.Available != 1,
})
}
}
if activeIndex == -1 {
activeIndex = len(outputs)
}
outputs = append(outputs, Output{
client: c,
CardID: "all",
CardName: "All",
PortID: "none",
PortName: "None",
Available: false,
})
return
}