CoolFace
Apppublic

fighter-programmer/voicegen

sourceHugging Faceupdated 4y agoView on Hugging Face
0likes
english.py189 linesDownload Raw Back to text
1""" from https://github.com/keithito/tacotron """2 3'''4Cleaners are transformations that run over the input text at both training and eval time.5 6Cleaners can be selected by passing a comma-delimited list of cleaner names as the "cleaners"7hyperparameter. Some cleaners are English-specific. You'll typically want to use:8  1. "english_cleaners" for English text9  2. "transliteration_cleaners" for non-English text that can be transliterated to ASCII using10     the Unidecode library (https://pypi.python.org/pypi/Unidecode)11  3. "basic_cleaners" if you do not want to transliterate (in this case, you should also update12     the symbols in symbols.py to match your data).13'''14 15 16# Regular expression matching whitespace:17 18 19import re20import inflect21from unidecode import unidecode22import eng_to_ipa as ipa23_inflect = inflect.engine()24_comma_number_re = re.compile(r'([0-9][0-9\,]+[0-9])')25_decimal_number_re = re.compile(r'([0-9]+\.[0-9]+)')26_pounds_re = re.compile(r'£([0-9\,]*[0-9]+)')27_dollars_re = re.compile(r'\$([0-9\.\,]*[0-9]+)')28_ordinal_re = re.compile(r'[0-9]+(st|nd|rd|th)')29_number_re = re.compile(r'[0-9]+')30 31# List of (regular expression, replacement) pairs for abbreviations:32_abbreviations = [(re.compile('\\b%s\\.' % x[0], re.IGNORECASE), x[1]) for x in [33    ('mrs', 'misess'),34    ('mr', 'mister'),35    ('dr', 'doctor'),36    ('st', 'saint'),37    ('co', 'company'),38    ('jr', 'junior'),39    ('maj', 'major'),40    ('gen', 'general'),41    ('drs', 'doctors'),42    ('rev', 'reverend'),43    ('lt', 'lieutenant'),44    ('hon', 'honorable'),45    ('sgt', 'sergeant'),46    ('capt', 'captain'),47    ('esq', 'esquire'),48    ('ltd', 'limited'),49    ('col', 'colonel'),50    ('ft', 'fort'),51]]52 53 54# List of (ipa, lazy ipa) pairs:55_lazy_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [56    ('r', 'ɹ'),57    ('æ', 'e'),58    ('ɑ', 'a'),59    ('ɔ', 'o'),60    ('ð', 'z'),61    ('θ', 's'),62    ('ɛ', 'e'),63    ('ɪ', 'i'),64    ('ʊ', 'u'),65    ('ʒ', 'ʥ'),66    ('ʤ', 'ʥ'),67    ('ˈ', '↓'),68]]69 70# List of (ipa, lazy ipa2) pairs:71_lazy_ipa2 = [(re.compile('%s' % x[0]), x[1]) for x in [72    ('r', 'ɹ'),73    ('ð', 'z'),74    ('θ', 's'),75    ('ʒ', 'ʑ'),76    ('ʤ', 'dʑ'),77    ('ˈ', '↓'),78]]79 80# List of (ipa, ipa2) pairs81_ipa_to_ipa2 = [(re.compile('%s' % x[0]), x[1]) for x in [82    ('r', 'ɹ'),83    ('ʤ', 'dʒ'),84    ('ʧ', 'tʃ')85]]86 87 88def expand_abbreviations(text):89    for regex, replacement in _abbreviations:90        text = re.sub(regex, replacement, text)91    return text92 93 94def collapse_whitespace(text):95    return re.sub(r'\s+', ' ', text)96 97 98def _remove_commas(m):99    return m.group(1).replace(',', '')100 101 102def _expand_decimal_point(m):103    return m.group(1).replace('.', ' point ')104 105 106def _expand_dollars(m):107    match = m.group(1)108    parts = match.split('.')109    if len(parts) > 2:110        return match + ' dollars'  # Unexpected format111    dollars = int(parts[0]) if parts[0] else 0112    cents = int(parts[1]) if len(parts) > 1 and parts[1] else 0113    if dollars and cents:114        dollar_unit = 'dollar' if dollars == 1 else 'dollars'115        cent_unit = 'cent' if cents == 1 else 'cents'116        return '%s %s, %s %s' % (dollars, dollar_unit, cents, cent_unit)117    elif dollars:118        dollar_unit = 'dollar' if dollars == 1 else 'dollars'119        return '%s %s' % (dollars, dollar_unit)120    elif cents:121        cent_unit = 'cent' if cents == 1 else 'cents'122        return '%s %s' % (cents, cent_unit)123    else:124        return 'zero dollars'125 126 127def _expand_ordinal(m):128    return _inflect.number_to_words(m.group(0))129 130 131def _expand_number(m):132    num = int(m.group(0))133    if num > 1000 and num < 3000:134        if num == 2000:135            return 'two thousand'136        elif num > 2000 and num < 2010:137            return 'two thousand ' + _inflect.number_to_words(num % 100)138        elif num % 100 == 0:139            return _inflect.number_to_words(num // 100) + ' hundred'140        else:141            return _inflect.number_to_words(num, andword='', zero='oh', group=2).replace(', ', ' ')142    else:143        return _inflect.number_to_words(num, andword='')144 145 146def normalize_numbers(text):147    text = re.sub(_comma_number_re, _remove_commas, text)148    text = re.sub(_pounds_re, r'\1 pounds', text)149    text = re.sub(_dollars_re, _expand_dollars, text)150    text = re.sub(_decimal_number_re, _expand_decimal_point, text)151    text = re.sub(_ordinal_re, _expand_ordinal, text)152    text = re.sub(_number_re, _expand_number, text)153    return text154 155 156def mark_dark_l(text):157    return re.sub(r'l([^aeiouæɑɔəɛɪʊ ]*(?: |$))', lambda x: 'ɫ'+x.group(1), text)158 159 160def english_to_ipa(text):161    text = unidecode(text).lower()162    text = expand_abbreviations(text)163    text = normalize_numbers(text)164    phonemes = ipa.convert(text)165    phonemes = collapse_whitespace(phonemes)166    return phonemes167 168 169def english_to_lazy_ipa(text):170    text = english_to_ipa(text)171    for regex, replacement in _lazy_ipa:172        text = re.sub(regex, replacement, text)173    return text174 175 176def english_to_ipa2(text):177    text = english_to_ipa(text)178    text = mark_dark_l(text)179    for regex, replacement in _ipa_to_ipa2:180        text = re.sub(regex, replacement, text)181    return text.replace('...', '…')182 183 184def english_to_lazy_ipa2(text):185    text = english_to_ipa(text)186    for regex, replacement in _lazy_ipa2:187        text = re.sub(regex, replacement, text)188    return text189