// accent.el - A British-RP ACCENT as an INGESTED TRANSFORM-GEOMETRY, composed // onto the voice (voice (+) accent, SEPARABLE). Reads elp/data/british-accent.psv // into an accent MANIFOLD in the engram (override nodes + a shared accent hub), // and the render reads the RP formant overrides + the non-rhotic rule back from // that geometry. NO accent targets live in code — same discipline as the base // phonetics. PROVENANCE NOTE: the RP Hz values are PROVISIONAL (reconstructed- // from-knowledge approximations, cite Deterding1997 / Hawkins&Midgley2005 / // Wells1982) pending transcription from the published tables — the PIPELINE is // the deliverable; exact values are being source-verified separately. fn ingest_accent(path: String) -> [String] { let content: String = fs_read(path) let lines: [String] = str_split(content, "\n") let nl: Int = native_list_len(lines) let amap: [String] = native_list_empty() let hub: String = engram_node("accent british-rp prov=PROVISIONAL cite=Deterding1997-HawkinsMidgley2005-Wells1982", "Accent", 80) let li: Int = 0 while li < nl { let line: String = native_list_get(lines, li) let ll: Int = str_len(line) let skip: Int = 0 if ll < 3 { skip = 1 } if skip == 0 { let first: Int = str_char_code(line, 0) if first == 35 { skip = 1 } } if skip == 0 { let f: [String] = str_split(line, "|") let nf: Int = native_list_len(f) if nf >= 6 { let key: String = native_list_get(f, 0) let f1: String = native_list_get(f, 1) let f2: String = native_list_get(f, 2) let f3: String = native_list_get(f, 3) let kind: String = native_list_get(f, 4) let set: String = native_list_get(f, 5) let cont: String = "accent british-rp " + key + " f1=" + f1 + " f2=" + f2 + " f3=" + f3 + " kind=" + kind + " set=" + set + " prov=PROVISIONAL cite=Deterding1997-HawkinsMidgley2005-Wells1982" let id: String = engram_node(cont, "AccentTarget", 80) amap = native_list_append(amap, key) amap = native_list_append(amap, cont) engram_connect(id, hub, 80, "of_accent") } } li = li + 1 } return amap } // RP formant override for a phoneme, read from the accent manifold. Returns // [f1,f2,f3] for a vowel_override record, or an empty list if none / a rule. fn accent_formants(amap: [String], code: String) -> [Int] { let out: [Int] = native_list_empty() let id: String = sp_map_get(amap, code) if str_eq(id, "") { return out } let j: String = id let isrule: Int = str_index_of(j, "drop_coda") if isrule >= 0 { return out } let f1: Int = parse_uint_from(j, "f1=") if f1 <= 0 { return out } let out = native_list_append(out, f1) let out = native_list_append(out, parse_uint_from(j, "f2=")) let out = native_list_append(out, parse_uint_from(j, "f3=")) return out } // Is this accent non-rhotic? (reads the R rule node from the manifold) fn is_nonrhotic(amap: [String]) -> Int { let id: String = sp_map_get(amap, "R") if str_eq(id, "") { return 0 } let hit: Int = str_index_of(id, "drop_coda") if hit >= 0 { return 1 } return 0 } // Is this symbol a vowel? Membership in the vowel-set derived from the phonetics // source's class column (phonological structure — the FORMANT NUMBERS still come // from the organ manifold; this is only the categorical class for the rule). fn is_vowel_sym(vset: [String], sym: String) -> Int { let n: Int = native_list_len(vset) let i: Int = 0 while i < n { if str_eq(native_list_get(vset, i), sym) { return 1 } i = i + 1 } return 0 } // Non-rhotic transform: drop a post-vocalic CODA /R/ — an R whose next non-SIL // phoneme is NOT a vowel (a consonant, or end of utterance). Keep INTERVOCALIC/ // onset R (next non-SIL phoneme is a vowel, e.g. the medial R in N UW R AA N). fn apply_rhoticity(codes: [String], vset: [String]) -> [String] { let n: Int = native_list_len(codes) let out: [String] = native_list_empty() let i: Int = 0 while i < n { let c: String = native_list_get(codes, i) let keep: Int = 1 if str_eq(c, "R") { let jx: Int = i + 1 let nextv: Int = 0 while jx < n { let ncode: String = native_list_get(codes, jx) if str_eq(ncode, "SIL") { jx = jx + 1 } else { nextv = is_vowel_sym(vset, ncode) jx = n + 1000 } } if nextv == 0 { keep = 0 } } if keep == 1 { out = native_list_append(out, c) } i = i + 1 } return out }