nx_g2p_gate.nx source
↩ module page · 116 lines · 4986 B
1// nx_g2p_gate.nx -- REFEREE for the text->phoneme front-end (nx_g2p).
2//
3// MAPPING: words map to the expected phoneme-id sequence (incl. digraphs):
4// "cat"->[K,AE,T] "see"->[S,IY] "moon"->[M,UW,N] "ship"->[SH,IH,P]
5// "the"->[TH,EH] "rock"->[R,AA,K]
6// INVENTORY: voiced flags correct (vowels/nasals voiced; fricatives/stops not).
7// DETERMINISM: same text -> same sequence.
8// END-TO-END: g2p("see") -> records -> nx_voice_read -> the S segment reads
9// UNVOICED (hiss) and the IY segment reads VOICED (tone) ==> text became
10// speech with correct voicing.
11//
12// Evidence -> stdout + knowledge/status/g2p_gate.log. Exit 0 GREEN / 1 RED.
13// Sovereign x86_64 throughout. license_tier: ORIGINAL
14import "nx_syscalls_x86_64.nx"
15import "nx_g2p.nx"
16import "nx_voice_read.nx"
17import "nx_voiceprint.nx"
18
19func gp(logfd: i64, s: *u8) -> i64 {
20 var n: i64 = 0
21 while s[n] != (0 as u8) { n = n + 1 }
22 sys_write(1, s, n)
23 if logfd > 0 { sys_write(logfd, s, n) }
24 return 0
25}
26func gn(logfd: i64, v: i64) -> i64 {
27 let bb: *u8 = sys_mmap(28)
28 var m: i64 = v
29 if m < 0 { sys_write(1, "-\x00" as *u8, 1); if logfd > 0 { sys_write(logfd, "-\x00" as *u8, 1) } m = 0 - m }
30 let t: *u8 = sys_mmap(28)
31 var k: i64 = 0
32 if m == 0 { t[0] = 48 as u8; k = 1 }
33 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
34 var i: i64 = 0
35 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
36 sys_write(1, bb, k)
37 if logfd > 0 { sys_write(logfd, bb, k) }
38 return 0
39}
40func slen(s: *u8) -> i64 {
41 var n: i64 = 0
42 while s[n] != (0 as u8) { n = n + 1 }
43 return n
44}
45// map one word; print; return 1 if it matches expected [e0,e1,e2] (ne ids)
46func chk(logfd: i64, text: *u8, e0: i64, e1: i64, e2: i64, ne: i64, ids: *i64) -> i64 {
47 let cnt: i64 = nx_g2p(text, slen(text), ids, 16)
48 gp(logfd, " \x00" as *u8); gp(logfd, text)
49 gp(logfd, " -> [\x00" as *u8)
50 var i: i64 = 0
51 while i < cnt { gn(logfd, ids[i]); gp(logfd, " \x00" as *u8); i = i + 1 }
52 gp(logfd, "]\n\x00" as *u8)
53 if cnt != ne { return 0 }
54 if ne >= 1 { if ids[0] != e0 { return 0 } }
55 if ne >= 2 { if ids[1] != e1 { return 0 } }
56 if ne >= 3 { if ids[2] != e2 { return 0 } }
57 return 1
58}
59
60func main() -> i64 {
61 let logfd: i64 = sys_openat_append("knowledge/status/g2p_gate.log\x00" as *u8, 0x1a4)
62 gp(logfd, "G2P-GATE (text -> phoneme)\n\x00" as *u8)
63
64 let ids: *i64 = sys_mmap(16 * 8) as *i64
65 var ok: i64 = 1
66
67 if chk(logfd, "cat\x00" as *u8, PH_K, PH_AE, PH_T, 3, ids) == 0 { ok = 0 }
68 if chk(logfd, "see\x00" as *u8, PH_S, PH_IY, 0, 2, ids) == 0 { ok = 0 }
69 if chk(logfd, "moon\x00" as *u8, PH_M, PH_UW, PH_N, 3, ids) == 0 { ok = 0 }
70 if chk(logfd, "ship\x00" as *u8, PH_SH, PH_IH, PH_P, 3, ids) == 0 { ok = 0 }
71 if chk(logfd, "the\x00" as *u8, PH_TH, PH_EH, 0, 2, ids) == 0 { ok = 0 }
72 if chk(logfd, "rock\x00" as *u8, PH_R, PH_AA, PH_K, 3, ids) == 0 { ok = 0 }
73
74 // inventory voiced flags
75 let rec: *i64 = sys_mmap(8 * 8) as *i64
76 nx_g2p_phoneme(PH_IY, rec); if rec[3] != 1 { ok = 0 } // vowel voiced
77 nx_g2p_phoneme(PH_M, rec); if rec[3] != 1 { ok = 0 } // nasal voiced
78 nx_g2p_phoneme(PH_S, rec); if rec[3] != 0 { ok = 0 } // fricative unvoiced
79 nx_g2p_phoneme(PH_T, rec); if rec[3] != 0 { ok = 0 } // stop unvoiced
80
81 // determinism
82 let ids2: *i64 = sys_mmap(16 * 8) as *i64
83 let c1: i64 = nx_g2p("cat\x00" as *u8, 3, ids, 16)
84 let c2: i64 = nx_g2p("cat\x00" as *u8, 3, ids2, 16)
85 if c1 != c2 { ok = 0 }
86 var di: i64 = 0
87 while di < c1 { if ids[di] != ids2[di] { ok = 0 } di = di + 1 }
88
89 // END-TO-END: "see" -> records -> nx_voice_read -> S unvoiced, IY voiced
90 let n: i64 = nx_g2p("see\x00" as *u8, 3, ids, 16)
91 let recs: *i64 = sys_mmap(2 * PH_REC * 8) as *i64
92 nx_g2p_phoneme(ids[0], (recs as i64) as *i64)
93 nx_g2p_phoneme(ids[1], (recs as i64 + PH_REC * 8) as *i64)
94 let buf: *u8 = sys_mmap(4096 * 2)
95 nx_voice_read(recs, 2, 120, 100, 100, buf, 4096)
96 let s_dur: i64 = recs[4] // S duration (samples)
97 let vpS: *i64 = sys_mmap(VP_WORDS * 8) as *i64
98 let vpI: *i64 = sys_mmap(VP_WORDS * 8) as *i64
99 nx_voiceprint_extract((buf as i64) as *u8, 460, vpS) // S region
100 nx_voiceprint_extract((buf as i64 + (s_dur + 150) * 2) as *u8, 900, vpI) // IY region
101 gp(logfd, " e2e see: S voiced-frames=\x00" as *u8); gn(logfd, vpS[0])
102 gp(logfd, " IY voiced-frames=\x00" as *u8); gn(logfd, vpI[0]); gp(logfd, "\n\x00" as *u8)
103 if vpS[0] != 0 { ok = 0 } // S must be unvoiced
104 if vpI[0] < 1 { ok = 0 } // IY must be voiced
105
106 if ok == 1 {
107 gp(logfd, "G2P-GATE result=ALL-PASS verdict=GREEN\n\x00" as *u8)
108 if logfd > 0 { sys_close(logfd) }
109 sys_exit(0)
110 return 0
111 }
112 gp(logfd, "G2P-GATE result=FAIL verdict=RED\n\x00" as *u8)
113 if logfd > 0 { sys_close(logfd) }
114 sys_exit(1)
115 return 1
116}