Файлы TextToSpeech, playEarcon и .wav - PullRequest
       20

Файлы TextToSpeech, playEarcon и .wav

6 голосов
/ 15 февраля 2012

В одном из моих приложений у меня есть действие, в котором речь синтезирует буквенно-цифровые ссылочные строки, буква / цифра за буквой / цифрой, например, «ABC123» звучит как «Ай, пчела, море, один два три».Поскольку это ограниченный набор звуков, я подумал, что было бы хорошо включить механизм TTS для работы без подключения к Интернету, воспроизводя предварительно записанные файлы .wav чисел и букв с помощью метода playEarcon.

Я поместилвсе 36 wav-файлов в папке res / raw и сопоставили идентификаторы ресурсов с буквами при инициализации механизма TTS.Это работает хорошо, однако .apk теперь намного больше, так как файлы wav хранятся в несжатом виде в apk.Я хотел бы уменьшить размер apk.

В ответе на другой вопрос говорится, что файлы 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 = "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); }
}

..

Ответы [ 2 ]

1 голос
/ 23 февраля 2012
  1. Почему wav-файлы не пытаются сжать: согласно википедии wav-файл является контейнером для данных.Чаще всего он используется для несжатого звука PCM, но также может использоваться для хранения данных, сжатых различными кодеками (вы можете найти возможные значения для wFormatTags (тип для сохраненных данных), например, здесь ).
  2. Вы можете сохранить свой ресурс в локальной файловой системе и использовать addEarcon(String earcon, String filename) вместо addEarcon(String earcon, String packagename, int resourceId).
  3. Вы можете использовать aapt с переключателем строки -0 wav cmd, чтобы сделать apk с файлами wav, исключенными изсжатые типы.
0 голосов
/ 25 февраля 2012

Вы должны попытаться преобразовать файл wav в файл ogg, тогда вы получите наилучшую скорость сжатия для звукового файла.

...