export enum VowelHeight { Open, NearOpen, OpenMid, Mid, CloseMid, NearClose, Close, } export enum VowelDepth { Front, Central, Back, } export interface VowelFeatures { height: VowelHeight; depth: VowelDepth; round: boolean; long: boolean; nasal: boolean; } export function vowelFeaturesToIpa(features: VowelFeatures): string { const ipa = () => { switch (features.height) { case VowelHeight.Open: switch (features.depth) { case VowelDepth.Front: return features.round ? 'ɶ' : 'a'; case VowelDepth.Central: return features.round ? 'ɞ' : 'ä'; case VowelDepth.Back: return features.round ? 'ɒ' : 'ɑ'; } case VowelHeight.NearOpen: switch (features.depth) { case VowelDepth.Front: return features.round ? 'ɶ' : 'æ'; case VowelDepth.Central: return features.round ? 'ɞ' : 'ɐ'; case VowelDepth.Back: return features.round ? 'ɒ' : 'ɑ'; } case VowelHeight.OpenMid: switch (features.depth) { case VowelDepth.Front: return features.round ? 'œ' : 'ɛ'; case VowelDepth.Central: return features.round ? 'ɞ' : 'ɜ'; case VowelDepth.Back: return features.round ? 'ɒ' : 'ɑ'; } case VowelHeight.Mid: switch (features.depth) { case VowelDepth.Front: return features.round ? 'ø̞' : 'e̞'; case VowelDepth.Central: return features.round ? 'ɵ' : 'ə'; case VowelDepth.Back: return features.round ? 'o̞' : 'ɤ̞'; } case VowelHeight.CloseMid: switch (features.depth) { case VowelDepth.Front: return features.round ? 'ø' : 'e'; case VowelDepth.Central: return features.round ? 'ɵ' : 'ɘ'; case VowelDepth.Back: return features.round ? 'o' : 'ɤ'; } case VowelHeight.NearClose: switch (features.depth) { case VowelDepth.Front: return features.round ? 'ʏ' : 'ɪ'; case VowelDepth.Central: return features.round ? 'ʉ' : 'ɨ'; case VowelDepth.Back: return features.round ? 'u' : 'ʊ'; } case VowelHeight.Close: switch (features.depth) { case VowelDepth.Front: return features.round ? 'y' : 'i'; case VowelDepth.Central: return features.round ? 'ʉ' : 'ɨ'; case VowelDepth.Back: return features.round ? 'u' : 'ɯ'; } default: throw new Error(`bad vowel height: ${features.height}`); } }; const nasal = features.nasal ? '̃' : ''; const vlong = features.long ? 'ː' : ''; return ipa() + nasal + vlong; }