summaryrefslogtreecommitdiffstats
path: root/README.md
blob: 7efbbbb6de8ed315dfbe23a9f2862f40b77ee116 (plain)
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
117
118
119
120
121
122
123
124
# Pulseaudio 4A (AGL Advanced Audio Agent) Client Module

This module allows pulseaudio to work as a client of the AGL Advanced Audio Agent.

## Dependencies

#### libafbwsc
This library is used to communicate with AFB (Application Framework Binder),
the interface that is being used by 4A.

#### libsystemd
This is needed for the systemd event loop implementation which is a hard
requirement of libafbwsc.

#### json-c
This is needed for json message parsing, also a hard requirement of libafbwsc.

## Building

This is meant to be built as part of the AGL distribution, using its bitbake
recipe. It depends on an AGL-specific patch on pulseaudio that installs the
module development headers on the system. On other distributions the source
files of this repository should be copied into the pulseaudio source tree
and pulseaudio's build system should be adjusted accordingly.

## Operation

* module-4a-client initially calls ahl-4a/get_roles to retrieve the available
roles in 4a
* When a new sink-input appears, it uses its media.role property and the
available roles to figure out which role it should use
* if the role turns out to be empty, it uses the default_role parameter to
assign a role to it
* it calls ahl-4a/<role> {"action": "open"} to open the device and get an ALSA
device uri
* it loads module-alsa-sink with the device uri set to whatever ahl-4a returned
* if all goes well, it moves the new sink-input to this new alsa sink
* otherwise it takes no action and expects pulseaudio configuration to be set
up in such a way so that the sink-input is muted
* when the sink-input disappears, it unloads the relevant module-alsa-sink
instance and calls ahl-4a/<role> {"action": "close"} to close the device in 4A

## Configuration

module-4a-client is recommended to be loaded from pulseaudio's default.pa config
file and it should be loaded in combination with a null sink:

```
load-module module-null-sink sink_name=aaaa_null_sink sink_properties="device.description='4A Null Output'"
set-default-sink aaaa_null_sink
load-module module-4a-client
```

This is because it expects that all new clients will automatically connect
to a sink that is not one of the sinks that it loads internally.

Additionally, for correct operation, it should **not** be loaded together
with one of the following:

* module-alsa-card
* module-udev-detect
* module-detect
* module-default-device-restore
* module-role-cork

... or anything else that might automatically load new sinks, move
clients on other sinks and alter stream volumes (volumes are meant to
be handled by 4A, pulseaudio should be dummy in this usage scenario)

### Parameters

The module accepts two parameters, both optional.

* 'uri' - The URI of the socket that will be used to talk to ahl-4a.
Defaults to 'unix:/run/user/0/apis/ws/ahl-4a'

* 'default_role' - The name of the role that will be used as a fallback for
clients that do not specify 'media.role'. Defaults to 'multimedia'

## Testing

Save this example configuration in a file called config.pa:
```
#!/usr/bin/pulseaudio -nF

.fail

load-module module-augment-properties
load-module module-native-protocol-unix

load-module module-null-sink sink_name=aaaa_null_sink sink_properties="device.description='4A Null Output'"
set-default-sink aaaa_null_sink
load-module module-4a-client

load-module module-rescue-streams
load-module module-always-sink
load-module module-suspend-on-idle
```

Start pulseaudio with the above example config:
```
# pulseaudio -nF config.pa
...
```

In another terminal:
```
# gst-launch-1.0 audiotestsrc ! pulsesink stream-properties="p,media.role=(string)emergency"
```

You can substitute "emergency" with any other available role, or just omit the
whole stream-properties=... part to get assigned the default role ("multimedia")

## Missing functionality

The following functionality still needs to be implemented:

* Handle source-outputs in the same way as sink-inputs
* Cork sink-inputs that have been denied access to the device, so that the
client can act on it.
* Enforce security requirements - no other client should be allowed to
connect to the internally loaded alsa sinks
* Propagate the SMACK label of clients to 4A - this is supposed to allow 4A
to restrict which clients are allowed to output audio