synit-manual/src/protocols/synit/audio.md

61 lines
2.8 KiB
Markdown
Raw Normal View History

2022-10-12 14:06:26 +00:00
# Audio control
2022-10-12 19:58:29 +00:00
- [`[synit]/protocols/schemas/audio.prs`](https://git.syndicate-lang.org/synit/synit/src/branch/main/protocols/schemas/audio.prs)
The audio control protocol configures sound sources and sinks, for instance for call audio
control on a mobile phone. This protocol is still *experimental*, as configuration of audio
stacks is complex and I have only a few simple examples to work from thus far. As Synit is
ported to new systems (e.g. new mobile handsets, to desktop machines, and so on), this protocol
will be refined.
**Implementation.** The protocol is (as of October 2022) implemented entirely within the
SqueakPhone Smalltalk image, in class `AudioProfileDaemon`. The audio profile daemon has three
tasks: first, to track Linux input `HEADPHONE_INSERT` and `MICROPHONE_INSERT` events and state,
producing `HeadsetSpeakerPresent` and `HeadsetMicrophonePresent` assertions in response;
second, to track application state such as whether a call is in progress or not; and third, to
respond to changes in device and application state, along with changes in sink/source mapping
configuration, by using the external `amixer` program to enable and disable audio sinks and
sources. The schema definition file contains a few
[comments](https://git.syndicate-lang.org/synit/synit/src/commit/a2babb63d55743ce942562e7ccb9106fdb239cf4/protocols/schemas/audio.prs#L3-L17)
that give some of the flavour of the logic involved.
## Source/Sink mappings
Each different kind of device asserts `Mapping` records to connect abstract `Endpoint` names to
concrete ALSA device names.
```
Mapping = <alsa-mapping @abstract Endpoint @concrete string> .
Endpoint = <source @value Source> / <sink @value Sink> .
Sink = =speaker / =headset / =earpiece .
Source = =speakerphone / =headset / =handset .
```
**Example.** When the Smalltalk code detects that it is running on a PinePhone, it asserts
- `<alsa-mapping <sink speaker> "Line Out">`
- `<alsa-mapping <sink headset> "Headphone">`
- `<alsa-mapping <sink earpiece> "Earpiece">`
- `<alsa-mapping <source speakerphone> "Mic1">`
- `<alsa-mapping <source handset> "Mic1">`
## Audio device state
The current daemon interprets low-level Linux input subsystem events, asserting
`HeadsetSpeakerPresent` and `HeadsetMicrophonePresent` when the relevant hardware is physically
attached to the system. These assertions are in turn used when selecting an audio profile to
enable.
```
HeadsetSpeakerPresent = <headset-speaker-present> .
HeadsetMicrophonePresent = <headset-microphone-present> .
```
## Relevant application state
The current daemon reacts to changes in
[`AlertSoundPlaying`](./soundEffects.md#AlertSoundPlaying),
[`PhoneRinging`](./telephony.md#PhoneRinging),
[`CallInProgress`](./telephony.md#CallInProgress), and
[`Speakerphone`](./telephony.md#Speakerphone) when selecting an audio profile to enable.