Jingles
Jingles are short audio clips that play over regular audio with automatic volume ducking.
How It Works
Section titled “How It Works”When a jingle plays:
- The target player or zone volume is reduced (ducked)
- The jingle audio plays through the target
- When the jingle ends, the original volume fades back up
Fade-in and fade-out transitions are configurable.
Ducking lowers each source relative to its current volume, so a source that is already muted stays silent for the duration of the jingle — playing a jingle never makes a muted player audible. Sources at full volume duck to the configured duck level as usual.
Targets
Section titled “Targets”Jingles can target:
- Specific players — Duck and overlay on selected players
- Specific zones — Duck and overlay on selected zones
Switching between Players and Zones clears the checkboxes: a jingle remembers one target list on one side, not both at once.
Saving a target selection
Section titled “Saving a target selection”The target list has a Save button next to Play/Stop. It lights up as soon as your selection differs from what the jingle has stored, and a short note above the list points out that targets are remembered only once saved. When there is nothing pending the button reads Saved, so the panel always shows whether the current selection is stored.
Previously a selection only stuck if you pressed Play — targets were recorded as a side effect of playback, so a jingle you configured and left alone lost its targets, and reopening it showed whatever it had last been played on.
- Playing a jingle still records its targets, exactly as before.
- Saving targets is admin-only, matching the rest of jingle editing.
PUT /api/jingles/{id} accepts two optional fields, targetType ("Players" or "Zones") and targetIds (an array of GUIDs). Send them together. An empty targetIds clears the stored selection, omitting them leaves it untouched, and an unrecognized targetType returns 400.
Duck level
Section titled “Duck level”The jingle Duck slider shows both units, e.g. 10% · -20.0 dB.
The percentage is a linear gain multiplier, not a fader position — so "10%" actually means −20 dB, noticeably quieter than the label alone suggests, because perceived loudness roughly halves every −10 dB. Every other level control in MZAP is a −40…0 dB fader, so the dB reading makes the real attenuation explicit.
| Slider | Attenuation |
|---|---|
| 5% | −26 dB |
| 10% | −20 dB |
| 20% | −14 dB |
| 50% | −6 dB |
| 60% | −4.4 dB |
| 100% | 0 dB (no ducking) |
Existing jingles are unaffected and keep their saved duck levels — this is a labelling change only.
The Ducked marker
Section titled “The Ducked marker”A player currently being attenuated carries a Ducked badge on its card, next to the volume row. It appears for both causes:
- A live microphone ducking other players.
- A jingle ducking its targets — which matters most for scheduled adverts in retail, where the music drops with no operator action and nothing else on screen would explain why.
The badge's tooltip names the cause, e.g. "Ducked by: Summer Sale", and lists all of them when a microphone and a jingle overlap.
Ducking never moves a player's own volume fader, so the fader position and what you hear cannot silently disagree — the badge is what tells you the difference.
Microphone auto-ducking
Section titled “Microphone auto-ducking”An Input (microphone) player can automatically lower the volume of other players while it is live, and restore them when it stops — so announcements over background music need no operator at the faders.
Configure it per microphone in the player detail view under Reduce other players while live, with a duck level and a fade duration. The controls appear only for Input players. There is also a Duck toggle on the player card in the Players list.
Defaults are a duck level of 0.2 (−14 dB) and a 500 ms fade. The −14 dB default sits in the middle of the −12…−20 dB range broadcast practice uses for speech over a music bed: the music stays audible underneath while speech reads clearly above it. Louder venues may prefer 10% (−20 dB).
On by default for microphones you add
Section titled “On by default for microphones you add”Creating an Input player enables ducking straight away, since announcing over background music is the usual reason to add one. Two deliberate exceptions:
- Input players MZAP creates automatically when it enumerates your audio hardware are left off. A machine with several interfaces can produce dozens of these, and they represent available inputs rather than microphones you chose to use.
- Loopback and per-application capture players are never ducking sources — they carry content, not voice.
Existing microphones keep whatever setting they already had; nothing changes on upgrade.
What gets ducked
Section titled “What gets ducked”- Every other player routed to a zone the microphone also feeds. A player audible in two zones is attenuated only in the shared one.
- Loopback and per-application capture players are ducked — they carry content, such as Spotify.
- Other microphones are not ducked, so two live mics never attenuate each other.
Behavior notes
Section titled “Behavior notes”- Ducking is released on any stop — including pause, and an input device failing or being unplugged, not just an explicit Stop.
- A player routed into a live microphone's zone is attenuated immediately.
- If a jingle and a microphone duck the same player at once, the result is the stronger of the two, not both multiplied together.
- Settings are saved in the workspace and restored with it.
PUT /api/players/{id}/ducking takes { autoDuckOthers: bool, duckLevel?: 0..1, duckFadeMs?: int } and returns 400 for non-Input players or out-of-range values. The player response gains autoDuckOthers, duckLevel, and duckFadeMs.
The SSE stream emits DuckingChangedEvent, carrying the source (microphone or jingle), its name, a cause of Microphone or Jingle, the ducked player IDs, the affected zones, and the applied level.
Text-to-speech (TTS) jingles
Section titled “Text-to-speech (TTS) jingles”Instead of supplying a pre-recorded audio file, you can create a jingle by typing text. MZAP synthesizes the speech to an audio file, and from that point on the TTS jingle behaves exactly like a file-based jingle — it plays through the same ducking pipeline, can be scheduled by a JinglePlay action, and appears in the jingle list (with a speech-bubble icon and the spoken text in its subtitle).
Creating a TTS jingle
Section titled “Creating a TTS jingle”- On the Jingles tab, click TTS.
- In the modal, set a name, pick a provider and voice, type the text, and adjust the speaking-rate slider.
- Click Preview to hear the voice before saving.
- Save. The jingle is created from the audio you previewed.
Editing a TTS jingle's text, voice, or rate re-synthesizes the audio automatically. Cosmetic edits (volume, duck level, fade) skip re-synthesis.
Text is capped at a 5000-character soft limit (about six minutes of speech) on every synthesis entry point.
The preview is what you save
Section titled “The preview is what you save”Saving reuses the exact audio you previewed. Cloud engines do not generate identical audio twice — the same text, voice, and rate can come back with noticeably different pacing — so a preview-then-save that synthesized twice could produce a jingle that did not sound like what you approved.
If you change the text, voice, provider, or speaking rate after previewing, the jingle is re-synthesized, so you never save audio that no longer matches the settings on screen.
This also halves the characters billed by your cloud provider per jingle.
Speaking rate is limited per provider
Section titled “Speaking rate is limited per provider”The rate slider shows each provider's real range, so the displayed rate is always the rate you hear:
| Provider | Rate range |
|---|---|
| Windows | 0.5× – 2.0× |
| Azure Speech | 0.5× – 2.0× |
| ElevenLabs | 0.7× – 1.2× |
ElevenLabs silently clamps anything outside its range. Previously the slider offered 0.5×–2.0× for every provider, so a jingle could play at 1.2× while the UI still read "2.00×".
Existing jingles saved with an out-of-range rate keep their audio — re-save one to bring its stored rate in line with what it actually plays at.
Switching provider in the dialog clears the previous provider's voice rather than leaving it selected, and Preview and Save are disabled while the new provider's voices load.
Providers
Section titled “Providers”| Provider | Type | Setup | License |
|---|---|---|---|
| Windows | Offline | None — uses the voices installed on the host machine | Included |
| Azure Speech | Cloud | Your own Azure key + region | Cloud TTS feature |
| ElevenLabs | Cloud | Your own ElevenLabs key (no region) | Cloud TTS feature |
The Windows provider works offline and free, using the voices installed via Windows Settings → Time & language → Speech. The two cloud providers — Azure Speech (~140 neural voices across 90+ languages) and ElevenLabs (premium multilingual voices) — require the Cloud TTS license feature and an API key you supply yourself. See Settings — Text-to-speech for the step-by-step key setup.
Cloud-provider voices are multilingual or grouped by language, and failed synthesis (invalid key, region typo, quota error) is reported inline in the modal — no jingle is created if synthesis fails.
The license is checked before synthesis is attempted, so creating or editing a cloud TTS jingle without the Cloud TTS feature returns a clear "not permitted" response rather than a generic "TTS synthesis failed" carrying a raw underlying error. Windows text-to-speech is unaffected — it is offline and free, and was never gated.
When a connection test fails
Section titled “When a connection test fails”Settings → Text to Speech → Test connection now shows the provider's own explanation instead of a blanket "Connection failed. Check the credentials." That distinguishes:
- A rejected key from a valid key missing a permission scope — ElevenLabs keys need
voices_readto list voices andtext_to_speechto generate audio. - A quota or rate limit.
- A wrong Azure region.
- A network or DNS failure.
A Check the setup steps link appears directly under a failed test, alongside the How to get a key links described in Settings → Text-to-speech.
Use Cases
Section titled “Use Cases”- Store announcements over background music
- Time signals or alerts
- Scheduled welcome messages
- DJ drops and station IDs
- Spoken closing-time or safety announcements via TTS