eSpeak NG is an open source speech synthesizer that supports more than hundred languages and accents.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VoiceVariantPreference.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. * Copyright (C) 2022 Beka Gozalishvili
  3. * Copyright (C) 2013 Reece H. Dunn
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package com.reecedunn.espeak.preference;
  18. import android.app.Activity;
  19. import android.content.Context;
  20. import android.content.DialogInterface;
  21. import android.content.SharedPreferences;
  22. import android.os.Build;
  23. import android.preference.DialogPreference;
  24. import android.preference.PreferenceManager;
  25. import android.util.AttributeSet;
  26. import android.view.LayoutInflater;
  27. import android.view.View;
  28. import android.view.ViewGroup;
  29. import android.widget.AdapterView;
  30. import android.widget.ArrayAdapter;
  31. import android.widget.Spinner;
  32. import android.widget.TextView;
  33. import com.reecedunn.espeak.R;
  34. import com.reecedunn.espeak.ResourceIdListAdapter;
  35. import com.reecedunn.espeak.VoiceSettings;
  36. import com.reecedunn.espeak.VoiceVariant;
  37. public class VoiceVariantPreference extends DialogPreference {
  38. private Spinner mCategory;
  39. private Spinner mVariant;
  40. private int mCategoryIndex = 0;
  41. private int mVariantIndex = 0;
  42. static class ViewHolder
  43. {
  44. public TextView text;
  45. }
  46. private class VariantData {
  47. private final int name;
  48. private final Object arg;
  49. private final VoiceVariant variant;
  50. protected VariantData(int name, String variant) {
  51. this(name, null, variant);
  52. }
  53. protected VariantData(int name, Object arg, String variant) {
  54. this.name = name;
  55. this.arg = arg;
  56. this.variant = VoiceVariant.parseVoiceVariant(variant);
  57. }
  58. public String getDisplayName(Context context) {
  59. String text = context.getText(name).toString();
  60. if (arg == null) {
  61. return text;
  62. }
  63. return String.format(text, arg);
  64. }
  65. public VoiceVariant getVariant() {
  66. return variant;
  67. }
  68. }
  69. public class VariantDataListAdapter extends ArrayAdapter<VariantData>
  70. {
  71. private final LayoutInflater mInflater;
  72. public VariantDataListAdapter(Activity context, VariantData[] resources)
  73. {
  74. super(context, android.R.layout.simple_list_item_1, resources);
  75. mInflater = context.getLayoutInflater();
  76. }
  77. @Override
  78. public View getView(int position, View convertView, ViewGroup parent)
  79. {
  80. ViewHolder holder;
  81. if (convertView == null)
  82. {
  83. convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
  84. holder = new ViewHolder();
  85. holder.text = (TextView)convertView.findViewById(android.R.id.text1);
  86. convertView.setTag(holder);
  87. }
  88. else
  89. {
  90. holder = (ViewHolder)convertView.getTag();
  91. }
  92. holder.text.setText(getItem(position).getDisplayName(getContext()));
  93. return convertView;
  94. }
  95. @Override
  96. public View getDropDownView(int position, View convertView, ViewGroup parent)
  97. {
  98. return getView(position, convertView, parent);
  99. }
  100. }
  101. private Integer[] categories = {
  102. R.string.variant_male,
  103. R.string.variant_female,
  104. R.string.variant_klatt,
  105. R.string.variant_nvda,
  106. R.string.variant_young,
  107. R.string.variant_old,
  108. R.string.variant_croak,
  109. R.string.variant_whisper,
  110. };
  111. private VariantData[][] variants = {
  112. { // Male
  113. new VariantData(R.string.variant_default, "male"),
  114. new VariantData(R.string.variant_n, 1, "m1"),
  115. new VariantData(R.string.variant_n, 2, "m2"),
  116. new VariantData(R.string.variant_n, 3, "m3"),
  117. new VariantData(R.string.variant_n, 4, "m4"),
  118. new VariantData(R.string.variant_n, 5, "m5"),
  119. new VariantData(R.string.variant_n, 6, "m6"),
  120. new VariantData(R.string.variant_n, 7, "m7"),
  121. new VariantData(R.string.variant_n, 8, "m8"),
  122. },{ // Female
  123. new VariantData(R.string.variant_default, "female"),
  124. new VariantData(R.string.variant_n, 1, "f1"),
  125. new VariantData(R.string.variant_n, 2, "f2"),
  126. new VariantData(R.string.variant_n, 3, "f3"),
  127. new VariantData(R.string.variant_n, 4, "f4"),
  128. new VariantData(R.string.variant_n, 5, "f5"),
  129. },{ // Klatt
  130. new VariantData(R.string.variant_n, 1, "klatt"),
  131. new VariantData(R.string.variant_n, 2, "klatt2"),
  132. new VariantData(R.string.variant_n, 3, "klatt3"),
  133. new VariantData(R.string.variant_n, 4, "klatt4"),
  134. new VariantData(R.string.variant_n, 5, "klatt5"),
  135. new VariantData(R.string.variant_n, 6, "klatt6"),
  136. },{ // NVDA
  137. new VariantData(R.string.variant_adam, "adam"),
  138. new VariantData(R.string.variant_alex, "Alex"),
  139. new VariantData(R.string.variant_alicia, "Alicia"),
  140. new VariantData(R.string.variant_andy, "Andy"),
  141. new VariantData(R.string.variant_andrea, "Andrea"),
  142. new VariantData(R.string.variant_anika, "anika"),
  143. new VariantData(R.string.variant_anika_robot, "anikaRobot"),
  144. new VariantData(R.string.variant_annie, "Annie"),
  145. new VariantData(R.string.variant_anouncer, "anouncer"),
  146. new VariantData(R.string.variant_antonio, "antonio"),
  147. new VariantData(R.string.variant_anxious_andy, "AnxiousAndy"),
  148. new VariantData(R.string.variant_aunty, "aunty"),
  149. new VariantData(R.string.variant_belinda, "belinda"),
  150. new VariantData(R.string.variant_benjamin, "benjamin"),
  151. new VariantData(R.string.variant_boris, "boris"),
  152. new VariantData(R.string.variant_caleb, "caleb"),
  153. new VariantData(R.string.variant_david, "david"),
  154. new VariantData(R.string.variant_demonic, "Demonic"),
  155. new VariantData(R.string.variant_denis, "Denis"),
  156. new VariantData(R.string.variant_diogo, "Diogo"),
  157. new VariantData(R.string.variant_ed, "ed"),
  158. new VariantData(R.string.variant_edward, "edward"),
  159. new VariantData(R.string.variant_edward2, "edward2"),
  160. new VariantData(R.string.variant_gene, "Gene"),
  161. new VariantData(R.string.variant_gene2, "Gene2"),
  162. new VariantData(R.string.variant_grandma, "grandma"),
  163. new VariantData(R.string.variant_grandpa, "grandpa"),
  164. new VariantData(R.string.variant_gustave, "gustave"),
  165. new VariantData(R.string.variant_henrique, "Henrique"),
  166. new VariantData(R.string.variant_hugo, "Hugo"),
  167. new VariantData(R.string.variant_iven, "iven"),
  168. new VariantData(R.string.variant_iven2, "iven2"),
  169. new VariantData(R.string.variant_iven3, "iven3"),
  170. new VariantData(R.string.variant_iven4, "iven4"),
  171. new VariantData(R.string.variant_jacky, "Jacky"),
  172. new VariantData(R.string.variant_john, "john"),
  173. new VariantData(R.string.variant_kaukovalta, "kaukovalta"),
  174. new VariantData(R.string.variant_lee, "Lee"),
  175. new VariantData(R.string.variant_linda, "linda"),
  176. new VariantData(R.string.variant_marcelo, "Marcelo"),
  177. new VariantData(R.string.variant_marco, "Marco"),
  178. new VariantData(R.string.variant_mario, "Mario"),
  179. new VariantData(R.string.variant_max, "max"),
  180. new VariantData(R.string.variant_miguel, "miguel"),
  181. new VariantData(R.string.variant_michael, "Michael"),
  182. new VariantData(R.string.variant_michel, "michel"),
  183. new VariantData(R.string.variant_mike, "Mike"),
  184. new VariantData(R.string.variant_mr_serious, "Mr serious"),
  185. new VariantData(R.string.variant_nguyen, "Nguyen"),
  186. new VariantData(R.string.variant_norbert, "norbert"),
  187. new VariantData(R.string.variant_pablo, "pablo"),
  188. new VariantData(R.string.variant_paul, "paul"),
  189. new VariantData(R.string.variant_pedro, "pedro"),
  190. new VariantData(R.string.variant_quincy, "quincy"),
  191. new VariantData(R.string.variant_ricishay_max, "RicishayMax"),
  192. new VariantData(R.string.variant_ricishay_max2, "RicishayMax2"),
  193. new VariantData(R.string.variant_ricishay_max3, "RicishayMax3"),
  194. new VariantData(R.string.variant_rob, "rob"),
  195. new VariantData(R.string.variant_robert, "robert"),
  196. new VariantData(R.string.variant_robosoft, "robosoft"),
  197. new VariantData(R.string.variant_robosoft2, "robosoft2"),
  198. new VariantData(R.string.variant_robosoft3, "robosoft3"),
  199. new VariantData(R.string.variant_robosoft4, "robosoft4"),
  200. new VariantData(R.string.variant_robosoft3, "robosoft3"),
  201. new VariantData(R.string.variant_robosoft4, "robosoft4"),
  202. new VariantData(R.string.variant_robosoft5, "robosoft5"),
  203. new VariantData(R.string.variant_robosoft6, "robosoft6"),
  204. new VariantData(R.string.variant_robosoft7, "robosoft7"),
  205. new VariantData(R.string.variant_robosoft8, "robosoft8"),
  206. new VariantData(R.string.variant_sandro, "sandro"),
  207. new VariantData(R.string.variant_shelby, "shelby"),
  208. new VariantData(R.string.variant_steph, "steph"),
  209. new VariantData(R.string.variant_steph2, "steph2"),
  210. new VariantData(R.string.variant_steph3, "steph3"),
  211. new VariantData(R.string.variant_storm, "Storm"),
  212. new VariantData(R.string.variant_travis, "travis"),
  213. new VariantData(R.string.variant_tweaky, "Tweaky"),
  214. new VariantData(R.string.variant_unirobot, "UniRobot"),
  215. new VariantData(R.string.variant_victor, "victor"),
  216. new VariantData(R.string.variant_zac, "zac"),
  217. },{ // Young
  218. new VariantData(R.string.variant_male, "male-young"),
  219. new VariantData(R.string.variant_female, "female-young"),
  220. },{ // Old
  221. new VariantData(R.string.variant_male, "male-old"),
  222. new VariantData(R.string.variant_female, "female-old"),
  223. },{ // Croak
  224. new VariantData(R.string.variant_male, "croak"),
  225. },{ // Whisper
  226. new VariantData(R.string.variant_male, "whisper"),
  227. new VariantData(R.string.variant_female, "whisperf"),
  228. },
  229. };
  230. public VoiceVariantPreference(Context context, AttributeSet attrs, int defStyle) {
  231. super(context, attrs, defStyle);
  232. setDialogLayoutResource(R.layout.voice_variant_preference);
  233. setLayoutResource(R.layout.information_view);
  234. setPositiveButtonText(android.R.string.ok);
  235. setNegativeButtonText(android.R.string.cancel);
  236. }
  237. public VoiceVariantPreference(Context context, AttributeSet attrs) {
  238. this(context, attrs, 0);
  239. }
  240. public VoiceVariantPreference(Context context) {
  241. this(context, null);
  242. }
  243. public void setVoiceVariant(VoiceVariant variant) {
  244. for (int i = 0; i < variants.length; ++i) {
  245. VariantData[] items = variants[i];
  246. for (int j = 0; j < items.length; ++j) {
  247. if (items[j].getVariant().equals(variant)) {
  248. mCategoryIndex = i;
  249. mVariantIndex = j;
  250. onDataChanged();
  251. return;
  252. }
  253. }
  254. }
  255. onDataChanged();
  256. }
  257. @Override
  258. protected View onCreateDialogView() {
  259. View root = super.onCreateDialogView();
  260. mCategory = (Spinner)root.findViewById(R.id.category);
  261. mVariant = (Spinner)root.findViewById(R.id.variant);
  262. return root;
  263. }
  264. @Override
  265. protected void onBindDialogView(View view) {
  266. super.onBindDialogView(view);
  267. // Cache the indices so they don't get overwritten by the OnItemSelectedListener handlers.
  268. final int category = mCategoryIndex;
  269. final int variant = mVariantIndex;
  270. mCategory.setAdapter(new ResourceIdListAdapter((Activity)getContext(), categories));
  271. mCategory.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
  272. private boolean mInitializing = true;
  273. @Override
  274. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
  275. mVariant.setAdapter(new VariantDataListAdapter((Activity) getContext(), variants[position]));
  276. if (mInitializing) {
  277. mVariant.setSelection(variant);
  278. mInitializing = false;
  279. }
  280. mCategoryIndex = position;
  281. }
  282. @Override
  283. public void onNothingSelected(AdapterView<?> adapterView) {
  284. }
  285. });
  286. mVariant.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
  287. @Override
  288. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
  289. mVariantIndex = position;
  290. }
  291. @Override
  292. public void onNothingSelected(AdapterView<?> adapterView) {
  293. }
  294. });
  295. mCategory.setSelection(category);
  296. }
  297. @Override
  298. public void onClick(DialogInterface dialog, int which) {
  299. switch (which) {
  300. case DialogInterface.BUTTON_POSITIVE:
  301. onDataChanged();
  302. if (shouldCommit()) {
  303. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
  304. {
  305. PreferenceManager preferenceManager = getPreferenceManager();
  306. preferenceManager.setStorageDeviceProtected ();
  307. }
  308. SharedPreferences.Editor editor = getEditor();
  309. if (editor != null) {
  310. VoiceVariant variant = variants[mCategoryIndex][mVariantIndex].getVariant();
  311. editor.putString(VoiceSettings.PREF_VARIANT, variant.toString());
  312. editor.commit();
  313. }
  314. }
  315. break;
  316. }
  317. super.onClick(dialog, which);
  318. }
  319. private void onDataChanged() {
  320. Context context = getContext();
  321. CharSequence category = context.getText(categories[mCategoryIndex]);
  322. CharSequence variant = variants[mCategoryIndex][mVariantIndex].getDisplayName(context);
  323. callChangeListener(String.format("%s (%s)", category, variant));
  324. }
  325. }