Approved gong voicing: 220Hz fundamental, fatter mids, -7dBFS at vol 75
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:
@@ -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 10–25 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user