TextToSpeech, playEarcon y archivos .wav

En una de mis aplicaciones tengo una actividad en la que el habla sintetiza cadenas alfanuméricas de referencia, letra / número por letra / número por ejemplo "ABC123" suena como "Ay, abeja, mar, uno dos tres". Como este es un conjunto limitado de sonidos pensé que sería bueno para permitir que el motor TTS para trabajar sin una conexión a Internet mediante la reproducción de archivos .wav pregrabados de los números y letras utilizando el método playEarcon.

He colocado todos los 36 archivos wav en la carpeta res / raw y mapeado los identificadores de recursos a las letras al inicializar el motor TTS. Esto funciona bien, sin embargo el .apk es ahora mucho más grande como los archivos wav se almacenan sin comprimir en el apk. Me gustaría hacer el tamaño del apk menor.

En la respuesta a otra pregunta se afirma que los archivos wav están excluidos de la compresión. (No veo por qué, ya que típicamente cremallera hasta aproximadamente el 40% del original). Una inspección interna del apk, esto parece ser cierto.

Como la extensión de los archivos de recursos no se hace referencia en el código, he intentado cambiar el nombre de los wavs, a vario .waw, .abc, .spc. Todos estos se comprimen, pero por desgracia el método playEarcon no produce ningún sonido cuando se invoca a menos que la extensión es .wav.

En resumen, quisiera coaccionar al motor TTS para que reproduzca archivos sin extensión wav, o persuadirlo para que comprima los archivos .wav.

Todas las sugerencias serán recibidas con gratitud. Por lo que vale la pena publicar el ejemplo de código demostrable más pequeño a continuación. Mis archivos de trabajo se denominan gb_a.wav, gb_b.wav, etc. Si se cambia la extensión, dejan de sonar.

public class WavSpeakerActivity extends Activity implements RadioGroup.OnCheckedChangeListener, TextToSpeech.OnInitListener { static final int mGBLetterResIds[] = { R.raw.gb_a, R.raw.gb_b, R.raw.gb_c, R.raw.gb_d, R.raw.gb_e, R.raw.gb_f, R.raw.gb_g, R.raw.gb_h, R.raw.gb_i, R.raw.gb_j, R.raw.gb_k, R.raw.gb_l, R.raw.gb_m, R.raw.gb_n, R.raw.gb_o, R.raw.gb_p, R.raw.gb_q, R.raw.gb_r, R.raw.gb_s, R.raw.gb_t, R.raw.gb_u, R.raw.gb_v, R.raw.gb_w, R.raw.gb_x, R.raw.gb_y, R.raw.gb_z }; static final int mGBNumberResIds[] = { R.raw.gb_zero, R.raw.gb_one, R.raw.gb_two, R.raw.gb_three, R.raw.gb_four, R.raw.gb_five, R.raw.gb_six, R.raw.gb_seven, R.raw.gb_eight, R.raw.gb_nine }; static final String mGbStr = "GB"; static final String mAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static final String mNumbers = "0123456789"; private String mPpackageName = null; private String mTextToSpeak = null; private RadioGroup mRadioGroup = null;// two buttons one sets letters, the other numbers private TextToSpeech mTts = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTts = new TextToSpeech(this, this); mRadioGroup = (RadioGroup) findViewById(R.id.radioGroup1); mRadioGroup.setOnCheckedChangeListener(this); } @Override protected void onResume() { super.onResume(); RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup1); switchText(rg); mPpackageName = getPackageName(); } @Override public void onDestroy() { // Don't forget to shutdown speech engine if (mTts != null) { mTts.stop(); mTts.shutdown(); } super.onDestroy(); } private void switchText(RadioGroup rg) { // select letters or digits as the String to speak int checkedButton = rg.getCheckedRadioButtonId(); switch (checkedButton) { case R.id.alphabet: mTextToSpeak = mAlphabet; break; case R.id.numbers: mTextToSpeak = mNumbers; break; } } public void myClickHandler(View target) { // Just the one button has been clicked - the 'Speak' one String earconKey; String lang = Locale.UK.getCountry(); // will be "GB", just have UK in this small example mTts.setLanguage(Locale.UK); // skip error checking for brevity's sake String text = mTextToSpeak.replaceAll("\\s", "");// remove spaces (if any) char c; for (int i = 0; i < text.length(); i++) { c = text.charAt(i); if ( Character.isLetter(c) || Character.isDigit(c) ) { earconKey = lang + Character.toString(c); // GBA, GBB..GBZ, GB0.. GB9 mTts.playEarcon(earconKey, TextToSpeech.QUEUE_ADD, null); } } } @Override public void onInit(int status) { // doesn't seem we need to check status or setLanguage if we're just playing earcons mapEarCons(); // map letter/digit sounds to resource ids } private void mapEarCons() { String key; for (char c = 'A'; c <= 'Z' ; c++){ key = mGbStr + Character.toString(c); // GBA, GBB .. GBZ mTts.addEarcon(key, mPpackageName, mGBLetterResIds[c - 'A'] );// add it } for (int i = 0 ; i <= 9; i++){ key = mGbStr + Integer.toString(i); // GB0, GB1 .. GB9 mTts.addEarcon(key, mPpackageName, mGBNumberResIds[i] ); } } @Override public void onCheckedChanged(RadioGroup rg, int arg1) { switchText(rg); } } 

. .

  1. ¿Por qué los archivos wav no se intentan comprimir: de acuerdo wikipedia archivo wav es un contenedor de datos. Lo más frecuente es que se utilice para sonido PCM sin comprimir, pero también se puede utilizar para almacenar datos comprimidos con varios códecs (puede encontrar valores posibles para wFormatTags (tipo de datos almacenados), por ejemplo aquí ).
  2. Puede guardar su recurso en el sistema de archivos local y utilizar addEarcon(String earcon, String filename) lugar de addEarcon(String earcon, String packagename, int resourceId) .
  3. Puede utilizar aapt con -0 wav conmutador de línea -0 wav cmd para hacer apk con archivos wav excluidos de tipos comprimidos.

Usted debe tratar de convertir el archivo wav a un archivo ogg , a continuación, obtendrá la mejor tasa de compresión para el archivo de sonido.

  • Otras opciones de la biblioteca de Android TextToSpeech
  • ¿Por qué no se llama a UtteranceProgress Listener a Text to Speach?
  • Android: dos instancias de Text-to-Speech funcionan muy lentamente
  • TextToSpeech.setEngineByPackageName () no establece nada
  • TextToSpeech versión de compilación android no reproduce audio
  • Manejo de múltiples idiomas sin demora en el TTS de Android
  • Android Texto a voz añadir texto de voz continuamente
  • Cómo cambiar programáticamente el motor predeterminado TTS
  • Desarrollo de aplicaciones similares a "Google ahora" - ¿es posible utilizar el reconocimiento de voz sin entrada de teclado?
  • Agrega mi motor TTS a Android TTS Serivce como SAPI
  • ¿Existe una utilidad o API para convertir abreviaturas abreviadas de SMS a oraciones adecuadas?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.