Skip to content

Sound

This page shows how to play sounds on your clock: melodies, and tracks from a DFPlayer module. It also shows how loud each kind of sound plays, and what happens when two sounds meet.

A few words this page uses:

  • Alert: a sound you ask for from outside the clock. A notification's sound and a request to /api/v1/audio/play are alerts.
  • App sound: a sound a script plays.
  • Master volume: the volume of the whole clock. Every other volume is a share of it.
  • RTTTL: a short text format for ringtones, from old mobile phones.

How it behaves

Every sound is described the same way, whether you play it with a request, over MQTT, with a notification or from a script. It plays at the master volume times the share of its group: alerts or app sounds. The clock plays one sound at a time (What plays over what). A new alert replaces the one that plays, and a script's sound never cuts an alert off. A sound plays once, unless you add "loop": true.

What your clock can play

Which sounds your clock can play depends on its hardware. The web UI shows only what your clock can play. To see it yourself, look at audio in GET /api/v1/capabilities:

{"audio":{"mp3":false,"rtttl":true,"song":false,"speech":false,"track":false,
          "radio":false,"url":false,"effect":false,"clip":false}}
Flag Your clock can
rtttl play melodies on the buzzer
track play numbered tracks from a DFPlayer module

Every flag is always there, true or false. The other flags are always false on this clock.

Play a sound

The quickest test plays three rising notes:

curl -X POST http://<awtrix-ip>/api/v1/audio/play \
  -H 'Content-Type: application/json' \
  -d '{"rtttl":"beep:d=4,o=5,b=120:c,e,g"}'

The answer is:

{"ok":true}

The body says what to play. It is called the sound, and a notification's sound takes the same value.

A stored sound is played by its name:

curl -X POST http://<awtrix-ip>/api/v1/audio/play \
  -H 'Content-Type: application/json' \
  -d '{"file":"ding"}'

A plain name in quotes is short for the same thing. "ding" and {"file":"ding"} play the same sound:

curl -X POST http://<awtrix-ip>/api/v1/audio/play \
  -H 'Content-Type: application/json' \
  -d '"ding"'

A sound has exactly one of these keys. The key says what plays:

Key Value Plays
file a stored name such as "ding" a stored melody
rtttl RTTTL text, up to 512 characters the melody in the request
track a whole number from 1 to 2999 a track from the DFPlayer

Next to the key, "loop": true repeats the sound until you stop it. See Repeat a sound.

Give the clock a choice

A sound can also be a list of 1 to 4 sounds. The clock plays the first one it can play. It skips an entry when it lacks the hardware for it, or when a file is not stored.

This notification plays track 3 on a clock with a DFPlayer, and the melody on every other clock:

curl -X POST http://<awtrix-ip>/api/v1/notifications \
  -H 'Content-Type: application/json' \
  -d '{"text":"Door","sound":[{"track":3},{"rtttl":"bell:d=4,o=5,b=100:e,c"}]}'

What the notification shows on the display

The display shows Door while the sound plays. A clock that can play none of the entries shows the notification without sound.

How a name is found

A plain name such as "ding" plays the melody /MELODIES/ding.txt.

Names are 1 to 32 characters of A-Z, a-z, 0-9, _ and -.

Melodies

A melody is a short tune in RTTTL text. You can send it with each request, or store it on the clock and play it by name. Melodies need a clock with rtttl in its capabilities.

Writing RTTTL

An RTTTL melody has three parts, separated by colons. All three are required:

name:defaults:notes
beep:d=4,o=5,b=120:c,e,g
└─┬─┘ └──────┬─────┘ └─┬─┘
name    defaults     notes
  • name: 1 to 24 characters. It is not played, but it must not be empty.
  • defaults: d is the default note length, o the default octave, b the beats per minute. Each may appear once at most, in any order, and each may be left out.
  • notes: separated by commas. Each note is an optional length, a letter a to g (p is a pause), an optional #, an optional . for a dotted note, and an optional octave. 16c6 is a 16th note C in octave 6. A note without a length or octave uses the defaults.

