File: bt-pinephone.lua

package info (click to toggle)
wireplumber 0.5.12-3
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 4,244 kB
  • sloc: ansic: 41,043; python: 391; sh: 62; makefile: 57; xml: 23
file content (116 lines) | stat: -rwxr-xr-x 3,054 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/wpexec
--
-- WirePlumber
--
-- Copyright © 2022 Collabora Ltd.
--    @author Frédéric Danis <frederic.danis@collabora.com>
--
-- SPDX-License-Identifier: MIT
--
-- This is an example of the offload SCO nodes platform specific management,
-- in this case for the PinePhone.
--
-- The PinePhone provides specific ALSA ports to route audio to the Bluetooth
-- chipset. This script selects these ports when the offload SCO nodes state
-- change to 'running'.
--
-- This scriptcan be executed as a standalone executable, or it can be placed
-- in WirePlumber's scripts directory and loaded together with other scripts.
-----------------------------------------------------------------------------

devices_om = ObjectManager {
  Interest {
    type = "device",
  }
}

nodes_om = ObjectManager {
  Interest {
    type = "node",
    Constraint { "node.name", "#", "*.bluez_*put*"},
    Constraint { "device.id", "+" },
  }
}

function parseParam(param, id)
  local route = param:parse()
  if route.pod_type == "Object" and route.object_id == id then
    return route.properties
  else
    return nil
  end
end

function setPlatformRoute (route_name, direction)
  local platform_sound = nil
  local device_id = nil
  local route_save = nil

  local interest = Interest {
    type = "device",
    Constraint { "device.name", "=", "alsa_card.platform-sound"}
  }
  for d in devices_om:iterate (interest) do
    platform_sound = d

    for p in platform_sound:iterate_params("Route") do
      route = parseParam(p, "Route")
      if route.direction == direction then
        device_id = route.device
        route_save = route.save
      end
    end

    for p in platform_sound:iterate_params("EnumRoute") do
      enum_route = parseParam(p, "EnumRoute")

      if enum_route.name == route_name then
        route_index = enum_route.index
      end
    end
  end

  if route.index == route_index then
    return
  end

  -- default props
  local props = {
    "Spa:Pod:Object:Param:Props", "Route",
    mute = false,
  }

  -- construct Route param
  local param = Pod.Object {
    "Spa:Pod:Object:Param:Route", "Route",
    index = route_index,
    device = device_id,
    props = Pod.Object(props),
    save = route_save,
  }

  Log.info(param, "setting route on " .. tostring(platform_sound))
  platform_sound:set_param("Route", param)
end

nodes_om:connect("object-added", function(_, node)
  node:connect("state-changed", function(node, old_state, cur_state)
    local interest = Interest {
      type = "device",
      Constraint { "object.id", "=", node.properties["device.id"]}
    }
    for d in devices_om:iterate (interest) do
      if cur_state == "running" then
        -- Both direction should be set to allow audio streaming
        setPlatformRoute("[Out] BluetoothHeadset", "Output")
        setPlatformRoute("[In] BluetoothHeadset", "Input")
      else
        setPlatformRoute("[Out] Earpiece", "Output")
        setPlatformRoute("[In] DigitalMic", "Input")
      end
    end
  end)
end)

nodes_om:activate()
devices_om:activate()