Skip to content
Draft
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
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ revision record.

## OVOS-AUDIO-1 — Audio Output Service

### 3

- §4.2 — an instant sound carries the §4.1 session scope: the audio
output service MUST only play an instant sound whose
`context.session.session_id` matches a session it is configured to
serve locally. Matches the enqueue rule already in §4.1; no wire
shape changes.

### 2

- §4.0 (new) — one audio-format rule for all audio payloads: the
Expand Down Expand Up @@ -505,6 +513,19 @@ version 2: its `{{ … }}` sequences become substitution points, and its

## OVOS-AUDIO-IN-1 — Audio Input Service

### 3

- §6.3 — sleep entry is now acknowledged: the audio input service
MUST reply on `ovos.listener.sleep.response` (OVOS-MSG-1 §5.3
`response` derivation) once sleep mode has been entered. Supersedes
the version-2 entry below, which called sleep entry unacknowledged
by design. §6.3 also adds `ovos.listener.sleep.query`, answered on
`ovos.listener.sleep.query.response` with an `asleep` bool, so a
component can read current sleep state instead of inferring it from
the last-seen lifecycle signal. A repeated `ovos.listener.sleep`
received while already asleep still gets the `.response`
acknowledgement; sleep mode does not change.

### 2

- §6.4 — `ovos.listener.wake`, the controller's request to leave sleep
Expand Down
41 changes: 30 additions & 11 deletions audio-in.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,13 @@ No payload. The session is identified by `context.session.session_id`
of this Message.

On receipt the audio input service enters sleep mode and suspends
capture until it is awoken (§6.4). Sleep entry is **unacknowledged
by design**: no confirmation Message is emitted on entering sleep.
The only sleep-related emission is `ovos.listener.awoken` on the
sleep→awake transition (§6.4).
capture until it is awoken (§6.4). The audio input service **MUST**
acknowledge the request via the `response` derivation (OVOS-MSG-1
§5.3) — on `ovos.listener.sleep.response` — once sleep mode has been
entered. The reply carries no payload; it exists so a controller can
confirm sleep took effect rather than assuming it from silence. A
request received while already asleep **MUST** get the same reply;
sleep mode does not change and the request is not an error.

**Sleep is device-scoped.** Although the `ovos.listener.sleep`
request rides a session like every Message, sleep mode is a
Expand All @@ -243,13 +246,23 @@ device-scope effect — capture suspended or resumed for every
session — is identical no matter which session's identifier the
Message carries.

No topic in this specification lets a component query current
listener state (awake, asleep, capturing) on demand. This is a
**deliberate omission**: sleep and record signals (§6.1–§6.4) are
edge-triggered notifications, not a queryable state store. A
deployment that needs to synchronize to current state on connect
(e.g. a bridge attaching mid-session) derives it from the last-seen
lifecycle signal rather than polling for one.
**Sleep state is queryable.** A component MAY query current sleep
state by emitting:

`ovos.listener.sleep.query`

Request payload: none.

The audio input service **MUST** reply via the `response` derivation
(OVOS-MSG-1 §5.3) — on `ovos.listener.sleep.query.response` — with:

| Field | Type | Required | Meaning |
|-------|------|----------|---------|
| `asleep` | bool | yes | `true` if the device is currently in sleep mode, `false` otherwise. |

This query is the only queryable listener state this specification
defines; capture activity (§6.1, §6.2) remains an edge-triggered
notification, not a queryable state store.

### 6.4 Wake request and awoken

Expand Down Expand Up @@ -316,6 +329,9 @@ word (push-to-talk, `ovos.mic.listen`) emit no wake-word signal.
| `ovos.listener.record.ended` | audio-input → broadcast | Voice-command capture ended (§6.2). |
| `ovos.listener.sleep` | controller → audio-input | Enter device-wide sleep mode and suspend capture (§6.3). |
| `ovos.listener.wake` | controller → audio-input | Leave sleep mode and resume capture (§6.4). |
| `ovos.listener.sleep.response` | audio-input → controller | Sleep mode entered (§6.3). |
| `ovos.listener.sleep.query` | any component → audio-input | Query current sleep state (§6.3). |
| `ovos.listener.sleep.query.response` | audio-input → requester | Current sleep state (§6.3). |
| `ovos.listener.awoken` | audio-input → broadcast | Left sleep mode (§6.4). |
| `ovos.mic.listen` | any component → audio-input | Re-open the user input channel; consumed here, defined in OVOS-AUDIO-1 §4.4. |
| `ovos.stt.failed` | audio-input → broadcast | Capture yielded no usable transcription; terminal, no lifecycle follows (§5). |
Expand Down Expand Up @@ -344,6 +360,9 @@ word (push-to-talk, `ovos.mic.listen`) emit no wake-word signal.
sessions while asleep (§6.3);
- leave sleep mode on `ovos.listener.wake`, treating a request received
while awake as a no-op (§6.4);
- reply to `ovos.listener.sleep` once sleep mode has been entered,
and reply to `ovos.listener.sleep.query` with current sleep state
(§6.3);
- emit `ovos.listener.awoken` on the sleep→awake transition (§6.4).

### An audio input service **SHOULD**:
Expand Down
17 changes: 12 additions & 5 deletions audio-out.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,16 @@ stream (§4.0).

### 4.2 Instant sounds

Instant sounds are played via `ovos.audio.play_sound`. They start
immediately on receipt, play over any audio currently in progress
from the scheduled queue, MAY overlap each other, and are **not**
affected by stop signals (§6).
Instant sounds are played via `ovos.audio.play_sound`. They carry
the session scope defined in §4.1: the audio output service MUST
only play an instant sound whose `context.session.session_id`
matches a session it is configured to serve locally. Playback starts
immediately on receipt, over any audio currently in progress from
the scheduled queue, and instant sounds MAY overlap each other. They
are **not** affected by stop signals (§6): an instant sound is a
short acknowledgement or error cue, and anything longer belongs on
the scheduled queue, where it takes its turn with speech and is
stoppable there.

**Play-sound topic** `ovos.audio.play_sound`:

Expand Down Expand Up @@ -448,7 +454,8 @@ obligation on receiving a stop signal is the sequence above.
time in FIFO order (§4.1);
- support queued sound playback via `ovos.audio.queue` (§4.1);
- play instant sounds immediately on `ovos.audio.play_sound` without
queuing or stopping scheduled playback (§4.2);
queuing or stopping scheduled playback, only for a session it is
configured to serve locally (§4.2);
- emit `ovos.audio.output.started` when a playback session begins
(§5.1);
- emit `ovos.audio.output.ended` when a playback session ends (§5.2);
Expand Down