Allowed values:

Element Allowed If left out
d and any note's length 1, 2, 4, 8, 16, 32 d, default 4
o and any note's octave 4, 5, 6, 7 o, default 6
b 10 to 300 default 63
note letter a to g, or p for a pause

Anything else is refused, including b#, e#, a pause with # and a length such as 3. The answer names the reason and the position in the text:

curl -X POST http://<awtrix-ip>/api/v1/audio/play \
  -H 'Content-Type: application/json' \
  -d '{"rtttl":"d=4,o=5,b=120:c,e,g"}'
{"error":{"code":"validationFailed",
          "message":"missing ':' (at offset 19)",
          "field":"rtttl"}}

The status is 422.

A melody is at most 512 characters, sent in the request or stored in a file. See Limits.

Some melodies to try:

# Two-tone doorbell
curl -X POST http://<awtrix-ip>/api/v1/audio/play -H 'Content-Type: application/json' \
  -d '{"rtttl":"bell:d=4,o=5,b=100:e,c"}'

# Falling "something went wrong"
curl -X POST http://<awtrix-ip>/api/v1/audio/play -H 'Content-Type: application/json' \
  -d '{"rtttl":"lose:d=8,o=5,b=120:16c,16b,16a,4g"}'

# Jackpot fanfare
curl -X POST http://<awtrix-ip>/api/v1/audio/play -H 'Content-Type: application/json' \
  -d '{"rtttl":"jackpot:d=8,o=5,b=120:16c,16e,16g,c6,16p,16c6,16e6,4g6"}'

Store a melody

  1. Open the Audio tab and go to Melodies.
  2. Press + New melody.
  3. Enter a name and the notes, then save.

The editor checks the text while you type, plays it in your browser, and plays it on the clock when you want to hear it there. See Melodies.

Or save one with a request:

curl -X PUT http://<awtrix-ip>/api/v1/audio/melodies/doorbell \
  -H 'Content-Type: application/json' \
  -d '{"rtttl":"d=4,o=5,b=100:e,c"}'

The answer is 201 for a new melody and 200 when it replaced one. A text with a mistake answers 422.

  • The melody is stored as /MELODIES/doorbell.txt. Its name part is always the name you saved it under. Send d=4,o=5,b=100:e,c and the file holds doorbell:d=4,o=5,b=100:e,c.
  • Names are 1 to 24 characters of A-Z, a-z, 0-9, _ and -.

Play a stored melody

Use the name without .txt:

curl -X POST http://<awtrix-ip>/api/v1/audio/play \
  -H 'Content-Type: application/json' \
  -d '{"file":"doorbell"}'

If nothing is called doorbell, the answer is 404:

{"error":{"code":"notFound","message":"nothing called \"doorbell\""}}

List the stored melodies

curl http://<awtrix-ip>/api/v1/audio/melodies
{"melodies":[{"name":"doorbell","rtttl":"doorbell:d=4,o=5,b=100:e,c",
              "bytes":26,"notes":2,"durationMs":2400,"valid":true}],
 "usedBytes":41216,"totalBytes":1048576}
  • notes and durationMs tell you how long a melody is without playing it.
  • A melody with a mistake is still listed, with valid:false, error and index. So you can find and fix it in the editor.
  • usedBytes and totalBytes are for the whole storage. Melodies share it with icons, palettes and scripts.

Delete or rename a melody

curl -X DELETE http://<awtrix-ip>/api/v1/audio/melodies/doorbell

The answer is 404 notFound if there is no such melody. To rename a melody, save it under the new name and delete the old one.

Repeat a sound

Add "loop": true to a sound to repeat it until you stop it:

curl -X POST http://<awtrix-ip>/api/v1/audio/play \
  -H 'Content-Type: application/json' \
  -d '{"rtttl":"siren:d=8,o=5,b=200:c,g,c,g","loop":true}'
  • It repeats until you stop it, or until a new alert takes its place.
  • In a notification it repeats while the notification is shown. See Notifications.

Volume

