nx_coach_markers.nx source
↩ module page · 51 lines · 2631 B
1// nx_coach_markers.nx -- "MAKE THE DATA ACTIONABLE": the wire from the clip-analysis marker library (NXMK) +
2// pose posture into SFW COACHING signals the nishi coach serves. It does NOT re-derive the markers (DRY: it
3// composes ts_classify from nx_ts_marks for the content label + ms profile) -- it adds the ACTIONABLE layer the
4// coach needs: how many dead-air segments to TRIM (and exactly which spans), how many high-energy phrases to
5// PRACTICE, whether cadence (dance rhythm) is present, and a single coaching FOCUS in which an inverted body
6// posture escalates to form/safety. Pure, deterministic, gate-able; the human-readable message table stays in the
7// coach (data-driven), this returns the numeric signals. license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_ts_marks.nx"
10
11// coaching SUMMARY for one clip. out[8]: [0]=content label (ts_classify), [1]=dead-air segment COUNT (to trim),
12// [2]=dead-air total ms, [3]=high-motion segment count (phrases to practice), [4]=rhythm segment count (cadence),
13// [5]=scene-cut count, [6]=posture (0 upright/1 horizontal/2 inverted/-1 unknown), [7]=coaching FOCUS enum
14// (=label, but an inverted posture overrides to 5 = form/safety). Returns the focus.
15func coach_summary(mtype: *i64, mstart: *i64, mend: *i64, nmarks: i64, dur_ms: i64, posture: i64, out: *i64) -> i64 {
16 let prof: *i64 = sys_mmap(64) as *i64
17 ts_classify(mtype, mstart, mend, nmarks, dur_ms, prof)
18 let label: i64 = prof[4]
19 var da: i64 = 0; var mo: i64 = 0; var rh: i64 = 0
20 var i: i64 = 0
21 while i < nmarks {
22 let t: i64 = mtype[i]
23 if t == 1 { da = da + 1 }
24 if t == 3 { mo = mo + 1 }
25 if t == 4 { rh = rh + 1 }
26 i = i + 1
27 }
28 out[0] = label
29 out[1] = da
30 out[2] = prof[0] // dead-air total ms (ts_classify quiet accumulator)
31 out[3] = mo
32 out[4] = rh
33 out[5] = prof[3] // scene-cut count
34 out[6] = posture
35 var focus: i64 = label
36 if posture == 2 { focus = 5 } // inverted body -> form/safety takes coaching priority (SFW)
37 out[7] = focus
38 return focus
39}
40
41// the exact dead-air spans to TRIM: fill ts[]/te[] with the (start,end) of each type-1 marker (up to cap). Returns
42// the count. This is what lets the coach show "trim 0:12-0:18" instead of a bare number -- genuinely actionable.
43func coach_trimlist(mtype: *i64, mstart: *i64, mend: *i64, nmarks: i64, ts: *i64, te: *i64, cap: i64) -> i64 {
44 var k: i64 = 0
45 var i: i64 = 0
46 while i < nmarks {
47 if mtype[i] == 1 { if k < cap { ts[k] = mstart[i]; te[k] = mend[i]; k = k + 1 } }
48 i = i + 1
49 }
50 return k
51}