@lovelace_lol/polymer 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +434 -12
  2. package/dist/index.d.ts +1945 -244
  3. package/dist/index.js +1686 -1017
  4. package/dist/vision/face-worker.js +296 -0
  5. package/dist/vision/face_landmarker.task +0 -0
  6. package/dist/vision/manifest.edn +1 -0
  7. package/dist/vision/vision_bundle.js +2 -0
  8. package/dist/vision/wasm/vision_wasm_internal.js +8841 -0
  9. package/dist/vision/wasm/vision_wasm_internal.wasm +0 -0
  10. package/dist/vision/wasm/vision_wasm_module_internal.js +8837 -0
  11. package/dist/vision/wasm/vision_wasm_module_internal.wasm +0 -0
  12. package/dist/vision/wasm/vision_wasm_nosimd_internal.js +8832 -0
  13. package/dist/vision/wasm/vision_wasm_nosimd_internal.wasm +0 -0
  14. package/dist/worker/agency-worker.js +1276 -962
  15. package/dist/worker/manifest.edn +1 -1
  16. package/package.json +33 -20
  17. package/dist/test.cjs +0 -1519
  18. package/shadow-cljs.edn +0 -173
  19. package/src/polymer/animation/agency.cljs +0 -84
  20. package/src/polymer/animation/domain.cljs +0 -110
  21. package/src/polymer/animation/planner.cljs +0 -88
  22. package/src/polymer/animation/runtime.cljs +0 -137
  23. package/src/polymer/animation/scheduler.cljs +0 -178
  24. package/src/polymer/animation/service.cljs +0 -981
  25. package/src/polymer/animation/state.cljs +0 -112
  26. package/src/polymer/blink/agency.cljs +0 -131
  27. package/src/polymer/blink/planner.cljs +0 -115
  28. package/src/polymer/blink/scheduler.cljs +0 -90
  29. package/src/polymer/blink/snippet.cljs +0 -50
  30. package/src/polymer/blink/state.cljs +0 -102
  31. package/src/polymer/camera_context/agency.cljs +0 -132
  32. package/src/polymer/camera_context/domain.cljs +0 -186
  33. package/src/polymer/camera_context/planner.cljs +0 -50
  34. package/src/polymer/camera_context/scheduler.cljs +0 -113
  35. package/src/polymer/camera_context/state.cljs +0 -121
  36. package/src/polymer/character.cljs +0 -403
  37. package/src/polymer/conversation/agency.cljs +0 -83
  38. package/src/polymer/conversation/domain.cljs +0 -35
  39. package/src/polymer/conversation/effector.cljs +0 -130
  40. package/src/polymer/conversation/planner.cljs +0 -178
  41. package/src/polymer/conversation/scheduler.cljs +0 -202
  42. package/src/polymer/conversation/service.cljs +0 -329
  43. package/src/polymer/conversation/state.cljs +0 -186
  44. package/src/polymer/core.cljs +0 -172
  45. package/src/polymer/eye_head/agency.cljs +0 -75
  46. package/src/polymer/eye_head/domain.cljs +0 -133
  47. package/src/polymer/eye_head/goap.cljs +0 -106
  48. package/src/polymer/eye_head/scheduler.cljs +0 -176
  49. package/src/polymer/eye_head/service.cljs +0 -259
  50. package/src/polymer/eye_head/snippet.cljs +0 -92
  51. package/src/polymer/eye_head/state.cljs +0 -167
  52. package/src/polymer/gaze/agency.cljs +0 -85
  53. package/src/polymer/gaze/domain.cljs +0 -211
  54. package/src/polymer/gaze/goap.cljs +0 -208
  55. package/src/polymer/gaze/scheduler.cljs +0 -184
  56. package/src/polymer/gaze/state.cljs +0 -202
  57. package/src/polymer/gesture/agency.cljs +0 -185
  58. package/src/polymer/gesture/goap.cljs +0 -461
  59. package/src/polymer/gesture/scheduler.cljs +0 -122
  60. package/src/polymer/gesture/snippet.cljs +0 -198
  61. package/src/polymer/gesture/state.cljs +0 -273
  62. package/src/polymer/lipsync/agency.cljs +0 -593
  63. package/src/polymer/lipsync/articulation/jaw.cljs +0 -258
  64. package/src/polymer/lipsync/articulation/snippet.cljs +0 -605
  65. package/src/polymer/lipsync/articulation/tongue.cljs +0 -418
  66. package/src/polymer/lipsync/articulation/visemes.cljs +0 -429
  67. package/src/polymer/lipsync/goap.cljs +0 -132
  68. package/src/polymer/lipsync/pronunciation/effector.cljs +0 -51
  69. package/src/polymer/lipsync/scheduler.cljs +0 -302
  70. package/src/polymer/lipsync/state.cljs +0 -202
  71. package/src/polymer/nlp/phonemes.cljs +0 -164
  72. package/src/polymer/prosodic/agency.cljs +0 -196
  73. package/src/polymer/prosodic/goap.cljs +0 -122
  74. package/src/polymer/prosodic/scheduler.cljs +0 -99
  75. package/src/polymer/prosodic/snippet.cljs +0 -106
  76. package/src/polymer/prosodic/state.cljs +0 -139
  77. package/src/polymer/runtime/embody.cljs +0 -117
  78. package/src/polymer/runtime/embody_wasm.cljs +0 -177
  79. package/src/polymer/runtime/rust_embody_host.cljs +0 -647
  80. package/src/polymer/society.cljs +0 -253
  81. package/src/polymer/stream.cljs +0 -130
  82. package/src/polymer/transcription/agency.cljs +0 -69
  83. package/src/polymer/transcription/domain.cljs +0 -68
  84. package/src/polymer/transcription/effector.cljs +0 -611
  85. package/src/polymer/transcription/planner.cljs +0 -203
  86. package/src/polymer/transcription/scheduler.cljs +0 -225
  87. package/src/polymer/transcription/service.cljs +0 -209
  88. package/src/polymer/transcription/state.cljs +0 -239
  89. package/src/polymer/tts/agency.cljs +0 -503
  90. package/src/polymer/tts/azure.cljs +0 -290
  91. package/src/polymer/tts/planner.cljs +0 -178
  92. package/src/polymer/tts/runtime.cljs +0 -624
  93. package/src/polymer/tts/scheduler.cljs +0 -162
  94. package/src/polymer/tts/state.cljs +0 -191
  95. package/src/polymer/worker.cljs +0 -81
