Approved gong voicing: 220Hz fundamental, fatter mids, -7dBFS at vol 75
Test, Build and Push / test-gateway (push) Successful in 11s
Test, Build and Push / release (push) Skipped
Test, Build and Push / build-gateway (push) Skipped

User verdict: audible and butler-non-intrusive on the bare 2W speaker.
Recorded as the house sound signature in architecture.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 20:44:30 +02:00
co-authored by Claude Fable 5
parent bfe792f006
commit ae9f6e0abb
2 changed files with 14 additions and 8 deletions
+6
View File
@@ -144,6 +144,12 @@ ported to LVGL. The `STATES` table in the sim defines the contract:
| `rage` | — | — | 34 fast streams | 3-frame kaomoji loop through the eyes slot: `(°□°) ┬─┬``(╯°□°)╯︵ ┻━┻``┬─┬ ( º_º )` — flips the table, then composes itself and puts it back |
| `error` | `x x` | `-` | none (rain dies) | face dims to 45% |
**Sound signature**: the cathedral gong (`play_boot_gong` in firmware — 220 Hz
inharmonic partial stack, feedback-comb reflections, ~-7 dBFS) is the approved house
sound: "audible and butler-non-intrusive." Plays at boot; planned as the
wake-from-`dormant` sound. Tune by adjective: tail = `tau`s, cathedral size = echo
delays, depth = fundamental, presence = `GONG_PEAK`/`GONG_VOLUME`.
**Wait cues are a hard requirement** (user-stated): Tatlock turns take 1025 s, so
`effort` must always show *alive-and-working* signals — the orbiting bezel arc, the
elapsed-seconds counter, and max rain. Never a bare static face during a wait, and no
+8 -8
View File
@@ -23,15 +23,15 @@ static const char *TAG = "desklock";
#define GONG_RATE 16000
#define GONG_SECONDS 5
#define GONG_SAMPLES (GONG_RATE * GONG_SECONDS)
#define GONG_VOLUME 58 /* codec volume: discreet, not loud */
#define GONG_PEAK 8000.0f /* ~-12 dBFS headroom */
#define GONG_VOLUME 75 /* codec volume: discreet, not loud */
#define GONG_PEAK 14000.0f /* ~-7 dBFS headroom */
/* A distant temple gong in a stone space.
*
* Inharmonic partials with per-partial decay (lows ring for seconds, highs
* die fast), a detuned fundamental pair for slow shimmer, a soft 45 ms
* attack so the strike reads as far away, and three early reflections that
* stand in for cathedral walls. Fundamental sits at 165 Hz — low enough to
* stand in for cathedral walls. Fundamental sits at 220 Hz — low enough to
* feel voluminous, high enough for the bare 2 W speaker to reproduce.
*/
static const struct {
@@ -39,11 +39,11 @@ static const struct {
float amp;
float tau; /* seconds to 1/e */
} gong_partials[] = {
{ 1.000f, 0.34f, 2.6f },
{ 1.000f, 0.30f, 2.6f },
{ 1.004f, 0.22f, 2.2f }, /* beating partner -> shimmer */
{ 1.590f, 0.16f, 1.4f },
{ 2.140f, 0.11f, 0.9f },
{ 2.760f, 0.08f, 0.55f },
{ 1.590f, 0.22f, 1.4f },
{ 2.140f, 0.16f, 0.9f },
{ 2.760f, 0.10f, 0.55f },
{ 3.570f, 0.05f, 0.35f },
{ 4.800f, 0.03f, 0.22f },
};
@@ -76,7 +76,7 @@ static void play_boot_gong(void)
}
for (size_t p = 0; p < sizeof(gong_partials) / sizeof(gong_partials[0]); p++) {
float step = 2.0f * (float)M_PI * 165.0f * gong_partials[p].ratio / GONG_RATE;
float step = 2.0f * (float)M_PI * 220.0f * gong_partials[p].ratio / GONG_RATE;
float decay = expf(-1.0f / (gong_partials[p].tau * GONG_RATE));
float env = gong_partials[p].amp;
float phase = 0.0f;