Skip to content

Audio Service

Maturity: Stable ⬤⬤⬤⬤◯

Established and production-ready, actively maintained. Rated by repository health, not version.

In a nutshell

ovos-audio is the part of OVOS that actually makes sound come out of the speakers. When a skill wants to say something, this service turns that text into speech (using a TTS plugin) and plays it, while making sure only one thing talks at a time and turning down background music so you can hear the reply. Think of it as the assistant's mouth and its audio mixer rolled into one. See TTS Plugins or the Glossary for related terms.

📐 Formal specification

The audio output service (dialog-transformer chain, TTS synthesis, tts-transformer chain, playback queue, plus remote-client rendering) is specified by OVOS-AUDIO-1: Audio Output Service. The dialog and tts transformer chains it hosts are specified by OVOS-TRANSFORM-1: Transformer Plugins (§3.5 dialog, §3.6 tts). See also the spec index. Spec topic names are canonical below, with the legacy name noted once. The media audioservice, subsystem 2 below, is a separate, deprecated concern and is not covered by OVOS-AUDIO-1.

ovos-audio is the component responsible for TTS synthesis and audio playback. It ensures that only one thing is speaking at a time and manages audio focus between different media sources.

In plain terms: when a skill says "tell the user X", that speak message lands here. ovos-audio turns the text into sound with a TTS plugin and plays it. It ducks any background music while it talks.

Two independent subsystems: don't conflate them

ovos-audio hosts two separate things that are easy to mix up:

  1. The TTS / sound playback queue (described on this page): a single playback queue (TTS.queue, drained by one PlaybackThread) that plays spoken responses and sound effects (beeps, notification sounds). This is the core job of ovos-audio. It is always on and has nothing to do with the media audioservice or ovos-media.
  2. The legacy media audioservice: an optional subsystem (AudioService, gated by enable_old_audioservice, on by default) that plays music, news, and streams through audioservice backends such as OCP. This is the deprecated part, being superseded by the standalone ovos-media daemon. A second top-level key, disable_ocp (default false, slated to flip to true), gates whether the OCP audioservice backend loads within this subsystem. Both keys are set at the top level of mycroft.conf, not under the Audio section. For the compatibility bridges and known coupling issues this legacy subsystem carries into ovos-media, see ovos-media Legacy Compatibility.

Switching media playback to ovos-media (enable_old_audioservice: false) turns off subsystem 2 only. TTS and sound playback (subsystem 1) keep working exactly as before. enable_old_audioservice works in both directions: flip it back to true to return to the legacy audioservice, on the same install, no reinstall needed.

Upcoming breaking change

The legacy media audioservice and standalone ovos-media currently coexist as mutually exclusive alternatives: which one plays media is a deployer's choice. Do not run both at once. The legacy media audioservice subsystem (subsystem 2 above, including the OCP audioservice backend) is planned to stop being the default, with media playback moving wholly to ovos-media. Opting in today takes two steps: set enable_old_audioservice: false and install and run the separate ovos-media daemon. The flag only turns the legacy half off. It does not start ovos-media for you. The TTS / sound playback queue (subsystem 1) is unaffected either way.


Technical Reference
  • PlaybackService.init_messagebus() in ovos_audio/service.py registers the ovos.utterance.speak (legacy speak) handler and the rest of the bus events. It is called from __init__. PlaybackService.run() marks the service alive/ready and reports legacy-audio-backend status.

  • PlaybackThread.run() in ovos_audio/playback.py holds the logic for playing back the synthesized audio chunks.

  • AudioService.play() in ovos_audio/audio.py routes media playback to the correct backend by URI scheme (MPV, VLC, etc.).


Overview

The audio service receives ovos.utterance.speak messages (legacy: speak) from the messagebus. This is the natural-language response exit point of the utterance lifecycle (OVOS-PIPELINE-1 §9.6). The service runs the text through the dialog-transformer chain, sends it to a TTS engine, runs the resulting audio through the tts-transformer chain, and plays it through its playback queue (OVOS-AUDIO-1 §3).

The same queue also plays queued sound files (ovos.audio.queue, legacy: mycroft.audio.queue), in order with speech. ovos.audio.play_sound (legacy: mycroft.audio.play_sound) is different: it bypasses the queue and plays the file immediately, possibly over active TTS. A remote client can instead ask for the synthesized audio back over the bus (base64 in the reply, nothing played locally) via ovos.utterance.speak.b64 / ovos.audio.speech. See the JSON round trip. Separately, and only when enable_old_audioservice is on, it also hosts the legacy media audioservice for music, news, and streams. See the Two independent subsystems note at the top of this page.