The clock has one master volume and two groups. Each group is a share of the master volume:

Setting Range Default Volume of
volume 0 to 100 60 the whole clock. Every group below is a share of it
appVolume 0 to 100 100 everything a script plays
alertVolume 0 to 100 100 notification sounds and /api/v1/audio/play

What you hear is the master volume times the group's share. With volume at 50 and alertVolume at 60, an alert plays at 30.

In the web UI

  1. Open the Audio tab.
  2. Move the sliders in the Mixer section at the top: Master, Apps and Alerts.

A change applies at once, also to sounds that are playing.

With the API

curl -X PATCH http://<awtrix-ip>/api/v1/settings \
  -H 'Content-Type: application/json' \
  -d '{"volume":50,"alertVolume":60}'
  • 0 is silence. "volume": 0 silences every sound.
  • A value outside 0 to 100 is refused with 422.

All these settings: Sound settings.

What plays over what

When What happens
An alert starts A script's sounds never cut an alert off
A new alert arrives while one plays The new alert replaces the playing one
A script plays a single sound while an alert plays The script's sound is not played
A notification with loop leaves the display Its sound stops at once
A notification without loop leaves the display Its sound plays to its end

The clock plays one sound at a time.

Stop a sound

On the Audio tab, press ■ in the bar that shows what is playing. Or send:

curl -X POST http://<awtrix-ip>/api/v1/audio/stop

This stops everything. Add group to stop less:

curl -X POST http://<awtrix-ip>/api/v1/audio/stop \
  -H 'Content-Type: application/json' \
  -d '{"group":"alert"}'
group Stops
alert the alert that is playing
app every sound a script plays

Any other value answers 422, must be alert, app or radio.

Over MQTT

The same sound goes to <prefix>/cmd/audio/play:

mosquitto_pub -h <broker> -t 'awtrixNG/cmd/audio/play' -m '{"file":"ding"}'
mosquitto_pub -h <broker> -t 'awtrixNG/cmd/audio/stop' -m '{"group":"alert"}'
  • An empty payload on cmd/audio/stop stops everything.
  • Errors come back on <prefix>/cmd/audio/play/result as {"ok":false,"error":{…}}.
  • <prefix>/state/audio shows what is playing. It is kept by the broker, and it is sent again on every change.
  • Storing and listing melodies works over HTTP only.

See Command topics.

DFPlayer tracks

A converted AWTRIX 2 mainboard can drive a DFPlayer Mini MP3 module. AWTRIX uses it when the DFPlayer switch under System → Audio is on and both DFPlayer pins are set. The buzzer keeps working next to it. See Sound hardware and The pin map.

A DFPlayer plays numbered files from its own SD card:

curl -X POST http://<awtrix-ip>/api/v1/audio/play \
  -H 'Content-Type: application/json' \
  -d '{"track":3}'
  • A number outside 1 to 2999 answers 422 validationFailed.
  • A track plays at the volume of its group, like every other sound.

The buzzer

The buzzer plays melodies only. To silence it for good, set pinBuzzer to -1 in the pin map.

When it goes wrong

What you see Why
422 validationFailed the sound has a mistake, for example two keys, a name with .mp3 or .txt, or a melody that cannot be read, or a track out of range. field names the key
404 notFound, nothing called "x" no melody has that name. Check the spelling
503 unavailable your clock cannot play this kind of sound, for example a melody without a buzzer. For a list, the clock can play none of its entries
200, but no sound the master volume or the group's volume is 0, a script's sound met a playing alert, or the DFPlayer track is not on the card

Every status code and message: Audio playback errors.

Good to know

  • An rtttl without a name in front is refused with 422. Write any name and a colon before the defaults: beep:d=4,o=5,b=120:c,e,g. Only a stored melody may leave the name out.
  • A stored sound is played by its name alone. {"file":"ding.txt"} is refused with 422, invalid name. Send {"file":"ding"}.
  • AWTRIX cannot see what is on the DFPlayer's card. A track that is not there answers 200 and plays nothing. Check the numbers of the files on the card.

Details