TextToSpeech,playEarcon和.wav文件
问题描述:
在我的一个应用程序中,我有一个语音合成字母数字参考字符串,字母/数字,字母/数字的活动,例如“ABC123”听起来像“Ay,bee,sea,one two three” 。由于这是一组有限的声音,我认为通过使用playEarcon方法播放预先录制的数字和字母的.wav文件,可以使TTS引擎在没有互联网连接的情况下工作。TextToSpeech,playEarcon和.wav文件
我已经将所有36个wav文件放在res/raw文件夹中,并在初始化TTS引擎时将资源id映射到字母。这效果很好,但是.apk现在更大,因为wav文件在apk中未压缩存储。我想使apk的大小更小。
在the answer to another question它声明wav文件从压缩中排除。 (我不明白为什么,因为它们通常会压缩到原来的大约40%)。一次检查apk的内部,这看起来是真的。
由于代码中没有引用资源文件的扩展名,我尝试将wavs重命名为各种.waw,.abc,.spc。所有这些都得到压缩,但不幸的是playEarcon方法在调用时不产生声音,除非扩展名是.wav。
总之我想强制TTS引擎播放没有wav扩展名的文件,或者说服它压缩.wav文件。
所有的建议将受到感谢。我发布了下面最小的可展示代码示例,值得一提。我的工作文件被命名为gb_a.wav,gb_b.wav等。如果扩展名被改变,他们停止发声。
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 = "";
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); }
}
。 。
答
- 为什么wav文件没有试图压缩:according wikipedia wav文件是数据的容器。大多数情况下,它用于未压缩的PCM声音,但也可用于存储使用各种编解码器压缩的数据(可找到
wFormatTags
(存储数据的类型)的可能值,例如here)。 - 您可以将资源保存到本地文件系统,并使用
addEarcon(String earcon, String filename)
而不是addEarcon(String earcon, String packagename, int resourceId)
。 - 您可以使用带有
-0 wav
cmd行开关的aapt来制作apk,其中包含从压缩类型中排除的wav文件。
答
您应该尝试将wav
文件转换为ogg
文件,然后您将获得最佳的声音文件压缩率。
重申您的观点(1) - 这是Android构建过程,它们将它们从压缩中排除(请参阅我引用的链接),我想找到一种方法来覆盖它。 (2)我想在我的apk中打包wavs(3)为什么我想要将它们从压缩中排除?他们已经被排除在外,这就是这个问题的要点 - 我想压缩它们! (3)关于 – NickT 2012-02-23 16:21:39
,对不起我的错误。那么,我认为,您可以下载aapt工具源码,将wav从默认情况下不压缩的类型中排除,重新构建它并使用这个新工具创建适配器。但是我没有尝试这个 - 所以AssetManager可能会拒绝加载这样的资源。 – 2012-02-23 16:36:08