Key Responsibilities

  • TTS Synthesis: Converts text to speech using various plugins.

  • Speech & Sound Playback: A single queue (TTS.queue, one PlaybackThread) plays spoken responses and queued sounds in order. Instant sounds (play_sound) bypass it.

  • Audio Focus: Prioritizes speech over music or other background sounds (ducking).

  • Viseme Generation: Provides lip-sync data for GUI animations.

  • Legacy media playback (optional, enable_old_audioservice): routes music/stream URIs to an audioservice backend. This is the deprecated path, replaced by ovos-media.

Architecture

Subsystem 1: TTS / sound playback (always on, OVOS-AUDIO-1 §3)

flowchart TD
    Bus[MessageBus] -->|"ovos.utterance.speak<br/>(legacy: speak)"| DXForm["dialog-transformers<br/>§3.5"]
    DXForm --> TTS[TTS Plugin]
    TTS --> TXForm["tts-transformers<br/>§3.6"]
    Bus -->|"ovos.audio.queue"| Queue[TTS.queue]
    TXForm --> Queue
    Queue --> Thread[PlaybackThread]
    Thread -->|ALSA/Pulse| Speakers[Speakers]
    Bus -->|"ovos.audio.play_sound<br/>(instant, may play over TTS)"| Speakers

Diagram: The flow starts at the message bus and ends at the speakers. Queued sounds (ovos.audio.queue) skip the transformers and join TTS.queue in order with speech. ovos.audio.play_sound bypasses the queue and plays immediately, possibly over active TTS.

Subsystem 2: legacy media audioservice (only if enable_old_audioservice)

flowchart LR
    Bus2[MessageBus] -->|mycroft.audio.service.play| AS[AudioService]
    AS --> Backend["audioservice backend: OCP / mpv / vlc"]

Diagram: The flow starts at the message bus and ends at the audioservice backend, and it routes the mycroft.audio.service.play event through the AudioService to one of OCP, mpv, or vlc.

Audio feedback cues (earcons)

Short status sounds are the assistant's non-verbal feedback channel, and for an eyes-free or screen-reader user they are the only status channel, standing in for whatever a sighted user would read off a display. They are configured under the top-level sounds section of mycroft.conf and delivered as instant sounds over ovos.audio.play_sound (legacy alias mycroft.audio.play_sound):

Key When it plays
sounds.start_listening The wake word was heard and recording started. Gated by the separate confirm_listening boolean — turning that off silences only this cue
sounds.end_listening Recording stopped; the utterance was captured and is on its way to STT
sounds.acknowledge A skill called self.acknowledge() to confirm a request that produces no spoken reply (also the skill installer's default success sound)
sounds.error Nothing could handle the utterance — complete intent failure (also the skill installer's default error sound)
sounds.cancel The utterance was aborted by a cancel word before matching. Unlike the four keys above, this one has no entry in the shipped mycroft.conf (so it is absent from the generated key table) — the code default snd/cancel.mp3 applies until you set it

Point any key at your own audio file to swap a cue for something more distinguishable. So "I heard the error beep" means the request reached the intent stage and nothing matched, while error beeps at install time come from the skill installer's pip_error (which defaults to the same file). See Accessibility for the eyes-free interaction picture and Bus Events Reference for the play_sound topics.

Configuration

Settings for the audio service are located in the tts and Audio sections of mycroft.conf, plus two top-level toggles (enable_old_audioservice, disable_ocp) that gate the deprecated media path. See the Two independent subsystems note above.

{
  "enable_old_audioservice": true,
  "disable_ocp": false,
  "tts": {
    "module": "ovos-tts-plugin-server",
    "ovos-tts-plugin-server": {
      "host": "https://tts.openvoiceos.pt"
    }
  },
  "Audio": {
    "default-backend": "mpv",
    "backends": {
      "mpv": {
        "type": "ovos_mpv",
        "active": true
      }
    }
  }
}


Read next: Media Service (ovos-media) · Screens on OVOS Today Related: Bus Events Reference · TTS Plugins · Speech Service · Bus Service · ovos-media Legacy Compatibility