@@ -1,418 +0,0 @@
1
- (ns polymer.lipsync.articulation.tongue
2
- (:require [clojure.string :as str]
3
- [polymer.lipsync.state :as state]
4
- [polymer.lipsync.articulation.visemes :as visemes]))
5
-
6
- ;; Tongue planning is an independent LipSync articulator beside lips and jaw.
7
- ;; The input is the same normalized phoneme/viseme timeline as the rest of
8
- ;; LipSync. The output is still ordinary typed AU channels, so Embody receives
9
- ;; the same snippet data shape as lips, jaw, blink, and future agencies.
10
-
11
- (def tongue-up-au "37")
12
- (def tongue-down-au "38")
13
- (def tongue-left-au "39")
14
- (def tongue-right-au "40")
15
- (def tongue-tilt-left-au "41")
16
- (def tongue-tilt-right-au "42")
17
- (def tongue-narrow-au "73")
18
- (def tongue-wide-au "74")
19
- (def tongue-tip-up-au "76")
20
- (def tongue-tip-down-au "77")
21
-
22
- (def tongue-au-keys
23
- ;; Keep the public list near the constants so snippet metadata and tests can
24
- ;; count tongue channels without hard-coding the planner internals.
25
- [tongue-up-au
26
- tongue-down-au
27
- tongue-left-au
28
- tongue-right-au
29
- tongue-tilt-left-au
30
- tongue-tilt-right-au
31
- tongue-narrow-au
32
- tongue-wide-au
33
- tongue-tip-up-au
34
- tongue-tip-down-au])
35
-
36
- (def tongue-au-caps
37
- ;; Per-AU caps keep the planner from over-driving optional tongue controls.
38
- ;; Tip/up cues can be more visible; width, tilt, and yaw cues stay subtle.
39
- {tongue-up-au 0.68
40
- tongue-down-au 0.48
41
- tongue-left-au 0.16
42
- tongue-right-au 0.16
43
- tongue-tilt-left-au 0.18
44
- tongue-tilt-right-au 0.18
45
- tongue-narrow-au 0.50
46
- tongue-wide-au 0.34
47
- tongue-tip-up-au 0.62
48
- tongue-tip-down-au 0.48})
49
-
50
- (def intensity-eps 0.001)
51
- (def tongue-group-gap-ms 86)
52
- (def tongue-lead-ms 36)
53
- (def tongue-release-ms 88)
54
- (def tongue-attack-ms 48)
55
- (def tongue-min-hold-ms 34)
56
-
57
- (def tongue-visemes
58
- #{(:Ch_J visemes/canonical-visemes)
59
- (:K_G_H_NG visemes/canonical-visemes)
60
- (:T_L_D_N visemes/canonical-visemes)
61
- (:Th visemes/canonical-visemes)
62
- (:R visemes/canonical-visemes)
63
- (:S_Z visemes/canonical-visemes)})
64
-
65
- (defn finite-number? [value]
66
- (and (number? value) (js/isFinite value)))
67
-
68
- (defn class-name [value]
69
- (cond
70
- (keyword? value) (name value)
71
- (string? value) (str/lower-case value)
72
- (nil? value) nil
73
- :else (str/lower-case (str value))))
74
-
75
- (defn event-classes [event]
76
- ;; Provider events sometimes arrive with only a viseme id. Fall back to the
77
- ;; canonical viseme class so Azure-style timelines and Web Speech fallback
78
- ;; timelines go through the same tongue rules.
79
- (let [from-event (into []
80
- (keep class-name)
81
- (concat (or (:phonemeClasses event) [])
82
- [(:phonemeClass event)]))
83
- fallback (into [] (keep class-name) (visemes/viseme-classes (:visemeId event)))]
84
- (set (if (seq from-event) from-event fallback))))
85
-
86
- (defn has-class? [event class]
87
- (contains? (event-classes event) class))
88
-
89
- (defn normalized-phoneme [event]
90
- (visemes/normalize-phoneme (:phoneme event)))
91
-
92
- (defn start-ms [event]
93
- (state/number-or (:offsetMs event) 0))
94
-
95
- (defn end-ms [event]
96
- (+ (start-ms event) (max 1 (state/number-or (:durationMs event) 1))))
97
-
98
- (defn excluded-lip-only? [event]
99
- ;; Bilabials and labiodentals are lip/teeth actions. Keeping them out of the
100
- ;; tongue planner prevents visible tongue motion on P/B/M/F/V closures.
101
- (or (has-class? event "pause")
102
- (has-class? event "bilabial")
103
- (has-class? event "labiodental")
104
- (has-class? event "vowel")
105
- (has-class? event "diphthong")
106
- (has-class? event "glide")))
107
-
108
- (defn clean-targets [targets]
109
- ;; Target maps are easier to reason about than a single scalar. Each phoneme
110
- ;; can request a different mix of existing Embody tongue AUs while the snippet
111
- ;; channel format stays unchanged.
112
- (into {}
113
- (keep (fn [[au target]]
114
- (let [value (state/clamp 0 1 (state/number-or target 0))]
115
- (when (> value intensity-eps)
116
- [au value]))))
117
- targets))
118
-
119
- (defn tongue-au-targets [event]
120
- ;; These values are performance cues, not phonetic simulation. The goal is to
121
- ;; distinguish dental, alveolar, velar, and sibilant gestures with the AU
122
- ;; controls Embody already exposes, while staying subtle enough for speech.
123
- (let [phoneme (normalized-phoneme event)
124
- viseme-id (:visemeId event)]
125
- (clean-targets
126
- (cond
127
- (excluded-lip-only? event) {}
128
-
129
- (contains? #{"TH" "DH"} phoneme)
130
- {tongue-up-au 0.44
131
- tongue-wide-au 0.22
132
- tongue-tip-up-au 0.58}
133
-
134
- (contains? #{"T" "D"} phoneme)
135
- {tongue-up-au 0.46
136
- tongue-tip-up-au 0.50}
137
-
138
- (= "L" phoneme)
139
- {tongue-up-au 0.48
140
- tongue-tip-up-au 0.54
141
- tongue-wide-au 0.10}
142
-
143
- (= "N" phoneme)
144
- {tongue-up-au 0.38
145
- tongue-tip-up-au 0.36}
146
-
147
- (contains? #{"K" "G" "NG"} phoneme)
148
- {tongue-down-au 0.30
149
- tongue-narrow-au 0.22
150
- tongue-tip-down-au 0.24}
151
-
152
- (contains? #{"S" "Z"} phoneme)
153
- {tongue-up-au 0.16
154
- tongue-narrow-au 0.42
155
- tongue-tip-up-au 0.22}
156
-
157
- (contains? #{"SH" "ZH"} phoneme)
158
- {tongue-down-au 0.18
159
- tongue-narrow-au 0.44
160
- tongue-tip-down-au 0.22
161
- tongue-tilt-left-au 0.08}
162
-
163
- (contains? #{"CH" "JH"} phoneme)
164
- {tongue-up-au 0.24
165
- tongue-narrow-au 0.34
166
- tongue-tip-up-au 0.28
167
- tongue-tilt-right-au 0.08}
168
-
169
- (= "R" phoneme)
170
- {tongue-narrow-au 0.18
171
- tongue-tip-down-au 0.12
172
- tongue-tilt-left-au 0.08}
173
-
174
- (= viseme-id (:Th visemes/canonical-visemes))
175
- {tongue-up-au 0.40
176
- tongue-wide-au 0.18
177
- tongue-tip-up-au 0.52}
178
-
179
- (= viseme-id (:T_L_D_N visemes/canonical-visemes))
180
- {tongue-up-au 0.42
181
- tongue-tip-up-au 0.44}
182
-
183
- (= viseme-id (:Ch_J visemes/canonical-visemes))
184
- {tongue-up-au 0.22
185
- tongue-narrow-au 0.30
186
- tongue-tip-up-au 0.24}
187
-
188
- (= viseme-id (:K_G_H_NG visemes/canonical-visemes))
189
- {tongue-down-au 0.26
190
- tongue-narrow-au 0.20
191
- tongue-tip-down-au 0.20}
192
-
193
- (= viseme-id (:S_Z visemes/canonical-visemes))
194
- {tongue-up-au 0.12
195
- tongue-narrow-au 0.36
196
- tongue-tip-up-au 0.18}
197
-
198
- (= viseme-id (:R visemes/canonical-visemes))
199
- {tongue-narrow-au 0.16
200
- tongue-tip-down-au 0.10}
201
-
202
- (has-class? event "dental")
203
- {tongue-up-au 0.40
204
- tongue-tip-up-au 0.48}
205
-
206
- (has-class? event "sibilant")
207
- {tongue-narrow-au 0.34
208
- tongue-tip-up-au 0.16}
209
-
210
- (has-class? event "tongue")
211
- {tongue-up-au 0.30
212
- tongue-tip-up-au 0.26}
213
-
214
- (has-class? event "liquid")
215
- {tongue-narrow-au 0.14
216
- tongue-tip-down-au 0.10}
217
-
218
- (contains? tongue-visemes viseme-id)
219
- {tongue-up-au 0.16}
220
-
221
- :else {}))))
222
-
223
- (defn tongue-event [event]
224
- (let [targets (tongue-au-targets event)]
225
- (when (seq targets)
226
- (assoc event :tongueTargets targets))))
227
-
228
- (defn target-active? [targets au]
229
- (> (get targets au 0) intensity-eps))
230
-
231
- (defn opposing-targets? [current next-event]
232
- ;; Do not collapse coronal and velar tongue gestures into one pose. A T/D/L/N
233
- ;; target wants tongue-up/tip-up; K/G/NG wants tongue-down/tip-down. Merging
234
- ;; those into one group drives opposing AUs at the same time and reads as a
235
- ;; snap. Compatible stacks, such as repeated sibilants, still group.
236
- (let [current-targets (:tongueTargets current)
237
- next-targets (:tongueTargets next-event)]
238
- (or (and (or (target-active? current-targets tongue-up-au)
239
- (target-active? current-targets tongue-tip-up-au))
240
- (or (target-active? next-targets tongue-down-au)
241
- (target-active? next-targets tongue-tip-down-au)))
242
- (and (or (target-active? current-targets tongue-down-au)
243
- (target-active? current-targets tongue-tip-down-au))
244
- (or (target-active? next-targets tongue-up-au)
245
- (target-active? next-targets tongue-tip-up-au))))))
246
-
247
- (defn same-tongue-group? [current next-event]
248
- (let [gap (- (start-ms next-event) (end-ms current))]
249
- (and (<= gap tongue-group-gap-ms)
250
- (>= gap (- tongue-group-gap-ms))
251
- (not (opposing-targets? current next-event)))))
252
-
253
- (defn raw-groups [events]
254
- ;; The grouping step makes the planner depend on a sequence of visemes rather
255
- ;; than individual phonemes. "texts" and "strengths" should become one coda
256
- ;; tongue gesture rather than K, T, TH, and S all firing separately.
257
- (let [ordered (->> (into [] (keep tongue-event) events)
258
- (sort-by :offsetMs)
259
- vec)]
260
- (loop [remaining ordered
261
- current []
262
- groups []]
263
- (cond
264
- (empty? remaining)
265
- (if (seq current) (conj groups current) groups)
266
-
267
- (empty? current)
268
- (recur (rest remaining) [(first remaining)] groups)
269
-
270
- (same-tongue-group? (last current) (first remaining))
271
- (recur (rest remaining) (conj current (first remaining)) groups)
272
-
273
- :else
274
- (recur (rest remaining) [(first remaining)] (conj groups current))))))
275
-
276
- (defn boosted-targets [events]
277
- ;; Clusters with several tongue consonants get a small boost, but each AU is
278
- ;; capped independently so stacked consonants do not create a stiff pose.
279
- (let [raw (reduce (fn [merged event]
280
- (merge-with max merged (:tongueTargets event)))
281
- {}
282
- events)
283
- boost (min 1.12 (+ 1 (* 0.04 (dec (count events)))))]
284
- (into {}
285
- (keep (fn [[au target]]
286
- (let [cap (get tongue-au-caps au 0.68)
287
- value (state/clamp 0 cap (* target boost))]
288
- (when (> value intensity-eps)
289
- [au value]))))
290
- raw)))
291
-
292
- (defn make-group [events]
293
- (let [start (apply min (map start-ms events))
294
- end (apply max (map end-ms events))]
295
- {:startMs start
296
- :endMs end
297
- :durationMs (max 1 (- end start))
298
- :targets (boosted-targets events)
299
- :events (vec events)}))
300
-
301
- (defn tongue-groups [events]
302
- (mapv make-group (raw-groups events)))
303
-
304
- (defn push-frame [curve time-sec intensity]
305
- (if (or (not (finite-number? time-sec))
306
- (not (finite-number? intensity)))
307
- curve
308
- (let [frame {:time (max 0 time-sec)
309
- :intensity (state/clamp 0 1 intensity)}
310
- previous (last curve)]
311
- (if (and previous (< (js/Math.abs (- (:time previous) (:time frame))) 0.001))
312
- (assoc-in curve [(dec (count curve)) :intensity] (:intensity frame))
313
- (conj curve frame)))))
314
-
315
- (defn deduplicate-curve [curve]
316
- (let [frames (vec curve)]
317
- (if (<= (count frames) 1)
318
- frames
319
- (loop [remaining (rest frames)
320
- result [(first frames)]]
321
- (if (empty? remaining)
322
- (vec result)
323
- (let [curr (first remaining)
324
- prev (last result)
325
- intensity-changed? (> (js/Math.abs (- (:intensity curr) (:intensity prev))) intensity-eps)
326
- time-changed? (> (js/Math.abs (- (:time curr) (:time prev))) 0.001)]
327
- (recur (rest remaining)
328
- (if (or intensity-changed? time-changed?)
329
- (conj result curr)
330
- result))))))))
331
-
332
- (defn scaled-target [group au scale]
333
- ;; Keep the per-AU cap after the user scale is applied. A tongueScale above
334
- ;; 1 should make tongue motion easier to see, but it should not turn subtle
335
- ;; width/tilt/yaw controls into full-strength snapped poses.
336
- (let [cap (get tongue-au-caps au 0.68)]
337
- (state/clamp 0 cap (* scale (get-in group [:targets au] 0)))))
338
-
339
- (defn build-tongue-curve-for-au [groups au tongue-scale]
340
- ;; Iterate every tongue group, including groups where this AU's target is 0.
341
- ;; That gives the planner enough context to ramp an active AU down before the
342
- ;; next opposing tongue gesture begins. Filtering to active groups only made
343
- ;; an AU release on its own stale end time, which could leave tongue-up active
344
- ;; while the next group was already driving tongue-down/narrow.
345
- (let [scale (state/clamp 0 2 (state/number-or tongue-scale 1))
346
- groups (vec groups)
347
- has-active? (some #(> (scaled-target % au scale) intensity-eps) groups)]
348
- (if (or (<= scale intensity-eps) (not has-active?))
349
- []
350
- (loop [index 0
351
- curve []]
352
- (if (>= index (count groups))
353
- (->> curve (sort-by :time) deduplicate-curve vec)
354
- (let [group (get groups index)
355
- previous (get groups (dec index))
356
- next-group (get groups (inc index))
357
- previous-target (if previous (scaled-target previous au scale) 0)
358
- next-target (if next-group (scaled-target next-group au scale) 0)
359
- start-sec (/ (max 0 (- (:startMs group) tongue-lead-ms)) 1000)
360
- group-start-sec (/ (:startMs group) 1000)
361
- end-sec (/ (+ (:endMs group) tongue-release-ms) 1000)
362
- target (scaled-target group au scale)
363
- attack-sec (/ (min tongue-attack-ms (max 24 (* (:durationMs group) 0.35))) 1000)
364
- hold-end-sec (/ (max (+ (:startMs group) tongue-min-hold-ms)
365
- (- (:endMs group) (* tongue-release-ms 0.4)))
366
- 1000)
367
- previous-end-sec (if previous (/ (:endMs previous) 1000) 0)
368
- next-start-sec (when next-group (/ (:startMs next-group) 1000))
369
- starts-after-gap? (or (nil? previous)
370
- (> (- start-sec previous-end-sec) (/ tongue-group-gap-ms 1000))
371
- (<= previous-target intensity-eps))
372
- curve-a (if (and (> target intensity-eps) starts-after-gap?)
373
- (push-frame curve start-sec 0)
374
- curve)
375
- curve-b (if (> target intensity-eps)
376
- (push-frame curve-a (+ group-start-sec attack-sec) target)
377
- (if (> previous-target intensity-eps)
378
- (push-frame curve-a group-start-sec 0)
379
- curve-a))
380
- connected? (and next-group
381
- (<= (- (:startMs next-group) (:endMs group)) tongue-group-gap-ms))
382
- release-end-sec (if (and connected?
383
- (<= next-target intensity-eps)
384
- next-start-sec)
385
- (max hold-end-sec next-start-sec)
386
- end-sec)]
387
- (recur (inc index)
388
- (cond
389
- (<= target intensity-eps)
390
- curve-b
391
-
392
- (and connected? (> next-target intensity-eps))
393
- (push-frame curve-b (max hold-end-sec
394
- (/ (- (:startMs next-group) tongue-lead-ms) 1000))
395
- target)
396
-
397
- :else
398
- (-> curve-b
399
- (push-frame hold-end-sec target)
400
- (push-frame release-end-sec 0))))))))))
401
-
402
- (defn build-tongue-curve [events tongue-scale]
403
- ;; Backward-compatible helper for tests and callers that only care about the
404
- ;; original tongue-up channel.
405
- (build-tongue-curve-for-au (tongue-groups events) tongue-up-au tongue-scale))
406
-
407
- (defn build-tongue-curves [events tongue-scale]
408
- (let [groups (tongue-groups events)
409
- active-aus (->> groups
410
- (mapcat #(keys (:targets %)))
411
- set
412
- (sort-by #(js/parseInt % 10)))]
413
- (into {}
414
- (keep (fn [au]
415
- (let [curve (build-tongue-curve-for-au groups au tongue-scale)]
416
- (when (seq curve)
417
- [au curve]))))
418
- active-aus)))