From 2202e171c53dde2359e95c7fa82bd1c7686604de Mon Sep 17 00:00:00 2001 From: krzim <44442910+krzim@users.noreply.github.com> Date: Thu, 29 Oct 2020 18:03:11 -0400 Subject: [PATCH 01/12] Fix import to grab the encoder model save function I saw that this was recently changed but I'm not sure if it should have been. This is the correct function given the arguments provided to it in the train loop. --- TTS/bin/train_encoder.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TTS/bin/train_encoder.py b/TTS/bin/train_encoder.py index 8d1f14fa..6a370362 100644 --- a/TTS/bin/train_encoder.py +++ b/TTS/bin/train_encoder.py @@ -13,10 +13,9 @@ from TTS.speaker_encoder.dataset import MyDataset from TTS.speaker_encoder.losses import AngleProtoLoss, GE2ELoss from TTS.speaker_encoder.model import SpeakerEncoder from TTS.speaker_encoder.utils.generic_utils import \ - check_config_speaker_encoder + check_config_speaker_encoder, save_best_model from TTS.speaker_encoder.utils.visual import plot_embeddings from TTS.tts.datasets.preprocess import load_meta_data -from TTS.tts.utils.io import save_best_model from TTS.utils.audio import AudioProcessor from TTS.utils.generic_utils import (count_parameters, create_experiment_folder, get_git_branch, From df180148e9fd7a8cfe428179bc6e7d0533cdd56a Mon Sep 17 00:00:00 2001 From: erogol Date: Wed, 9 Dec 2020 15:46:25 +0100 Subject: [PATCH 02/12] use noise augmentation in TTSDataset --- TTS/bin/train_glow_tts.py | 1 + TTS/tts/datasets/TTSDataset.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/TTS/bin/train_glow_tts.py b/TTS/bin/train_glow_tts.py index 70d0506a..f56dfb5e 100644 --- a/TTS/bin/train_glow_tts.py +++ b/TTS/bin/train_glow_tts.py @@ -57,6 +57,7 @@ def setup_loader(ap, r, is_val=False, verbose=False): use_phonemes=c.use_phonemes, phoneme_language=c.phoneme_language, enable_eos_bos=c.enable_eos_bos_chars, + use_noise_augment=not is_val, verbose=verbose, speaker_mapping=speaker_mapping if c.use_speaker_embedding and c.use_external_speaker_embedding_file else None) diff --git a/TTS/tts/datasets/TTSDataset.py b/TTS/tts/datasets/TTSDataset.py index 88545d45..38dd2890 100644 --- a/TTS/tts/datasets/TTSDataset.py +++ b/TTS/tts/datasets/TTSDataset.py @@ -30,6 +30,7 @@ class MyDataset(Dataset): phoneme_language="en-us", enable_eos_bos=False, speaker_mapping=None, + use_noise_augment=False, verbose=False): """ Args: @@ -48,6 +49,7 @@ class MyDataset(Dataset): phoneme_language (str): one the languages from https://github.com/bootphon/phonemizer#languages enable_eos_bos (bool): enable end of sentence and beginning of sentences characters. + use_noise_augment (bool): enable adding random noise to wav for augmentation. verbose (bool): print diagnostic information. """ self.batch_group_size = batch_group_size @@ -66,6 +68,7 @@ class MyDataset(Dataset): self.phoneme_language = phoneme_language self.enable_eos_bos = enable_eos_bos self.speaker_mapping = speaker_mapping + self.use_noise_augment = use_noise_augment self.verbose = verbose self.input_seq_computed = False if use_phonemes and not os.path.isdir(phoneme_cache_path): @@ -134,6 +137,10 @@ class MyDataset(Dataset): wav = np.asarray(self.load_wav(wav_file), dtype=np.float32) + # apply noise for augmentation + if self.use_noise_augment: + wav = wav + (1.0 / 32768.0) * np.random.rand(*wav.shape) + if not self.input_seq_computed: if self.use_phonemes: text = self._load_or_generate_phoneme_sequence(wav_file, text, self.phoneme_cache_path, self.enable_eos_bos, self.cleaners, self.phoneme_language, self.tp, self.add_blank) From 53679b706da2bc38510b467289be844f8e6e9d24 Mon Sep 17 00:00:00 2001 From: erogol Date: Wed, 9 Dec 2020 23:39:09 +0100 Subject: [PATCH 03/12] glow-tts distributed fix --- TTS/bin/train_glow_tts.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/TTS/bin/train_glow_tts.py b/TTS/bin/train_glow_tts.py index f56dfb5e..60be8fa0 100644 --- a/TTS/bin/train_glow_tts.py +++ b/TTS/bin/train_glow_tts.py @@ -280,7 +280,12 @@ def train(data_loader, model, criterion, optimizer, scheduler, # Diagnostic visualizations # direct pass on model for spec predictions target_speaker = None if speaker_c is None else speaker_c[:1] - spec_pred, *_ = model.inference(text_input[:1], text_lengths[:1], g=target_speaker) + + if hasattr(model, 'module'): + spec_pred, *_ = model.module.inference(text_input[:1], text_lengths[:1], g=target_speaker) + else: + spec_pred, *_ = model.inference(text_input[:1], text_lengths[:1], g=target_speaker) + spec_pred = spec_pred.permute(0, 2, 1) gt_spec = mel_input.permute(0, 2, 1) const_spec = spec_pred[0].data.cpu().numpy() From 92cc9630d7b288662abb3886c1e226800ac79fec Mon Sep 17 00:00:00 2001 From: erogol Date: Thu, 10 Dec 2020 00:30:34 +0100 Subject: [PATCH 04/12] fix glow-tts synthesis for DPP --- TTS/tts/utils/synthesis.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TTS/tts/utils/synthesis.py b/TTS/tts/utils/synthesis.py index cad1d21f..8b2fbec6 100644 --- a/TTS/tts/utils/synthesis.py +++ b/TTS/tts/utils/synthesis.py @@ -62,7 +62,11 @@ def run_model_torch(model, inputs, CONFIG, truncated, speaker_id=None, style_mel inputs, speaker_ids=speaker_id, speaker_embeddings=speaker_embeddings) elif 'glow' in CONFIG.model.lower(): inputs_lengths = torch.tensor(inputs.shape[1:2]).to(inputs.device) # pylint: disable=not-callable - postnet_output, _, _, _, alignments, _, _ = model.inference(inputs, inputs_lengths, g=speaker_id if speaker_id else speaker_embeddings) + if hasattr(model, 'module'): + # distributed model + postnet_output, _, _, _, alignments, _, _ = model.module.inference(inputs, inputs_lengths, g=speaker_id if speaker_id else speaker_embeddings) + else: + postnet_output, _, _, _, alignments, _, _ = model.inference(inputs, inputs_lengths, g=speaker_id if speaker_id else speaker_embeddings) postnet_output = postnet_output.permute(0, 2, 1) # these only belong to tacotron models. decoder_output = None From 788cd6f9024e627275381481f606afa6ae80e04b Mon Sep 17 00:00:00 2001 From: erogol Date: Thu, 10 Dec 2020 02:05:48 +0100 Subject: [PATCH 05/12] fix multi-speaker glow-tts inference --- TTS/tts/utils/synthesis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TTS/tts/utils/synthesis.py b/TTS/tts/utils/synthesis.py index 8b2fbec6..76fdb3de 100644 --- a/TTS/tts/utils/synthesis.py +++ b/TTS/tts/utils/synthesis.py @@ -64,9 +64,9 @@ def run_model_torch(model, inputs, CONFIG, truncated, speaker_id=None, style_mel inputs_lengths = torch.tensor(inputs.shape[1:2]).to(inputs.device) # pylint: disable=not-callable if hasattr(model, 'module'): # distributed model - postnet_output, _, _, _, alignments, _, _ = model.module.inference(inputs, inputs_lengths, g=speaker_id if speaker_id else speaker_embeddings) + postnet_output, _, _, _, alignments, _, _ = model.module.inference(inputs, inputs_lengths, g=speaker_id if speaker_id is not None else speaker_embeddings) else: - postnet_output, _, _, _, alignments, _, _ = model.inference(inputs, inputs_lengths, g=speaker_id if speaker_id else speaker_embeddings) + postnet_output, _, _, _, alignments, _, _ = model.inference(inputs, inputs_lengths, g=speaker_id if speaker_id is not None else speaker_embeddings) postnet_output = postnet_output.permute(0, 2, 1) # these only belong to tacotron models. decoder_output = None From 58687f9c34b9d6d644eaebb9a4e31b27c522cbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sat, 5 Dec 2020 09:45:04 +0100 Subject: [PATCH 06/12] tests/test_text_processing: fix undefined variable --- tests/test_text_processing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_text_processing.py b/tests/test_text_processing.py index ae3250a8..d6bcbe61 100644 --- a/tests/test_text_processing.py +++ b/tests/test_text_processing.py @@ -171,4 +171,4 @@ def test_text2phone(): gt = "ɹ|iː|s|ə|n|t| |ɹ|ɪ|s|ɜː|tʃ| |æ|t| |h|ɑːɹ|v|ɚ|d| |h|ɐ|z| |ʃ|oʊ|n| |m|ɛ|d|ᵻ|t|eɪ|ɾ|ɪ|ŋ| |f|ɔː|ɹ| |æ|z| |l|ɪ|ɾ|əl| |æ|z| |eɪ|t| |w|iː|k|s| |k|æ|n| |æ|k|tʃ|uː|əl|i| |ɪ|n|k|ɹ|iː|s|,| |ð|ə| |ɡ|ɹ|eɪ| |m|æ|ɾ|ɚ|ɹ| |ɪ|n|ð|ə| |p|ɑːɹ|t|s| |ʌ|v|ð|ə| |b|ɹ|eɪ|n| |ɹ|ɪ|s|p|ɑː|n|s|ə|b|əl| |f|ɔː|ɹ| |ɪ|m|oʊ|ʃ|ə|n|əl| |ɹ|ɛ|ɡ|j|uː|l|eɪ|ʃ|ə|n| |æ|n|d| |l|ɜː|n|ɪ|ŋ|!" lang = "en-us" ph = text2phone(text, lang) - assert gt == ph, f"\n{phonemes} \n vs \n{gt}" + assert gt == ph, f"\n{ph} \n vs \n{gt}" From 76138687d3445514e7c615617267a4203f193a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sat, 5 Dec 2020 09:45:57 +0100 Subject: [PATCH 07/12] expand more currencies --- TTS/tts/utils/text/cleaners.py | 2 +- TTS/tts/utils/text/number_norm.py | 71 ++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/TTS/tts/utils/text/cleaners.py b/TTS/tts/utils/text/cleaners.py index 492a1017..190f52aa 100644 --- a/TTS/tts/utils/text/cleaners.py +++ b/TTS/tts/utils/text/cleaners.py @@ -122,8 +122,8 @@ def portuguese_cleaners(text): def phoneme_cleaners(text): '''Pipeline for phonemes mode, including number and abbreviation expansion.''' - text = convert_to_ascii(text) text = expand_numbers(text) + text = convert_to_ascii(text) text = expand_abbreviations(text) text = replace_symbols(text) text = remove_aux_symbols(text) diff --git a/TTS/tts/utils/text/number_norm.py b/TTS/tts/utils/text/number_norm.py index 50de8d5c..a366ae42 100644 --- a/TTS/tts/utils/text/number_norm.py +++ b/TTS/tts/utils/text/number_norm.py @@ -2,12 +2,12 @@ import inflect import re +from typing import Dict _inflect = inflect.engine() _comma_number_re = re.compile(r'([0-9][0-9\,]+[0-9])') _decimal_number_re = re.compile(r'([0-9]+\.[0-9]+)') -_pounds_re = re.compile(r'£([0-9\,]*[0-9]+)') -_dollars_re = re.compile(r'\$([0-9\.\,]*[0-9]+)') +_currency_re = re.compile(r'(£|\$|¥)([0-9\,\.]*[0-9]+)') _ordinal_re = re.compile(r'[0-9]+(st|nd|rd|th)') _number_re = re.compile(r'[0-9]+') @@ -20,24 +20,54 @@ def _expand_decimal_point(m): return m.group(1).replace('.', ' point ') -def _expand_dollars(m): - match = m.group(1) - parts = match.split('.') +def __expand_currency(value: str, inflection: Dict[float, str]) -> str: + parts = value.replace(",", "").split('.') if len(parts) > 2: - return match + ' dollars' # Unexpected format - dollars = int(parts[0]) if parts[0] else 0 - cents = int(parts[1]) if len(parts) > 1 and parts[1] else 0 - if dollars and cents: - dollar_unit = 'dollar' if dollars == 1 else 'dollars' - cent_unit = 'cent' if cents == 1 else 'cents' - return '%s %s, %s %s' % (dollars, dollar_unit, cents, cent_unit) - if dollars: - dollar_unit = 'dollar' if dollars == 1 else 'dollars' - return '%s %s' % (dollars, dollar_unit) - if cents: - cent_unit = 'cent' if cents == 1 else 'cents' - return '%s %s' % (cents, cent_unit) - return 'zero dollars' + return f"{value} {inflection[2]}" # Unexpected format + text = [] + integer = int(parts[0]) if parts[0] else 0 + if integer > 0: + integer_unit = inflection.get(integer, inflection[2]) + text.append(f"{integer} {integer_unit}") + fraction = int(parts[1]) if len(parts) > 1 and parts[1] else 0 + if fraction > 0: + fraction_unit = inflection.get(fraction/100, inflection[0.02]) + text.append(f"{fraction} {fraction_unit}") + if len(text) == 0: + return f"zero {inflection[2]}" + return " ".join(text) + + +def _expand_currency(m: "re.Match") -> str: + currencies = { + "$": { + 0.01: "cent", + 0.02: "cents", + 1: "dollar", + 2: "dollars", + }, + "€": { + 0.01: "cent", + 0.02: "cents", + 1: "euro", + 2: "euros", + }, + "£": { + 0.01: "penny", + 0.02: "pence", + 1: "pound sterling", + 2: "pounds sterling", + }, + "¥": { + # TODO rin + 0.02: "sen", + 2: "yen", + } + } + unit = m.group(1) + currency = currencies[unit] + value = m.group(2) + return __expand_currency(value, currency) def _expand_ordinal(m): @@ -62,8 +92,7 @@ def _expand_number(m): def normalize_numbers(text): text = re.sub(_comma_number_re, _remove_commas, text) - text = re.sub(_pounds_re, r'\1 pounds', text) - text = re.sub(_dollars_re, _expand_dollars, text) + text = re.sub(_currency_re, _expand_currency, text) text = re.sub(_decimal_number_re, _expand_decimal_point, text) text = re.sub(_ordinal_re, _expand_ordinal, text) text = re.sub(_number_re, _expand_number, text) From 664668265068243cfaa8796093acca17147c7fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sat, 5 Dec 2020 09:46:34 +0100 Subject: [PATCH 08/12] cleaners: expand english time --- TTS/tts/utils/text/cleaners.py | 2 ++ TTS/tts/utils/text/time.py | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 TTS/tts/utils/text/time.py diff --git a/TTS/tts/utils/text/cleaners.py b/TTS/tts/utils/text/cleaners.py index 190f52aa..7c3f1017 100644 --- a/TTS/tts/utils/text/cleaners.py +++ b/TTS/tts/utils/text/cleaners.py @@ -14,6 +14,7 @@ import re from unidecode import unidecode from .number_norm import normalize_numbers from .abbreviations import abbreviations_en, abbreviations_fr +from .time import expand_time_english # Regular expression matching whitespace: _whitespace_re = re.compile(r'\s+') @@ -95,6 +96,7 @@ def english_cleaners(text): '''Pipeline for English text, including number and abbreviation expansion.''' text = convert_to_ascii(text) text = lowercase(text) + text = expand_time_english(text) text = expand_numbers(text) text = expand_abbreviations(text) text = replace_symbols(text) diff --git a/TTS/tts/utils/text/time.py b/TTS/tts/utils/text/time.py new file mode 100644 index 00000000..55ecbd8c --- /dev/null +++ b/TTS/tts/utils/text/time.py @@ -0,0 +1,44 @@ +import re +import inflect + +_inflect = inflect.engine() + +_time_re = re.compile(r"""\b + ((0?[0-9])|(1[0-1])|(1[2-9])|(2[0-3])) # hours + : + ([0-5][0-9]) # minutes + \s*(a\\.m\\.|am|pm|p\\.m\\.|a\\.m|p\\.m)? # am/pm + \b""", + re.IGNORECASE | re.X) + + +def _expand_num(n: int) -> str: + return _inflect.number_to_words(n) + + +def _expand_time_english(match: "re.Match") -> str: + hour = int(match.group(1)) + past_noon = hour >= 12 + time = [] + if hour > 12: + hour -= 12 + elif hour == 0: + hour = 12 + past_noon = True + time.append(_expand_num(hour)) + + minute = int(match.group(6)) + if minute > 0: + if minute < 10: + time.append("oh") + time.append(_expand_num(minute)) + am_pm = match.group(7) + if am_pm is None: + time.append("p m" if past_noon else "a m") + else: + time.extend(list(am_pm.replace(".", ""))) + return " ".join(time) + + +def expand_time_english(text: str) -> str: + return re.sub(_time_re, _expand_time_english, text) From 2007b0bcee90f9d4a08d22c8c4759d1cad4ab113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sat, 5 Dec 2020 09:46:51 +0100 Subject: [PATCH 09/12] add tests for currency/time expansion --- tests/test_text_cleaners.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/test_text_cleaners.py diff --git a/tests/test_text_cleaners.py b/tests/test_text_cleaners.py new file mode 100644 index 00000000..081e819a --- /dev/null +++ b/tests/test_text_cleaners.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +from TTS.tts.utils.text.cleaners import english_cleaners, phoneme_cleaners +from typing import Any + + +def assert_equal(actual: Any, expected: Any) -> None: + assert actual == expected, f"\n{actual} \n vs \n{expected}" + + +def test_time() -> None: + assert_equal(english_cleaners("It's 11:00"), "it's eleven a m") + assert_equal(english_cleaners("It's 9:01"), "it's nine oh one a m") + assert_equal(english_cleaners("It's 16:00"), "it's four p m") + assert_equal(english_cleaners("It's 00:00 am"), "it's twelve a m") + + +def test_currency() -> None: + assert_equal(phoneme_cleaners("It's $10.50"), + "It's ten dollars fifty cents") + assert_equal(phoneme_cleaners("£1.1"), + "one pound sterling one penny") + assert_equal(phoneme_cleaners("¥1"), + "one yen") From ea2c57b0ac1fb67332364bf91cdaee2db0ccbe20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Thu, 10 Dec 2020 16:37:54 +0100 Subject: [PATCH 10/12] test_text_processing: remove assertion message pytest does a better job at diffing anyway in case of an error --- tests/test_text_processing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_text_processing.py b/tests/test_text_processing.py index d6bcbe61..2f68c6e7 100644 --- a/tests/test_text_processing.py +++ b/tests/test_text_processing.py @@ -171,4 +171,4 @@ def test_text2phone(): gt = "ɹ|iː|s|ə|n|t| |ɹ|ɪ|s|ɜː|tʃ| |æ|t| |h|ɑːɹ|v|ɚ|d| |h|ɐ|z| |ʃ|oʊ|n| |m|ɛ|d|ᵻ|t|eɪ|ɾ|ɪ|ŋ| |f|ɔː|ɹ| |æ|z| |l|ɪ|ɾ|əl| |æ|z| |eɪ|t| |w|iː|k|s| |k|æ|n| |æ|k|tʃ|uː|əl|i| |ɪ|n|k|ɹ|iː|s|,| |ð|ə| |ɡ|ɹ|eɪ| |m|æ|ɾ|ɚ|ɹ| |ɪ|n|ð|ə| |p|ɑːɹ|t|s| |ʌ|v|ð|ə| |b|ɹ|eɪ|n| |ɹ|ɪ|s|p|ɑː|n|s|ə|b|əl| |f|ɔː|ɹ| |ɪ|m|oʊ|ʃ|ə|n|əl| |ɹ|ɛ|ɡ|j|uː|l|eɪ|ʃ|ə|n| |æ|n|d| |l|ɜː|n|ɪ|ŋ|!" lang = "en-us" ph = text2phone(text, lang) - assert gt == ph, f"\n{ph} \n vs \n{gt}" + assert gt == ph From cdb81f8c5dcf109c28bb253c0da304d621ad112e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Thu, 10 Dec 2020 16:43:07 +0100 Subject: [PATCH 11/12] test_text_cleaners: don't re-invent assertions pytest does treat assert special and does a better job w.r.t error reporting --- tests/test_text_cleaners.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/tests/test_text_cleaners.py b/tests/test_text_cleaners.py index 081e819a..0407b5d7 100644 --- a/tests/test_text_cleaners.py +++ b/tests/test_text_cleaners.py @@ -1,24 +1,16 @@ #!/usr/bin/env python3 from TTS.tts.utils.text.cleaners import english_cleaners, phoneme_cleaners -from typing import Any - - -def assert_equal(actual: Any, expected: Any) -> None: - assert actual == expected, f"\n{actual} \n vs \n{expected}" def test_time() -> None: - assert_equal(english_cleaners("It's 11:00"), "it's eleven a m") - assert_equal(english_cleaners("It's 9:01"), "it's nine oh one a m") - assert_equal(english_cleaners("It's 16:00"), "it's four p m") - assert_equal(english_cleaners("It's 00:00 am"), "it's twelve a m") + assert english_cleaners("It's 11:00") == "it's eleven a m" + assert english_cleaners("It's 9:01") == "it's nine oh one a m" + assert english_cleaners("It's 16:00") == "it's four p m" + assert english_cleaners("It's 00:00 am") == "it's twelve a m" def test_currency() -> None: - assert_equal(phoneme_cleaners("It's $10.50"), - "It's ten dollars fifty cents") - assert_equal(phoneme_cleaners("£1.1"), - "one pound sterling one penny") - assert_equal(phoneme_cleaners("¥1"), - "one yen") + assert phoneme_cleaners("It's $10.50") == "It's ten dollars fifty cents" + assert phoneme_cleaners("£1.1") == "one pound sterling one penny" + assert phoneme_cleaners("¥1") == "one yen" From 62fd4ca70dec5851c44265147b389aa135861a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Fri, 4 Dec 2020 22:48:08 +0100 Subject: [PATCH 12/12] inflect negative numbers correctly --- TTS/tts/utils/text/number_norm.py | 2 +- tests/test_text_cleaners.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/TTS/tts/utils/text/number_norm.py b/TTS/tts/utils/text/number_norm.py index a366ae42..2b83c271 100644 --- a/TTS/tts/utils/text/number_norm.py +++ b/TTS/tts/utils/text/number_norm.py @@ -9,7 +9,7 @@ _comma_number_re = re.compile(r'([0-9][0-9\,]+[0-9])') _decimal_number_re = re.compile(r'([0-9]+\.[0-9]+)') _currency_re = re.compile(r'(£|\$|¥)([0-9\,\.]*[0-9]+)') _ordinal_re = re.compile(r'[0-9]+(st|nd|rd|th)') -_number_re = re.compile(r'[0-9]+') +_number_re = re.compile(r'-?[0-9]+') def _remove_commas(m): diff --git a/tests/test_text_cleaners.py b/tests/test_text_cleaners.py index 0407b5d7..7a2abe72 100644 --- a/tests/test_text_cleaners.py +++ b/tests/test_text_cleaners.py @@ -14,3 +14,8 @@ def test_currency() -> None: assert phoneme_cleaners("It's $10.50") == "It's ten dollars fifty cents" assert phoneme_cleaners("£1.1") == "one pound sterling one penny" assert phoneme_cleaners("¥1") == "one yen" + + +def test_expand_numbers() -> None: + assert "minus one" == phoneme_cleaners("-1") + assert "one" == phoneme_cleaners("1")