Committed by
GitHub
Build Android TTS APKs for coqui-ai/TTS models (#704)
正在显示
7 个修改的文件
包含
89 行增加
和
115 行删除
| @@ -186,6 +186,12 @@ class MainActivity : AppCompatActivity() { | @@ -186,6 +186,12 @@ class MainActivity : AppCompatActivity() { | ||
| 186 | // ruleFsts = "vits-zh-aishell3/rule.fst" | 186 | // ruleFsts = "vits-zh-aishell3/rule.fst" |
| 187 | // lexicon = "lexicon.txt" | 187 | // lexicon = "lexicon.txt" |
| 188 | 188 | ||
| 189 | + // Example 4: | ||
| 190 | + // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-coqui-de-css10.tar.bz2 | ||
| 191 | + // modelDir = "vits-coqui-de-css10" | ||
| 192 | + // modelName = "model.onnx" | ||
| 193 | + // lang = "deu" | ||
| 194 | + | ||
| 189 | if (dataDir != null) { | 195 | if (dataDir != null) { |
| 190 | val newDir = copyDataDir(modelDir) | 196 | val newDir = copyDataDir(modelDir) |
| 191 | modelDir = newDir + "/" + modelDir | 197 | modelDir = newDir + "/" + modelDir |
| @@ -6,15 +6,18 @@ import androidx.appcompat.app.AppCompatActivity | @@ -6,15 +6,18 @@ import androidx.appcompat.app.AppCompatActivity | ||
| 6 | import android.os.Bundle | 6 | import android.os.Bundle |
| 7 | import android.speech.tts.TextToSpeech | 7 | import android.speech.tts.TextToSpeech |
| 8 | 8 | ||
| 9 | -class GetSampleText : Activity() { | ||
| 10 | - override fun onCreate(savedInstanceState: Bundle?) { | ||
| 11 | - super.onCreate(savedInstanceState) | ||
| 12 | - var result = TextToSpeech.LANG_AVAILABLE | ||
| 13 | - var text: String = "" | ||
| 14 | - when(TtsEngine.lang) { | 9 | +fun getSampleText(lang: String): String { |
| 10 | + var text = "" | ||
| 11 | + when (lang) { | ||
| 15 | "ara" -> { | 12 | "ara" -> { |
| 16 | text = "هذا هو محرك تحويل النص إلى كلام باستخدام الجيل القادم من كالدي" | 13 | text = "هذا هو محرك تحويل النص إلى كلام باستخدام الجيل القادم من كالدي" |
| 17 | } | 14 | } |
| 15 | + "ben" -> { | ||
| 16 | + text = "এটি একটি টেক্সট-টু-স্পীচ ইঞ্জিন যা পরবর্তী প্রজন্মের কালডি ব্যবহার করে" | ||
| 17 | + } | ||
| 18 | + "bul" -> { | ||
| 19 | + text = "Това е машина за преобразуване на текст в реч, използваща Kaldi от следващо поколение" | ||
| 20 | + } | ||
| 18 | "cat" -> { | 21 | "cat" -> { |
| 19 | text = "Aquest és un motor de text a veu que utilitza Kaldi de nova generació" | 22 | text = "Aquest és un motor de text a veu que utilitza Kaldi de nova generació" |
| 20 | } | 23 | } |
| @@ -33,11 +36,20 @@ class GetSampleText : Activity() { | @@ -33,11 +36,20 @@ class GetSampleText : Activity() { | ||
| 33 | "eng" -> { | 36 | "eng" -> { |
| 34 | text = "This is a text-to-speech engine using next generation Kaldi" | 37 | text = "This is a text-to-speech engine using next generation Kaldi" |
| 35 | } | 38 | } |
| 39 | + "est" -> { | ||
| 40 | + text = "See on teksti kõneks muutmise mootor, mis kasutab järgmise põlvkonna Kaldi" | ||
| 41 | + } | ||
| 36 | "fin" -> { | 42 | "fin" -> { |
| 37 | text = "Tämä on tekstistä puheeksi -moottori, joka käyttää seuraavan sukupolven kaldia" | 43 | text = "Tämä on tekstistä puheeksi -moottori, joka käyttää seuraavan sukupolven kaldia" |
| 38 | } | 44 | } |
| 39 | "fra" -> { | 45 | "fra" -> { |
| 40 | - text = "Il s'agit d'un moteur de synthèse vocale utilisant Kaldi de nouvelle génération." | 46 | + text = "Il s'agit d'un moteur de synthèse vocale utilisant Kaldi de nouvelle génération" |
| 47 | + } | ||
| 48 | + "gle" -> { | ||
| 49 | + text = "Is inneall téacs-go-hurlabhra é seo a úsáideann Kaldi den chéad ghlúin eile" | ||
| 50 | + } | ||
| 51 | + "hrv" -> { | ||
| 52 | + text = "Ovo je mehanizam za pretvaranje teksta u govor koji koristi Kaldi sljedeće generacije" | ||
| 41 | } | 53 | } |
| 42 | "hun" -> { | 54 | "hun" -> { |
| 43 | text = "Ez egy szövegfelolvasó motor a következő generációs kaldi használatával" | 55 | text = "Ez egy szövegfelolvasó motor a következő generációs kaldi használatával" |
| @@ -54,6 +66,15 @@ class GetSampleText : Activity() { | @@ -54,6 +66,15 @@ class GetSampleText : Activity() { | ||
| 54 | "kaz" -> { | 66 | "kaz" -> { |
| 55 | text = "Бұл келесі буын kaldi көмегімен мәтіннен сөйлеуге арналған қозғалтқыш" | 67 | text = "Бұл келесі буын kaldi көмегімен мәтіннен сөйлеуге арналған қозғалтқыш" |
| 56 | } | 68 | } |
| 69 | + "mlt" -> { | ||
| 70 | + text = "Din hija magna text-to-speech li tuża Kaldi tal-ġenerazzjoni li jmiss" | ||
| 71 | + } | ||
| 72 | + "lav" -> { | ||
| 73 | + text = "Šis ir teksta pārvēršanas runā dzinējs, kas izmanto nākamās paaudzes Kaldi" | ||
| 74 | + } | ||
| 75 | + "lit" -> { | ||
| 76 | + text = "Tai teksto į kalbą variklis, kuriame naudojamas naujos kartos Kaldi" | ||
| 77 | + } | ||
| 57 | "ltz" -> { | 78 | "ltz" -> { |
| 58 | text = "Dëst ass en Text-zu-Speech-Motor mat der nächster Generatioun Kaldi" | 79 | text = "Dëst ass en Text-zu-Speech-Motor mat der nächster Generatioun Kaldi" |
| 59 | } | 80 | } |
| @@ -81,6 +102,9 @@ class GetSampleText : Activity() { | @@ -81,6 +102,9 @@ class GetSampleText : Activity() { | ||
| 81 | "slk" -> { | 102 | "slk" -> { |
| 82 | text = "Toto je nástroj na prevod textu na reč využívajúci kaldi novej generácie" | 103 | text = "Toto je nástroj na prevod textu na reč využívajúci kaldi novej generácie" |
| 83 | } | 104 | } |
| 105 | + "slv" -> { | ||
| 106 | + text = "To je mehanizem za pretvorbo besedila v govor, ki uporablja Kaldi naslednje generacije" | ||
| 107 | + } | ||
| 84 | "spa" -> { | 108 | "spa" -> { |
| 85 | text = "Este es un motor de texto a voz que utiliza kaldi de próxima generación." | 109 | text = "Este es un motor de texto a voz que utiliza kaldi de próxima generación." |
| 86 | } | 110 | } |
| @@ -105,9 +129,17 @@ class GetSampleText : Activity() { | @@ -105,9 +129,17 @@ class GetSampleText : Activity() { | ||
| 105 | "zho", "cmn" -> { | 129 | "zho", "cmn" -> { |
| 106 | text = "使用新一代卡尔迪的语音合成引擎" | 130 | text = "使用新一代卡尔迪的语音合成引擎" |
| 107 | } | 131 | } |
| 108 | - else -> { | ||
| 109 | - result = TextToSpeech.LANG_NOT_SUPPORTED | ||
| 110 | } | 132 | } |
| 133 | + return text | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +class GetSampleText : Activity() { | ||
| 137 | + override fun onCreate(savedInstanceState: Bundle?) { | ||
| 138 | + super.onCreate(savedInstanceState) | ||
| 139 | + var result = TextToSpeech.LANG_AVAILABLE | ||
| 140 | + var text: String = getSampleText(TtsEngine.lang ?: "") | ||
| 141 | + if (text.isEmpty()) { | ||
| 142 | + result = TextToSpeech.LANG_NOT_SUPPORTED | ||
| 111 | } | 143 | } |
| 112 | 144 | ||
| 113 | val intent = Intent().apply{ | 145 | val intent = Intent().apply{ |
| @@ -73,109 +73,7 @@ class MainActivity : ComponentActivity() { | @@ -73,109 +73,7 @@ class MainActivity : ComponentActivity() { | ||
| 73 | ) | 73 | ) |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | - var testTextContent = "" | ||
| 77 | - | ||
| 78 | - when(TtsEngine.lang) { | ||
| 79 | - "ara" -> { | ||
| 80 | - testTextContent = "هذا هو محرك تحويل النص إلى كلام باستخدام الجيل القادم من كالدي" | ||
| 81 | - } | ||
| 82 | - "cat" -> { | ||
| 83 | - testTextContent = "Aquest és un motor de testText a veu que utilitza Kaldi de nova generació" | ||
| 84 | - } | ||
| 85 | - "ces" -> { | ||
| 86 | - testTextContent = "Toto je převodník testTextu na řeč využívající novou generaci kaldi" | ||
| 87 | - } | ||
| 88 | - "dan" -> { | ||
| 89 | - testTextContent = "Dette er en tekst til tale-motor, der bruger næste generation af kaldi" | ||
| 90 | - } | ||
| 91 | - "deu" -> { | ||
| 92 | - testTextContent = "Dies ist eine testText-to-Speech-Engine, die Kaldi der nächsten Generation verwendet" | ||
| 93 | - } | ||
| 94 | - "ell" -> { | ||
| 95 | - testTextContent = "Αυτή είναι μια μηχανή κειμένου σε ομιλία που χρησιμοποιεί kaldi επόμενης γενιάς" | ||
| 96 | - } | ||
| 97 | - "eng" -> { | ||
| 98 | - testTextContent = "This is a testText-to-speech engine using next generation Kaldi" | ||
| 99 | - } | ||
| 100 | - "fas" -> { | ||
| 101 | - testTextContent = "این یک موتور تبدیل متن به گفتار است برپایه نسخه پیشگام کالدی" | ||
| 102 | - } | ||
| 103 | - "fin" -> { | ||
| 104 | - testTextContent = "Tämä on tekstistä puheeksi -moottori, joka käyttää seuraavan sukupolven kaldia" | ||
| 105 | - } | ||
| 106 | - "fra" -> { | ||
| 107 | - testTextContent = "Il s'agit d'un moteur de synthèse vocale utilisant Kaldi de nouvelle génération." | ||
| 108 | - } | ||
| 109 | - "hun" -> { | ||
| 110 | - testTextContent = "Ez egy szövegfelolvasó motor a következő generációs kaldi használatával" | ||
| 111 | - } | ||
| 112 | - "isl" -> { | ||
| 113 | - testTextContent = "Þetta er testTexta í tal vél sem notar næstu kynslóð kaldi" | ||
| 114 | - } | ||
| 115 | - "ita" -> { | ||
| 116 | - testTextContent = "Questo è un motore di sintesi vocale che utilizza kaldi di nuova generazione" | ||
| 117 | - } | ||
| 118 | - "kat" -> { | ||
| 119 | - testTextContent = "ეს არის ტექსტიდან მეტყველების ძრავა შემდეგი თაობის კალდის გამოყენებით" | ||
| 120 | - } | ||
| 121 | - "kaz" -> { | ||
| 122 | - testTextContent = "Бұл келесі буын kaldi көмегімен мәтіннен сөйлеуге арналған қозғалтқыш" | ||
| 123 | - } | ||
| 124 | - "ltz" -> { | ||
| 125 | - testTextContent = "Dëst ass en testText-zu-Speech-Motor mat der nächster Generatioun Kaldi" | ||
| 126 | - } | ||
| 127 | - "nep" -> { | ||
| 128 | - testTextContent = "यो अर्को पुस्ता काल्डी प्रयोग गरेर स्पीच इन्जिनको पाठ हो" | ||
| 129 | - } | ||
| 130 | - "nld" -> { | ||
| 131 | - testTextContent = "Dit is een tekst-naar-spraak-engine die gebruik maakt van Kaldi van de volgende generatie" | ||
| 132 | - } | ||
| 133 | - "nor" -> { | ||
| 134 | - testTextContent = "Dette er en tekst til tale-motor som bruker neste generasjons kaldi" | ||
| 135 | - } | ||
| 136 | - "pol" -> { | ||
| 137 | - testTextContent = "Jest to silnik syntezatora mowy wykorzystujący Kaldi nowej generacji" | ||
| 138 | - } | ||
| 139 | - "por" -> { | ||
| 140 | - testTextContent = "Este é um mecanismo de conversão de testTexto em fala usando Kaldi de próxima geração" | ||
| 141 | - } | ||
| 142 | - "ron" -> { | ||
| 143 | - testTextContent = "Acesta este un motor testText to speech care folosește generația următoare de kadi" | ||
| 144 | - } | ||
| 145 | - "rus" -> { | ||
| 146 | - testTextContent = "Это движок преобразования текста в речь, использующий Kaldi следующего поколения." | ||
| 147 | - } | ||
| 148 | - "slk" -> { | ||
| 149 | - testTextContent = "Toto je nástroj na prevod testTextu na reč využívajúci kaldi novej generácie" | ||
| 150 | - } | ||
| 151 | - "spa" -> { | ||
| 152 | - testTextContent = "Este es un motor de testTexto a voz que utiliza kaldi de próxima generación." | ||
| 153 | - } | ||
| 154 | - "srp" -> { | ||
| 155 | - testTextContent = "Ово је механизам за претварање текста у говор који користи калди следеће генерације" | ||
| 156 | - } | ||
| 157 | - "swa" -> { | ||
| 158 | - testTextContent = "Haya ni maandishi kwa injini ya hotuba kwa kutumia kizazi kijacho kaldi" | ||
| 159 | - } | ||
| 160 | - "swe" -> { | ||
| 161 | - testTextContent = "Detta är en testText till tal-motor som använder nästa generations kaldi" | ||
| 162 | - } | ||
| 163 | - "tur" -> { | ||
| 164 | - testTextContent = "Bu, yeni nesil kaldi'yi kullanan bir metinden konuşmaya motorudur" | ||
| 165 | - } | ||
| 166 | - "ukr" -> { | ||
| 167 | - testTextContent = "Це механізм перетворення тексту на мовлення, який використовує kaldi нового покоління" | ||
| 168 | - } | ||
| 169 | - "vie" -> { | ||
| 170 | - testTextContent = "Đây là công cụ chuyển văn bản thành giọng nói sử dụng kaldi thế hệ tiếp theo" | ||
| 171 | - } | ||
| 172 | - "zho", "cmn" -> { | ||
| 173 | - testTextContent = "使用新一代卡尔迪的语音合成引擎" | ||
| 174 | - } | ||
| 175 | - else -> { | ||
| 176 | - testTextContent = "" | ||
| 177 | - } | ||
| 178 | - } | 76 | + val testTextContent = getSampleText(TtsEngine.lang ?: "") |
| 179 | 77 | ||
| 180 | var testText by remember { mutableStateOf(testTextContent) } | 78 | var testText by remember { mutableStateOf(testTextContent) } |
| 181 | 79 |
| @@ -57,6 +57,7 @@ object TtsEngine { | @@ -57,6 +57,7 @@ object TtsEngine { | ||
| 57 | // Please enable one and only one of the examples below | 57 | // Please enable one and only one of the examples below |
| 58 | 58 | ||
| 59 | // Example 1: | 59 | // Example 1: |
| 60 | + // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-vctk.tar.bz2 | ||
| 60 | // modelDir = "vits-vctk" | 61 | // modelDir = "vits-vctk" |
| 61 | // modelName = "vits-vctk.onnx" | 62 | // modelName = "vits-vctk.onnx" |
| 62 | // lexicon = "lexicon.txt" | 63 | // lexicon = "lexicon.txt" |
| @@ -71,11 +72,19 @@ object TtsEngine { | @@ -71,11 +72,19 @@ object TtsEngine { | ||
| 71 | // lang = "eng" | 72 | // lang = "eng" |
| 72 | 73 | ||
| 73 | // Example 3: | 74 | // Example 3: |
| 75 | + // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-icefall-zh-aishell3.tar.bz2 | ||
| 74 | // modelDir = "vits-zh-aishell3" | 76 | // modelDir = "vits-zh-aishell3" |
| 75 | // modelName = "vits-aishell3.onnx" | 77 | // modelName = "vits-aishell3.onnx" |
| 76 | // ruleFsts = "vits-zh-aishell3/rule.fst" | 78 | // ruleFsts = "vits-zh-aishell3/rule.fst" |
| 77 | // lexicon = "lexicon.txt" | 79 | // lexicon = "lexicon.txt" |
| 78 | // lang = "zho" | 80 | // lang = "zho" |
| 81 | + | ||
| 82 | + // Example 4: | ||
| 83 | + // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-coqui-de-css10.tar.bz2 | ||
| 84 | + // This model does not need lexicon or dataDir | ||
| 85 | + // modelDir = "vits-coqui-de-css10" | ||
| 86 | + // modelName = "model.onnx" | ||
| 87 | + // lang = "deu" | ||
| 79 | } | 88 | } |
| 80 | 89 | ||
| 81 | 90 |
| @@ -59,7 +59,7 @@ sed -i.bak s/"lang = null"/"lang = \"$lang_iso_639_3\""/ ./TtsEngine.kt | @@ -59,7 +59,7 @@ sed -i.bak s/"lang = null"/"lang = \"$lang_iso_639_3\""/ ./TtsEngine.kt | ||
| 59 | {% if tts_model.data_dir %} | 59 | {% if tts_model.data_dir %} |
| 60 | data_dir={{ tts_model.data_dir }} | 60 | data_dir={{ tts_model.data_dir }} |
| 61 | sed -i.bak s%"dataDir = null"%"dataDir = \"$data_dir\""% ./TtsEngine.kt | 61 | sed -i.bak s%"dataDir = null"%"dataDir = \"$data_dir\""% ./TtsEngine.kt |
| 62 | -{% else %} | 62 | +{% elif not tts_model.is_char %} |
| 63 | sed -i.bak s/"lexicon = null"/"lexicon = \"lexicon.txt\""/ ./TtsEngine.kt | 63 | sed -i.bak s/"lexicon = null"/"lexicon = \"lexicon.txt\""/ ./TtsEngine.kt |
| 64 | {% endif %} | 64 | {% endif %} |
| 65 | 65 |
| @@ -57,7 +57,7 @@ sed -i.bak s/"modelName = null"/"modelName = \"$model_name\""/ ./MainActivity.kt | @@ -57,7 +57,7 @@ sed -i.bak s/"modelName = null"/"modelName = \"$model_name\""/ ./MainActivity.kt | ||
| 57 | {% if tts_model.data_dir %} | 57 | {% if tts_model.data_dir %} |
| 58 | data_dir={{ tts_model.data_dir }} | 58 | data_dir={{ tts_model.data_dir }} |
| 59 | sed -i.bak s%"dataDir = null"%"dataDir = \"$data_dir\""% ./MainActivity.kt | 59 | sed -i.bak s%"dataDir = null"%"dataDir = \"$data_dir\""% ./MainActivity.kt |
| 60 | -{% else %} | 60 | +{% elif not tts_model.is_char %} |
| 61 | sed -i.bak s/"lexicon = null"/"lexicon = \"lexicon.txt\""/ ./MainActivity.kt | 61 | sed -i.bak s/"lexicon = null"/"lexicon = \"lexicon.txt\""/ ./MainActivity.kt |
| 62 | {% endif %} | 62 | {% endif %} |
| 63 | 63 |
| @@ -34,6 +34,7 @@ class TtsModel: | @@ -34,6 +34,7 @@ class TtsModel: | ||
| 34 | lang: str = "" # en, zh, fr, de, etc. | 34 | lang: str = "" # en, zh, fr, de, etc. |
| 35 | rule_fsts: Optional[List[str]] = None | 35 | rule_fsts: Optional[List[str]] = None |
| 36 | data_dir: Optional[str] = None | 36 | data_dir: Optional[str] = None |
| 37 | + is_char: bool = False | ||
| 37 | lang_iso_639_3: str = "" | 38 | lang_iso_639_3: str = "" |
| 38 | 39 | ||
| 39 | 40 | ||
| @@ -57,7 +58,35 @@ def get_coqui_models() -> List[TtsModel]: | @@ -57,7 +58,35 @@ def get_coqui_models() -> List[TtsModel]: | ||
| 57 | m.model_name = "model.onnx" | 58 | m.model_name = "model.onnx" |
| 58 | m.lang = "en" | 59 | m.lang = "en" |
| 59 | 60 | ||
| 60 | - return models | 61 | + character_models = [ |
| 62 | + TtsModel(model_dir="vits-coqui-bg-cv", lang="bg"), | ||
| 63 | + TtsModel(model_dir="vits-coqui-bn-custom_female", lang="bn"), | ||
| 64 | + TtsModel(model_dir="vits-coqui-cs-cv", lang="cs"), | ||
| 65 | + TtsModel(model_dir="vits-coqui-da-cv", lang="da"), | ||
| 66 | + TtsModel(model_dir="vits-coqui-de-css10", lang="de"), | ||
| 67 | + TtsModel(model_dir="vits-coqui-es-css10", lang="es"), | ||
| 68 | + TtsModel(model_dir="vits-coqui-et-cv", lang="et"), | ||
| 69 | + TtsModel(model_dir="vits-coqui-fi-css10", lang="fi"), | ||
| 70 | + TtsModel(model_dir="vits-coqui-fr-css10", lang="fr"), | ||
| 71 | + TtsModel(model_dir="vits-coqui-ga-cv", lang="ga"), | ||
| 72 | + TtsModel(model_dir="vits-coqui-hr-cv", lang="hr"), | ||
| 73 | + TtsModel(model_dir="vits-coqui-lt-cv", lang="lt"), | ||
| 74 | + TtsModel(model_dir="vits-coqui-lv-cv", lang="lv"), | ||
| 75 | + TtsModel(model_dir="vits-coqui-mt-cv", lang="mt"), | ||
| 76 | + TtsModel(model_dir="vits-coqui-nl-css10", lang="nl"), | ||
| 77 | + TtsModel(model_dir="vits-coqui-pl-mai_female", lang="pl"), | ||
| 78 | + TtsModel(model_dir="vits-coqui-pt-cv", lang="pt"), | ||
| 79 | + TtsModel(model_dir="vits-coqui-ro-cv", lang="ro"), | ||
| 80 | + TtsModel(model_dir="vits-coqui-sk-cv", lang="sk"), | ||
| 81 | + TtsModel(model_dir="vits-coqui-sl-cv", lang="sl"), | ||
| 82 | + TtsModel(model_dir="vits-coqui-sv-cv", lang="sv"), | ||
| 83 | + TtsModel(model_dir="vits-coqui-uk-mai", lang="uk"), | ||
| 84 | + ] | ||
| 85 | + for m in character_models: | ||
| 86 | + m.is_char = True | ||
| 87 | + m.model_name = "model.onnx" | ||
| 88 | + | ||
| 89 | + return models + character_models | ||
| 61 | 90 | ||
| 62 | 91 | ||
| 63 | def get_piper_models() -> List[TtsModel]: | 92 | def get_piper_models() -> List[TtsModel]: |
-
请 注册 或 登录 后发表评论