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 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. * Copyright (C) 2013 Reece H. Dunn
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.reecedunn.espeak.preference;
  17. import android.app.Activity;
  18. import android.content.Context;
  19. import android.content.DialogInterface;
  20. import android.content.SharedPreferences;
  21. import android.preference.DialogPreference;
  22. import android.util.AttributeSet;
  23. import android.view.LayoutInflater;
  24. import android.view.View;
  25. import android.view.ViewGroup;
  26. import android.widget.AdapterView;
  27. import android.widget.ArrayAdapter;
  28. import android.widget.Spinner;
  29. import android.widget.TextView;
  30. import com.reecedunn.espeak.R;
  31. import com.reecedunn.espeak.ResourceIdListAdapter;
  32. import com.reecedunn.espeak.VoiceSettings;
  33. import com.reecedunn.espeak.VoiceVariant;
  34. public class VoiceVariantPreference extends DialogPreference {
  35. private Spinner mCategory;
  36. private Spinner mVariant;
  37. private int mCategoryIndex = 0;
  38. private int mVariantIndex = 0;
  39. static class ViewHolder
  40. {
  41. public TextView text;
  42. }
  43. private class VariantData {
  44. private final int name;
  45. private final Object arg;
  46. private final VoiceVariant variant;
  47. protected VariantData(int name, String variant) {
  48. this(name, null, variant);
  49. }
  50. protected VariantData(int name, Object arg, String variant) {
  51. this.name = name;
  52. this.arg = arg;
  53. this.variant = VoiceVariant.parseVoiceVariant(variant);
  54. }
  55. public String getDisplayName(Context context) {
  56. String text = context.getText(name).toString();
  57. if (arg == null) {
  58. return text;
  59. }
  60. return String.format(text, arg);
  61. }
  62. public VoiceVariant getVariant() {
  63. return variant;
  64. }
  65. }
  66. public class VariantDataListAdapter extends ArrayAdapter<VariantData>
  67. {
  68. private final LayoutInflater mInflater;
  69. public VariantDataListAdapter(Activity context, VariantData[] resources)
  70. {
  71. super(context, android.R.layout.simple_list_item_1, resources);
  72. mInflater = context.getLayoutInflater();
  73. }
  74. @Override
  75. public View getView(int position, View convertView, ViewGroup parent)
  76. {
  77. ViewHolder holder;
  78. if (convertView == null)
  79. {
  80. convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
  81. holder = new ViewHolder();
  82. holder.text = (TextView)convertView.findViewById(android.R.id.text1);
  83. convertView.setTag(holder);
  84. }
  85. else
  86. {
  87. holder = (ViewHolder)convertView.getTag();
  88. }
  89. holder.text.setText(getItem(position).getDisplayName(getContext()));
  90. return convertView;
  91. }
  92. @Override
  93. public View getDropDownView(int position, View convertView, ViewGroup parent)
  94. {
  95. return getView(position, convertView, parent);
  96. }
  97. }
  98. private Integer[] categories = {
  99. R.string.variant_male,
  100. R.string.variant_female,
  101. R.string.variant_klatt,
  102. R.string.variant_nvda,
  103. R.string.variant_young,
  104. R.string.variant_old,
  105. R.string.variant_croak,
  106. R.string.variant_whisper,
  107. };
  108. private VariantData[][] variants = {
  109. { // Male
  110. new VariantData(R.string.variant_default, "male"),
  111. new VariantData(R.string.variant_n, 1, "m1"),
  112. new VariantData(R.string.variant_n, 2, "m2"),
  113. new VariantData(R.string.variant_n, 3, "m3"),
  114. new VariantData(R.string.variant_n, 4, "m4"),
  115. new VariantData(R.string.variant_n, 5, "m5"),
  116. new VariantData(R.string.variant_n, 6, "m6"),
  117. new VariantData(R.string.variant_n, 7, "m7"),
  118. },{ // Female
  119. new VariantData(R.string.variant_default, "female"),
  120. new VariantData(R.string.variant_n, 1, "f1"),
  121. new VariantData(R.string.variant_n, 2, "f2"),
  122. new VariantData(R.string.variant_n, 3, "f3"),
  123. new VariantData(R.string.variant_n, 4, "f4"),
  124. new VariantData(R.string.variant_n, 5, "f5"),
  125. },{ // Klatt
  126. new VariantData(R.string.variant_n, 1, "klatt"),
  127. new VariantData(R.string.variant_n, 2, "klatt2"),
  128. new VariantData(R.string.variant_n, 3, "klatt3"),
  129. new VariantData(R.string.variant_n, 4, "klatt4"),
  130. },{ // NVDA
  131. new VariantData(R.string.variant_andy, "Andy"),
  132. new VariantData(R.string.variant_annie, "Annie"),
  133. new VariantData(R.string.variant_anxious_andy, "AnxiousAndy"),
  134. new VariantData(R.string.variant_aunty, "aunty"),
  135. new VariantData(R.string.variant_boris, "boris"),
  136. new VariantData(R.string.variant_denis, "Denis"),
  137. new VariantData(R.string.variant_gene, "Gene"),
  138. new VariantData(R.string.variant_gene2, "Gene2"),
  139. new VariantData(R.string.variant_iven, "iven"),
  140. new VariantData(R.string.variant_iven2, "iven2"),
  141. new VariantData(R.string.variant_iven3, "iven3"),
  142. new VariantData(R.string.variant_jacky, "Jacky"),
  143. new VariantData(R.string.variant_john, "john"),
  144. new VariantData(R.string.variant_kaukovalta, "kaukovalta"),
  145. new VariantData(R.string.variant_lee, "Lee"),
  146. new VariantData(R.string.variant_linda, "linda"),
  147. new VariantData(R.string.variant_mario, "Mario"),
  148. new VariantData(R.string.variant_max, "max"),
  149. new VariantData(R.string.variant_michael, "Michael"),
  150. new VariantData(R.string.variant_michel, "michel"),
  151. new VariantData(R.string.variant_mr_serious, "Mr serious"),
  152. new VariantData(R.string.variant_norbert, "norbert"),
  153. new VariantData(R.string.variant_quincy, "quincy"),
  154. new VariantData(R.string.variant_rob, "rob"),
  155. new VariantData(R.string.variant_robert, "robert"),
  156. new VariantData(R.string.variant_storm, "Storm"),
  157. new VariantData(R.string.variant_travis, "travis"),
  158. new VariantData(R.string.variant_tweaky, "Tweaky"),
  159. new VariantData(R.string.variant_zac, "zac"),
  160. },{ // Young
  161. new VariantData(R.string.variant_male, "male-young"),
  162. new VariantData(R.string.variant_female, "female-young"),
  163. },{ // Old
  164. new VariantData(R.string.variant_male, "male-old"),
  165. new VariantData(R.string.variant_female, "female-old"),
  166. },{ // Croak
  167. new VariantData(R.string.variant_male, "croak"),
  168. },{ // Whisper
  169. new VariantData(R.string.variant_male, "whisper"),
  170. new VariantData(R.string.variant_female, "whisperf"),
  171. },
  172. };
  173. public VoiceVariantPreference(Context context, AttributeSet attrs, int defStyle) {
  174. super(context, attrs, defStyle);
  175. setDialogLayoutResource(R.layout.voice_variant_preference);
  176. setLayoutResource(R.layout.information_view);
  177. setPositiveButtonText(android.R.string.ok);
  178. setNegativeButtonText(android.R.string.cancel);
  179. }
  180. public VoiceVariantPreference(Context context, AttributeSet attrs) {
  181. this(context, attrs, 0);
  182. }
  183. public VoiceVariantPreference(Context context) {
  184. this(context, null);
  185. }
  186. public void setVoiceVariant(VoiceVariant variant) {
  187. for (int i = 0; i < variants.length; ++i) {
  188. VariantData[] items = variants[i];
  189. for (int j = 0; j < items.length; ++j) {
  190. if (items[j].getVariant().equals(variant)) {
  191. mCategoryIndex = i;
  192. mVariantIndex = j;
  193. onDataChanged();
  194. return;
  195. }
  196. }
  197. }
  198. onDataChanged();
  199. }
  200. @Override
  201. protected View onCreateDialogView() {
  202. View root = super.onCreateDialogView();
  203. mCategory = (Spinner)root.findViewById(R.id.category);
  204. mVariant = (Spinner)root.findViewById(R.id.variant);
  205. return root;
  206. }
  207. @Override
  208. protected void onBindDialogView(View view) {
  209. super.onBindDialogView(view);
  210. // Cache the indices so they don't get overwritten by the OnItemSelectedListener handlers.
  211. final int category = mCategoryIndex;
  212. final int variant = mVariantIndex;
  213. mCategory.setAdapter(new ResourceIdListAdapter((Activity)getContext(), categories));
  214. mCategory.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
  215. private boolean mInitializing = true;
  216. @Override
  217. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
  218. mVariant.setAdapter(new VariantDataListAdapter((Activity) getContext(), variants[position]));
  219. if (mInitializing) {
  220. mVariant.setSelection(variant);
  221. mInitializing = false;
  222. }
  223. mCategoryIndex = position;
  224. }
  225. @Override
  226. public void onNothingSelected(AdapterView<?> adapterView) {
  227. }
  228. });
  229. mVariant.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
  230. @Override
  231. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
  232. mVariantIndex = position;
  233. }
  234. @Override
  235. public void onNothingSelected(AdapterView<?> adapterView) {
  236. }
  237. });
  238. mCategory.setSelection(category);
  239. }
  240. @Override
  241. public void onClick(DialogInterface dialog, int which) {
  242. switch (which) {
  243. case DialogInterface.BUTTON_POSITIVE:
  244. onDataChanged();
  245. if (shouldCommit()) {
  246. SharedPreferences.Editor editor = getEditor();
  247. if (editor != null) {
  248. VoiceVariant variant = variants[mCategoryIndex][mVariantIndex].getVariant();
  249. editor.putString(VoiceSettings.PREF_VARIANT, variant.toString());
  250. editor.commit();
  251. }
  252. }
  253. break;
  254. }
  255. super.onClick(dialog, which);
  256. }
  257. private void onDataChanged() {
  258. Context context = getContext();
  259. CharSequence category = context.getText(categories[mCategoryIndex]);
  260. CharSequence variant = variants[mCategoryIndex][mVariantIndex].getDisplayName(context);
  261. callChangeListener(String.format("%s (%s)", category, variant));
  262. }
  263. }