Skip to content
Merged
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
1 change: 1 addition & 0 deletions lampOS/crates/skills/tests/skills.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ fn every_skill_folder_says_its_kind_and_version() {
"light-out",
"light-scenes",
"light-show",
"music-sway",
"not-feeling-well",
"point-light",
"reminders",
Expand Down
6 changes: 6 additions & 0 deletions lampOS/crates/update/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ pub const NOT_PRODUCT_SKILLS: &[(&str, &str)] = &[
until its scores are measured in an empty room and a busy one: a glance at every loud \
voice would read as a machine",
),
(
"music-sway",
"it reads `ears/classes`, which lamp-ears says only with `LAMP_EARS_CLASSES=on` (#1669), off \
until its scores are measured in an empty room and a busy one: a sway at people's talk \
would read as a machine",
),
(
"not-feeling-well",
"not yet tried on a lamp (#1681): whether its droop and dim on `lamp/health`'s `error` \
Expand Down
2 changes: 1 addition & 1 deletion lampOS/docs/creature.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ is released or the reader has failed.
| You talk over it | Stops and listens | Now for sentences (6 of 10 played), weak for one word; tonight's work |
| Two people talk near it | Stays out; a glance now and then at whoever laughs | Now (stays out); the glance built, off: `skills/laugh-glance` on `ears/classes` (#1669), not tried on a lamp |
| A bang, something dropped | One startled glance, then lets it go; the next ones get nothing | Now when awake; resting #710 |
| Music | A slight sway in time while it plays, only if it is not working with you | To build |
| Music | Once, a slight sway when music has played a while, only if it is not working with you | Built, off: `skills/music-sway` on `ears/classes` (#1669), not tried on a lamp |
| A long silence | Breathing eye, tiny shifts of weight; dozes after a while | Rest clip now; sleep to build |

### Sight
Expand Down
4 changes: 4 additions & 0 deletions lampOS/docs/sound-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ lamp playback, music with vocals, instrumental music and laughter as separate
labelled conditions. Training/calibration and held-out evaluation recordings
must not overlap. A zero observation duration is unmeasured, not zero false rate.

The first of them, the music sway, is built and held out of the product
(`skills/music-sway`, `install::NOT_PRODUCT_SKILLS`); it reads
`scores.music` and does nothing without this topic.

Only after this evidence do the three `kind = "core"` skills use the topic:
a small rare music sway, a glance at laughter, and following a departing person
with Nine's presence contract (#1677). None acts over the lamp's speech or a
Expand Down
25 changes: 25 additions & 0 deletions lampOS/skills/music-sway/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: music-sway
description: When music has been playing in the room for a while, the lamp sways its head a little from side to side, once, like someone enjoying the song; never while it is speaking or listening, never at night, and at most twice an hour.
---

# Music sway

When music has been playing in the room for about twenty seconds, the lamp
sways its head a little from side to side, about six seconds, as someone
enjoying the song would. Then it keeps still: once for a piece of music, and
again only after five minutes without music, and never more than twice an
hour, whatever plays.

It never sways while it is speaking, listening or thinking, nor with a hand
on it, and keeps still
at night (23:00 to 06:00, the lamp's local time). A short clip (a ringtone, a
video) is not music that goes on, and a quiet bar does not end it.

It hears music by the ears' room sound scores (`ears/classes`, with
`LAMP_EARS_CLASSES=on` in lamp-ears): a score from 0 to 1 the lamp works out
on the lamp itself, from the room microphone, keeping no sound. Without them
it does nothing.

If asked about it: "When there's music on, I sometimes sway along a little.
It's the music, not you; I'll stop if you'd rather."
1 change: 1 addition & 0 deletions lampOS/skills/music-sway/moves/sway.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "sway", "step_ms": 500, "frames": [[0, 0, 0, 0, 0], [0, 20, 6, 0, 0], [0, 35, 10, 0, 0], [0, 20, 6, 0, 0], [0, 0, 0, 0, 0], [0, -20, -6, 0, 0], [0, -35, -10, 0, 0], [0, -20, -6, 0, 0], [0, 0, 0, 0, 0], [0, 20, 6, 0, 0], [0, 35, 10, 0, 0], [0, 20, 6, 0, 0], [0, 0, 0, 0, 0]]}
48 changes: 48 additions & 0 deletions lampOS/skills/music-sway/skill.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Music sway (#1669, the owner, 19 Oct 07:2x: "a small sway while music
# plays ... rare and small, and never while the lamp is speaking or someone
# is talking to it"; docs/creature.md, Joys). It reads ears/classes
# (LAMP_EARS_CLASSES=on in lamp-ears) and sways its head a little, once,
# when music has played in the room for a while. Written to lamp-skills'
# schema (docs/skills.md).
needs = ["ears", "body"]
# A core skill (docs/skills.md, "Core and installable skills"), held out of
# the product's install until its lamp check (install::NOT_PRODUCT_SKILLS).
# Without the ears' classes it does nothing.
kind = "core"
version = "1.0.0"

# What it may read and use, and nothing more: the room's sound scores, the
# voice's state, and the body. It never speaks or lights.
[permissions]
topics = ["ears/classes", "voice/state", "body/hand"]
body = true

[trigger]
topic = "ears/classes"
field = "scores.music" # YAMNet's music score, 0 to 1; an unavailable message has none and never holds
above = 0.6 # provisional: no threshold is measured yet (sound-events.md); the lamp check sets it
for = "20s" # music that goes on, not a ringtone or a clip from a video
gap = "5s" # a quiet bar or a missed score does not end the music
rearm = { below = 0.3, for = "5m" } # once a piece of music; again only after five minutes without it
cooldown = "30m" # rare: at most twice an hour, whatever plays

[[while]] # no hand on the lamp: never while someone adjusts the head (the reviewer on #1927)
topic = "body/hand"
field = "pushed"
equals = false
unknown = "holds" # a body that says nothing of hands still drops a move under one

[[while]] # never in the middle of a turn: not while it speaks, listens or thinks
topic = "voice/state"
field = "state"
equals = "resting"

[quiet] # not at night: the night is the lamp's sleep (Expression's 23:00 to 06:00)
from = "23:00"
to = "06:00"

[ask]
policy = "nudge"

[[do]]
body = { move = "sway" }
25 changes: 25 additions & 0 deletions lampOS/skills/music-sway/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Music sway's tests

**How they were made.** Not on a lamp: no lamp publishes `ears/classes` yet
(#1923). Each case's `.jsonl` files were written by a script in the format
`lamp-bus record` writes: `ears/classes` every 500 ms, each message good for
1.5 s (`expires_ms`), as lamp-ears says it with `LAMP_EARS_CLASSES=on`
(`crates/ears/src/classes.rs`), with a music score of 0.85 while music plays
and 0.05 otherwise; and `voice/state`, kept until replaced. Each
`expect.toml` sets the local time of the case's first message (`clock`).
Re-recording a case on a lamp, with its owner's yes, replaces the written one.

**Run** with `lamp-skills test lampOS/skills/music-sway` (or `cargo test -p
lamp-skills`, which runs every skill's cases).

| Case | What it holds | Result (lamp-skills, #1669) |
|---|---|---|
| `sways-once-after-twenty-seconds-of-music` | From 10:00, music for five minutes, then quiet | Pass: one sway at 20 s, none again while the same music goes on |
| `a-quiet-bar-does-not-end-the-music` | Music with three quiet seconds at 10 s | Pass: still one sway at 20 s (`gap = "5s"`) |
| `not-for-a-short-clip` | Ten seconds of music | Pass: nothing |
| `never-while-the-lamp-speaks` | Five minutes of music while the lamp speaks | Pass: nothing |
| `never-at-night` | From 23:30, five minutes of music | Pass: nothing |
| `never-with-a-hand-on-it` | Five minutes of music, a hand on the lamp from 5 s | Pass: nothing |

The threshold (0.6) is provisional: no score is measured on a lamp yet
(`docs/sound-events.md`). How the sway looks is for the lamp check.
Loading
Loading