### Install ToJyutping using pip Source: https://github.com/canclid/tojyutping/blob/main/README.md Install the ToJyutping library using pip. This is the primary method for adding the tool to your Python environment. ```sh pip install ToJyutping ``` -------------------------------- ### Handle multi-syllable characters with IPA Source: https://github.com/canclid/tojyutping/blob/main/README.md Illustrates how ToJyutping represents characters with multiple IPA syllables, using the example of the ligature '瓩'. ```python >>> ToJyutping.get_ipa_list('一瓩') [('一', 'jɐt̚˥'), ('瓩', 't͡sʰiːn˥.ŋaː˩˧')] ``` -------------------------------- ### Get IPA candidates for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Retrieve a list of possible IPA pronunciations for each character in a Cantonese sentence. Pronunciations are sorted by likelihood. ```python >>> ToJyutping.get_ipa_candidates('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') [('咁', ['kɐm˧', 'kɐm˧˥', 'kɐm˥', 'kɐm˨˩']), ('啱', ['ŋaːm˥', 'aːm˥', 'ɐm˥', 'ŋɐm˥']), ('老', ['lou̯˩˧', 'lou̯˧˥']), ('世', ['sɐi̯˧', 'sɐi̯˧˥']), ('要', ['jiːu̯˥', 'jiːu̯˧', 'jiːu̯˧˥']), ('求', ['kʰɐu̯˨˩']), ('佢', ['kʰɵy̑˩˧', 'hɵy̑˩˧']), ('等', ['tɐŋ˧˥']), ('陣', ['t͡sɐn˨', 't͡sɐn˧˥']), ('要', ['jiːu̯˧', 'jiːu̯˧˥', 'jiːu̯˥']), ('開', ['hɔːi̯˥']), ('會', ['wuːi̯˧˥', 'wuːi̯˩˧', 'wuːi̯˨', 'wuːi̯˧', 'kʰuːi̯˧˥', 'kʰuːi̯˧', 'kʷʰuːi̯˧˥']), (',', []), ('剩', ['t͡seŋ˨', 'seŋ˨']), ('低', ['tɐi̯˥']), ('嘅', ['kɛː˧', 'kɛː˧˥', 'kʰɔːi̯˧˥', 'kʰɔːi̯˧']), ('嘢', ['jɛː˩˧', 'ɛː˩˧']), ('我', ['ŋɔː˩˧', 'ɔː˩˧']), ('會', ['wuːi̯˩˧', 'wuːi̯˨', 'wuːi̯˧˥', 'wuːi̯˧', 'kʰuːi̯˧˥', 'kʰuːi̯˧', 'kʷʰuːi̯˧˥']), ('搞', ['kaːu̯˧˥']), ('掂', ['tiːm˨', 'tiːm˧', 'tiːm˥']), ('㗎', ['kaː˧', 'kɐ˧', 'kaː˧˥', 'kaː˥', 'kaː˨˩']), ('喇', ['laː˧', 'laː˥', 'laːk̚˧', 'laː˩˧', 'laːt̚˧']), ('。', [])] ``` -------------------------------- ### Get Jyutping candidates for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Retrieve a list of possible Jyutping pronunciations for each character in a Cantonese sentence. Pronunciations are sorted by likelihood. ```python >>> ToJyutping.get_jyutping_candidates('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') [('咁', ['gam3', 'gam2', 'gam1', 'gam4']), ('啱', ['ngaam1', 'aam1', 'am1', 'ngam1']), ('老', ['lou5', 'lou2']), ('世', ['sai3', 'sai2']), ('要', ['jiu1', 'jiu3', 'jiu2']), ('求', ['kau4']), ('佢', ['keoi5', 'heoi5']), ('等', ['dang2']), ('陣', ['zan6', 'zan2']), ('要', ['jiu3', 'jiu2', 'jiu1']), ('開', ['hoi1']), ('會', ['wui2', 'wui5', 'wui6', 'wui3', 'kui2', 'kui3', 'kwui2']), (',', []), ('剩', ['zing6', 'sing6']), ('低', ['dai1']), ('嘅', ['ge3', 'ge2', 'koi2', 'koi3']), ('嘢', ['je5', 'e5']), ('我', ['ngo5', 'o5']), ('會', ['wui5', 'wui6', 'wui2', 'wui3', 'kui2', 'kui3', 'kwui2']), ('搞', ['gaau2']), ('掂', ['dim6', 'dim3', 'dim1']), ('㗎', ['gaa3', 'ga3', 'gaa2', 'gaa1', 'gaa4']), ('喇', ['laa3', 'laa1', 'laak3', 'laa5', 'laat3']), ('。', [])] ``` -------------------------------- ### Get single IPA string for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Get a single string representing the IPA pronunciation of a Cantonese sentence, with characters and their pronunciations concatenated. ```python >>> ToJyutping.get_ipa('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') '咁[kɐm˧]啱[ŋaːm˥]老[lou̯˩˧]世[sɐi̯˧]要[jiːu̯˥]求[kʰɐu̯˨˩]佢[kʰɵy̑˩˧]等[tɐŋ˧˥]陣[t͡sɐn˨]要[jiːu̯˧]開[hɔːi̯˥]會[wuːi̯˧˥],剩[t͡seŋ˨]低[tɐi̯˥]嘅[kɛː˧]嘢[jɛː˩˧]我[ŋɔː˩˧]會[wuːi̯˩˧]搞[kaːu̯˧˥]掂[tiːm˨]㗎[kaː˧]喇[laː˧].' ``` -------------------------------- ### Get Jyutping list for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Obtain a list of Jyutping pronunciations for each character in a given Cantonese sentence. Punctuation is returned as None. ```python >>> import ToJyutping >>> ToJyutping.get_jyutping_list('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') [('咁', 'gam3'), ('啱', 'ngaam1'), ('老', 'lou5'), ('世', 'sai3'), ('要', 'jiu1'), ('求', 'kau4'), ('佢', 'keoi5'), ('等', 'dang2'), ('陣', 'zan6'), ('要', 'jiu3'), ('開', 'hoi1'), ('會', 'wui2'), (',', None), ('剩', 'zing6'), ('低', 'dai1'), ('嘅', 'ge3'), ('嘢', 'je5'), ('我', 'ngo5'), ('會', 'wui5'), ('搞', 'gaau2'), ('掂', 'dim6'), ('㗎', 'gaa3'), ('喇', 'laa3'), ('。', None)] ``` -------------------------------- ### Get IPA list for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Obtain a list of IPA (International Phonetic Alphabet) pronunciations for each character in a Cantonese sentence. Punctuation is returned as None. ```python >>> ToJyutping.get_ipa_list('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') [('咁', 'kɐm˧'), ('啱', 'ŋaːm˥'), ('老', 'lou̯˩˧'), ('世', 'sɐi̯˧'), ('要', 'jiːu̯˥'), ('求', 'kʰɐu̯˨˩'), ('佢', 'kʰɵy̑˩˧'), ('等', 'tɐŋ˧˥'), ('陣', 't͡sɐn˨'), ('要', 'jiːu̯˧'), ('開', 'hɔːi̯˥'), ('會', 'wuːi̯˧˥'), (',', None), ('剩', 't͡seŋ˨'), ('低', 'tɐi̯˥'), ('嘅', 'kɛː˧'), ('嘢', 'jɛː˩˧'), ('我', 'ŋɔː˩˧'), ('會', 'wuːi̯˩˧'), ('搞', 'kaːu̯˧˥'), ('掂', 'tiːm˨'), ('㗎', 'kaː˧'), ('喇', 'laː˧'), ('。', None)] ``` -------------------------------- ### Get IPA text for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Obtain a space-separated string of IPA pronunciations for a Cantonese sentence, suitable for text processing. ```python >>> ToJyutping.get_ipa_text('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') 'kɐm˧.ŋaːm˥.lou̯˩˧.sɐi̯˧.jiːu̯˥.kʰɐu̯˨˩.kʰɵy̑˩˧.tɐŋ˧˥.t͡sɐn˨.jiːu̯˧.hɔːi̯˥.wuːi̯˧˥ | t͡seŋ˨.tɐi̯˥.kɛː˧.jɛː˩˧.ŋɔː˩˧.wuːi̯˩˧.kaːu̯˧˥.tiːm˨.kaː˧.laː˧' ``` -------------------------------- ### Get Jyutping text for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Obtain a space-separated string of Jyutping pronunciations for a Cantonese sentence, suitable for text processing. ```python >>> ToJyutping.get_jyutping_text('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') 'gam3 ngaam1 lou5 sai3 jiu1 kau4 keoi5 dang2 zan6 jiu3 hoi1 wui2, zing6 dai1 ge3 je5 ngo5 wui5 gaau2 dim6 gaa3 laa3.' ``` -------------------------------- ### Get single Jyutping string for a sentence Source: https://github.com/canclid/tojyutping/blob/main/README.md Get a single string representing the Jyutping pronunciation of a Cantonese sentence, with characters and their pronunciations concatenated. ```python >>> ToJyutping.get_jyutping('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') '咁(gam3)啱(ngaam1)老(lou5)世(sai3)要(jiu1)求(kau4)佢(keoi5)等(dang2)陣(zan6)要(jiu3)開(hoi1)會(wui2),剩(zing6)低(dai1)嘅(ge3)嘢(je5)我(ngo5)會(wui5)搞(gaau2)掂(dim6)㗎(gaa3)喇(laa3)。' ``` -------------------------------- ### Get Default Jyutping Source: https://github.com/canclid/tojyutping/blob/main/README.md Retrieve the default Jyutping text for a given Cantonese sentence. This is the baseline before any customizations are applied. ```python >>> ToJyutping.get_jyutping_text('上堂終於講到分數') 'soeng5 tong4 zung1 jyu1 gong2 dou3 fan1 sou3' ``` -------------------------------- ### Chaining Converters: Customizing '到' Source: https://github.com/canclid/tojyutping/blob/main/README.md Illustrates chaining custom converters to modify the pronunciation of '到'. One converter sets it to 'dou2', while another sets it to None, demonstrating independent customization. ```python >>> converter_dou2 = converter_lesson.customize({'到': 'dou2'}) >>> converter_None = converter_lesson.customize({'到': None}) >>> converter_dou2.get_jyutping_text('上堂終於講到分數') 'soeng6 tong4 zung1 jyu1 gong2 dou2 fan6 sou3' >>> converter_None.get_jyutping_text('上堂終於講到分數') 'soeng6 tong4 zung1 jyu1 gong2 […] fan6 sou3' ``` -------------------------------- ### Grapheme-to-Phoneme Conversion with Punctuation Offset and Same Padding ID Source: https://github.com/canclid/tojyutping/blob/main/README.md Shows how to make the padding ID and the unknown character filler ID the same by adjusting offsets. This can lead to unexpected results if not carefully managed. ```python >>> ToJyutping.g2p('咩話……你話上個月上堂學法文文法用咗 $50,000!?', puncts_offset=0, offset=(7, 7, 0)) PhonemesList([(10, 45, 1), (21, 27, 2), (1,), (14, 46, 5), (21, 27, 6), (25, 83, 6), (16, 63, 3), (26, 91, 6), (25, 83, 5), (13, 68, 4), (22, 71, 6), (11, 34, 3), (10, 40, 2), (10, 40, 4), (11, 34, 3), (26, 77, 6), (23, 63, 2), (0,), (0,), (0,), (0,), (0,), (0,), (0,), (3,), (4,)]) ``` -------------------------------- ### Import specific function from ToJyutping Source: https://github.com/canclid/tojyutping/blob/main/README.md Demonstrates importing a single function, `get_jyutping_text`, directly from the ToJyutping library for use in your script. ```python >>> from ToJyutping import get_jyutping_text >>> get_jyutping_text('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') 'gam3 ngaam1 lou5 sai3 jiu1 kau4 keoi5 dang2 zan6 jiu3 hoi1 wui2, zing6 dai1 ge3 je5 ngo5 wui5 gaau2 dim6 gaa3 laa3.' ``` -------------------------------- ### Customize Entries: Exclude Shorter Matches Source: https://github.com/canclid/tojyutping/blob/main/README.md Demonstrates excluding a custom entry ('好學生' to None) to fall back to shorter matches or individual character pronunciations. This shows how exclusion affects the output when longer entries are not present. ```python >>> ToJyutping.get_jyutping_text('好學生') 'hou2 hok6 saang1' >>> converter_studious = ToJyutping.customize({'好學生': None}) >>> converter_studious.get_jyutping_text('好學生') 'hou3 hok6 saang1' # Using shorter matches 好學 and 生 ``` -------------------------------- ### Customize Entries: Fallback to Individual Characters Source: https://github.com/canclid/tojyutping/blob/main/README.md Shows how further customization can lead to falling back to individual character pronunciations when shorter matches are also excluded. This highlights the library's behavior when no specific entry is found. ```python >>> converter_good_student = converter_studious.customize({'好學': None}) >>> converter_good_student.get_jyutping_text('好學生') 'hou2 hok6 saang1' # Using individual character pronunciations as it can’t be decomposed further ``` -------------------------------- ### Grapheme-to-Phoneme Conversion with Punctuation Offset Source: https://github.com/canclid/tojyutping/blob/main/README.md Demonstrates converting Cantonese text to phonemes with a custom offset for punctuation IDs. This is useful for remapping punctuation categories. ```python >>> ToJyutping.g2p('咩話……你話上個月上堂學法文文法用咗 $50,000!?', offset=(1, 1, 0), puncts_offset=88) PhonemesList([(4, 39, 1), (15, 21, 2), (89,), (8, 40, 5), (15, 21, 6), (19, 77, 6), (10, 57, 3), (20, 85, 6), (19, 77, 5), (7, 62, 4), (16, 65, 6), (5, 28, 3), (4, 34, 2), (4, 34, 4), (5, 28, 3), (20, 71, 6), (17, 57, 2), (88,), (88,), (88,), (88,), (88,), (88,), (88,), (91,), (92,)]) ``` -------------------------------- ### Modify text/__init__.py for Cantonese Symbol ID Mapping Source: https://github.com/canclid/tojyutping/blob/main/Bert-VITS2-usage/README.md This diff for `text/__init__.py` updates the `cleaned_text_to_sequence` function to use ToJyutping's symbol IDs for Cantonese and modifies `get_bert` to map 'YUE' to the Chinese BERT model. ```diff # ... def cleaned_text_to_sequence(cleaned_text, tones, language): """Converts a string of text to a sequence of IDs corresponding to the symbols in the text. Args: text: string to convert to a sequence Returns: List of integers corresponding to the symbols in the text """ - phones = [_symbol_to_id[symbol] for symbol in cleaned_text] + # For Cantonese, ToJyutping.g2p already mapped the text into symbol IDs + phones = cleaned_text if language == "YUE" else [_symbol_to_id[symbol] for symbol in cleaned_text] tone_start = language_tone_start_map[language] tones = [i + tone_start for i in tones] lang_id = language_id_map[language] lang_ids = [lang_id for i in phones] return phones, tones, lang_ids def get_bert(norm_text, word2ph, language, device, style_text=None, style_weight=0.7): from .chinese_bert import get_bert_feature as zh_bert from .english_bert_mock import get_bert_feature as en_bert from .japanese_bert import get_bert_feature as jp_bert - lang_bert_func_map = {"ZH": zh_bert, "EN": en_bert, "JP": jp_bert} + # Import your Cantonese Bert model here, or reuse the Chinese Bert model: + lang_bert_func_map = {"ZH": zh_bert, "EN": en_bert, "JP": jp_bert, "YUE": zh_bert} bert = lang_bert_func_map[language]( norm_text, word2ph, device, style_text, style_weight ) return bert # ... ``` -------------------------------- ### Handling of multi-syllable characters Source: https://github.com/canclid/tojyutping/blob/main/README.md Demonstrates how the library handles characters that may have more than one syllable in their pronunciation, such as dated ligature characters. ```APIDOC ## Handling of multi-syllable characters ### Description In rare cases, the pronunciation of a single character can contain more than one syllable. This is often observed with dated ligature characters (合字) coined to represent units with SI prefixes. ### Method `ToJyutping.get_jyutping_list(text: str)` `ToJyutping.get_ipa_list(text: str)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python # Example for Jyutping ToJyutping.get_jyutping_list('一瓩') # Example for IPA ToJyutping.get_ipa_list('一瓩') ``` ### Response #### Success Response (200) For characters with multi-syllable pronunciations, the output will reflect these multiple syllables. #### Response Example ```json # Jyutping Example: [ ('一', 'jat1'), ('瓩', 'cin1 ngaa5') ] # IPA Example: [ ('一', 'jɐt̚˥'), ('瓩', 't͡sʰiːn˥.ŋaː˩˧') ] ``` ``` -------------------------------- ### Customize Jyutping Entry with Pronunciations Source: https://github.com/canclid/tojyutping/blob/main/README.md Use this method to add custom Jyutping entries or override existing ones. It's important to manually include original pronunciations if using candidate retrieval functions like get_jyutping_candidates or get_ipa_candidates, as they might be lost during customization. The library automatically handles deduplication of pronunciation values. ```python >>> 到_original_pronunciations = ToJyutping.get_jyutping_candidates('到') >>> 到_original_pronunciations [('到', ['dou3', 'dou2'])] >>> converter_dou2_dou3 = converter_lesson.customize({'到': ['dou2', *到_original_pronunciations[0][1]]}) >>> converter_dou2_dou3.get_jyutping_candidates('到') [('到', ['dou2', 'dou3'])] ``` -------------------------------- ### get_ipa_candidates Source: https://github.com/canclid/tojyutping/blob/main/README.md Retrieves a list of possible IPA pronunciations for each character in the input text, sorted by likelihood. ```APIDOC ## get_ipa_candidates ### Description Retrieves a list of possible IPA pronunciations for each character in the input text, sorted by likelihood. The first pronunciation in the list is considered the most likely. ### Method `ToJyutping.get_ipa_candidates(text: str) -> list[tuple[str, list[str]]]` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import ToJyutping ToJyutping.get_ipa_candidates('咁啱老世要求佢等陣要開會,剩低嘅嘢我會搞掂㗎喇。') ``` ### Response #### Success Response (200) A list of tuples, where each tuple contains a character and a list of its possible IPA pronunciations, ordered by likelihood. #### Response Example ```json [ ('咁', ['kɐm˧', 'kɐm˧˥', 'kɐm˥', 'kɐm˨˩']), ('啱', ['ŋaːm˥', 'aːm˥', 'ɐm˥', 'ŋɐm˥']), ('老', ['lou̯˩˧', 'lou̯˧˥']), ('世', ['sɐi̯˧', 'sɐi̯˧˥']), ('要', ['jiːu̯˥', 'jiːu̯˧', 'jiːu̯˧˥']), ('求', ['kʰɐu̯˨˩']), ('佢', ['kʰɵy̑˩˧', 'hɵy̑˩˧']), ('等', ['tɐŋ˧˥']), ('陣', ['t͡sɐn˨', 't͡sɐn˧˥']), ('要', ['jiːu̯˧', 'jiːu̯˧˥', 'jiːu̯˥']), ('開', ['hɔːi̯˥']), ('會', ['wuːi̯˧˥', 'wuːi̯˩˧', 'wuːi̯˨', 'wuːi̯˧', 'kʰuːi̯˧˥', 'kʰuːi̯˧', 'kʷʰuːi̯˧˥']), (',', []), ('剩', ['t͡seŋ˨', 'seŋ˨']), ('低', ['tɐi̯˥']), ('嘅', ['kɛː˧', 'kɛː˧˥', 'kʰɔːi̯˧˥', 'kʰɔːi̯˧']), ('嘢', ['jɛː˩˧', 'ɛː˩˧']), ('我', ['ŋɔː˩˧', 'ɔː˩˧']), ('會', ['wuːi̯˩˧', 'wuːi̯˨', 'wuːi̯˧˥', 'wuːi̯˧', 'kʰuːi̯˧˥', 'kʰuːi̯˧', 'kʷʰuːi̯˧˥']), ('搞', ['kaːu̯˧˥']), ('掂', ['tiːm˨', 'tiːm˧', 'tiːm˥']), ('㗎', ['kaː˧', 'kɐ˧', 'kaː˧˥', 'kaː˥', 'kaː˨˩']), ('喇', ['laː˧', 'laː˥', 'laːk̚˧', 'laː˩˧', 'laːt̚˧']), ('。', []) ] ``` ``` -------------------------------- ### Grapheme-to-Phoneme Conversion with Tone in Same Sequence Source: https://github.com/canclid/tojyutping/blob/main/README.md Converts text to phonemes, ensuring tone values are in the same sequence as onsets and rhymes, outputting integers from 8 to 100. Useful when a unified sequence is required. ```python >>> ToJyutping.g2p('咩話……你話上個月上堂學法文文法用咗 $50,000!?', tone_same_seq=True) PhonemesList([(11, 46, 95), (22, 28, 96), (2,), (15, 47, 99), (22, 28, 100), (26, 84, 100), (17, 64, 97), (27, 92, 100), (26, 84, 99), (14, 69, 98), (23, 72, 100), (12, 35, 97), (11, 41, 96), (11, 41, 98), (12, 35, 97), (27, 78, 100), (24, 64, 96), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (4,), (5,)]) ``` -------------------------------- ### Basic Grapheme-to-Phoneme Conversion Source: https://github.com/canclid/tojyutping/blob/main/README.md Converts a Cantonese string into a list of phoneme tuples (onset, rhyme, tone) and associated metadata. Handles punctuations as singletons. Useful for text-to-speech and automatic speech recognition. ```python >>> ToJyutping.g2p('咩話……你話上個月上堂學法文文法用咗 $50,000!?') PhonemesList( [(11, 46, 1), (22, 28, 2), (2,), (15, 47, 5), (22, 28, 6), (26, 84, 6), (17, 64, 3), (27, 92, 6), (26, 84, 5), (14, 69, 4), (23, 72, 6), (12, 35, 3), (11, 41, 2), (11, 41, 4), (12, 35, 3), (27, 78, 6), (24, 64, 2), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (4,), (5,)], segmentals=[11, 46, 22, 28, 2, 15, 47, 22, 28, 26, 84, 17, 64, 27, 92, 26, 84, 14, 69, 23, 72, 12, 35, 11, 41, 11, 41, 12, 35, 27, 78, 24, 64, 1, 1, 1, 1, 1, 1, 1, 4, 5], tones=[1, 1, 2, 2, 0, 5, 5, 6, 6, 6, 6, 3, 3, 6, 6, 5, 5, 4, 4, 6, 6, 3, 3, 2, 2, 4, 4, 3, 3, 6, 6, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], lengths=[2, 2, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1] ) ``` -------------------------------- ### Modify cleaner.py for Cantonese Text Normalization Source: https://github.com/canclid/tojyutping/blob/main/Bert-VITS2-usage/README.md This snippet shows the additions to `cleaner.py` to integrate ToJyutping for Cantonese text. It handles Unicode normalization and uses `ToJyutping.g2p` for phoneme conversion, returning normalized text, segmentals, tones, and lengths. ```diff +import ToJyutping +import unicodedata + from text import chinese, japanese, english, cleaned_text_to_sequence +from text.symbols import symbols, yue_offset def clean_text(text, language): + text = unicodedata.normalize("NFC", text) + if language == "YUE": + # Already handles punctuation and maps to symbol IDs internally + phonemes = ToJyutping.g2p(text, offset=(yue_offset, yue_offset, 1)) + norm_text = "".join( + char if length > 1 else + # Convert punctuation ID back to one of … . , ! ? - ' + symbols[phonemes.segmentals[sum(phonemes.lengths[:i])]] if length == 1 else "" + for i, (char, length) in enumerate(zip(text, phonemes.lengths, strict=True)) + ) + lengths = [length for length in phonemes.lengths if length > 0] + return norm_text, phonemes.segmentals, phonemes.tones, lengths language_module = language_module_map[language] norm_text = language_module.text_normalize(text) phones, tones, word2ph = language_module.g2p(norm_text) return norm_text, phones, tones, word2ph # ... ``` -------------------------------- ### Handle multi-syllable characters with Jyutping Source: https://github.com/canclid/tojyutping/blob/main/README.md Shows how ToJyutping handles characters that have multiple Jyutping syllables, such as the ligature '瓩'. ```python >>> ToJyutping.get_jyutping_list('一瓩') [('一', 'jat1'), ('瓩', 'cin1 ngaa5')] ``` -------------------------------- ### Default Phoneme List Source: https://github.com/canclid/tojyutping/blob/main/README.md Displays the default phoneme list structure used in the conversion. This list contains tuples representing onsets, rhymes, and tones. ```python PhonemesList([(103, 238, 301), (114, 220, 302), (2,), (107, 239, 305), (114, 220, 306), (118, 276, 306), (109, 256, 303), (119, 284, 306), (118, 276, 305), (106, 261, 304), (115, 264, 306), (104, 227, 303), (103, 233, 302), (103, 233, 304), (104, 227, 303), (119, 270, 306), (116, 256, 302), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (4,), (5,)]) ``` -------------------------------- ### Configure for Cantonese Only Source: https://github.com/canclid/tojyutping/blob/main/Bert-VITS2-usage/README.md Adapts the symbol and language configurations to include only Cantonese, removing other language definitions. This is useful if the project focuses solely on Cantonese speech synthesis. ```diff -punctuation = ["!", "?", "…", ",", ".", "'", "-"] +# Follows the order in ToJyutping.g2p +punctuation = ["…", ".", ",", "!", "?", "-", "'"] pu_symbols = punctuation + ["SP", "UNK"] pad = "_" -# chinese -zh_symbols = [ -# ... -] -num_en_tones = 4 +# Cantonese: Symbols are already mapped internally in ToJyutping.g2p +# Generates identity mappings for `len(symbols)` to work correctly +yue_symbols = list(range(87)) +num_yue_tones = 6 # combine all symbols -normal_symbols = sorted(set(zh_symbols + ja_symbols + en_symbols)) -symbols = [pad] + normal_symbols + pu_symbols +symbols = [pad] + pu_symbols +yue_offset = len(symbols) # For use by ToJyutping.g2p in cleaner.py +symbols += yue_symbols sil_phonemes_ids = [symbols.index(i) for i in pu_symbols] # combine all tones -num_tones = num_zh_tones + num_ja_tones + num_en_tones +num_tones = num_yue_tones # language maps -language_id_map = {"ZH": 0, "JP": 1, "EN": 2} +language_id_map = {"YUE": 0} num_languages = len(language_id_map.keys()) language_tone_start_map = { - "ZH": 0, - "JP": num_zh_tones, - "EN": num_zh_tones + num_ja_tones, + "YUE": 0, } -if __name__ == "__main__": - a = set(zh_symbols) - b = set(en_symbols) - print(sorted(a & b)) ``` -------------------------------- ### Chaining Converters: Unaffected Default Source: https://github.com/canclid/tojyutping/blob/main/README.md Confirms that chaining custom converters does not affect the original default converter. The original `ToJyutping.get_jyutping_text` call remains unchanged. ```python >>> ToJyutping.get_jyutping_text('上堂終於講到分數') 'soeng5 tong4 zung1 jyu1 gong2 dou3 fan1 sou3' # Also not affected ``` -------------------------------- ### Convert Jyutping to IPA Source: https://github.com/canclid/tojyutping/blob/main/README.md Use the `jyutping2ipa` helper function to convert Jyutping strings to IPA. This function ignores punctuation and throws an error for invalid Jyutping inputs. ```python >>> ToJyutping.jyutping2ipa('jat1') 'jɐt̚˥' ``` ```python >>> ToJyutping.jyutping2ipa('cin1 ngaa5') 't͡sʰiːn˥.ŋaː˩˧' ``` -------------------------------- ### Customizing Punctuation with puncts_map Source: https://github.com/canclid/tojyutping/blob/main/README.md Specify a custom mapping for punctuations using the `puncts_map` option. Ensure `unknown_id` is provided when using `puncts_map`. Punctuation pronunciations cannot be overridden with this option. ```python >>> ToJyutping.g2p('咩話……你話上個月上堂學法文文法用咗 $50,000!?', puncts_map={'…': 2, '$': 3, '!': 4, '?': 5}, unknown_id=1) PhonemesList([(9, 44, 1), (20, 26, 2), (2,), (13, 45, 5), (20, 26, 6), (24, 82, 6), (15, 62, 3), (25, 90, 6), (24, 82, 5), (12, 67, 4), (21, 70, 6), (10, 33, 3), (9, 39, 2), (9, 39, 4), (10, 33, 3), (25, 76, 6), (22, 62, 2), (3,), (1,), (1,), (1,), (1,), (1,), (1,), (4,), (5,)]) ``` -------------------------------- ### Customization Limitation: Longer Built-in Entries Source: https://github.com/canclid/tojyutping/blob/main/README.md Demonstrates a limitation where longer built-in entries are prioritized over custom overrides for shorter segments. '上堂' is not overridden by '上' customization because '上堂' is a longer, existing entry. ```python >>> converter_dou2.get_jyutping_text('笑到轆地') 'siu3 dou3 luk1 dei2' >>> converter_None.get_jyutping_text('笑到轆地') 'siu3 dou3 luk1 dei2' >>> converter_another_lesson = ToJyutping.customize({'上': None, '分': 'fan6'}) >>> converter_another_lesson.get_jyutping_text('上堂終於講到分數') 'soeng5 tong4 zung1 jyu1 gong2 dou3 fan6 sou3' >>> # In the second example, their isn’t an entry for 分數, so 分 is patched successfully. However, this is not the case for 上 since the longer built-in entry 上堂 is prioritized. ```