Как вы получаете аудио байт [] из синтезированной речи, созданной механизмом TextToSpeech?

Я пытаюсь получить аудио байт [], который создается, когда механизм TextToSpeech синтезирует текст.

Я пытался создать визуализатор и назначил OnDataCaptureListener но предоставляемый им байт [] всегда один и тот же, и поэтому я не верю, что массив связан с произносимым текстом.

Это моя реализация:

            AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);

            audioManager.requestAudioFocus(focusChange -> Log.d(TAG, "focusChange is: is: " + focusChange), AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);

            int audioSessionId = audioManager.generateAudioSessionId();

            mVisualizer = new Visualizer(audioSessionId);

            mVisualizer.setEnabled(false);

            mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[0]);

            mVisualizer.setDataCaptureListener(
            new Visualizer.OnDataCaptureListener() {

            public void onWaveFormDataCapture(Visualizer visualizer,
             byte[] bytes, int samplingRate) {

                   //here the bytes are always equal to the bytes received in the last call
              }

              public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {

               }
             }, Visualizer.getMaxCaptureRate(), true, true);

             mVisualizer.setEnabled(true);

Я также обнаружил, что вы можете использовать SynthesisCallback для получения байта [] через его audioAvailable() метод, но я не могу реализовать это должным образом.

Я создал TextToSpeechService но это onSynthesizeText() метод никогда не вызывается. Тем не менее, я могу сказать, что сервис работает как onLoadLanguage() называется.

Мой вопрос в двух словах: как я могу получить представление аудио байтов [] аудио, созданного при синтезе текста движком TextToSpeech?

Заранее спасибо.

1 ответ

Я слышал, что onAudioAvailable() устарела и мой обратный вызов тоже не вызывается.

Итак, обходной путь:

  1. В деятельности:

    try
        {
            tts.shutdown();
            tts = null;
        }
        catch (Exception e)
        {}
     tts = new TextToSpeech(this, this);
    
  2. В OnInit() метод:

       @Override
        public void onInit(int p1)
        {
    
         HashMap<String,String> mTTSMap = new HashMap<String,String>();
        tts.setOnUtteranceProgressListener(new UtteranceProgressListener()
                { 
                    @Override
                    public void onStart(final String p1)
                    {
                        // TODO: Implement this method
                            Log.e(TAG, "START");
                    }
    
                    @Override
                    public void onDone(final String p1)
                    {
                        if (p1.compareTo("abcde") == 0)
                        {
                            synchronized (MainActivity.this)
                            {
                                MainActivity.this.notifyAll();
                            }
                        }
                    }
    
                    @Override
                    public void onError(final String p1)
                    {       
                         //this is also deprecated...
                    }
                    @Override
                    public void onAudioAvailable(final String id, final byte[] bytes)
                    {
              //never calked!
                        runOnUiThread(new Runnable(){
    
                                @Override
                                public void run()
                                {
                                    // TODO: Implement this method
                                    Toast.makeText(MainActivity.this, "id:" + id  /*"bytes:" + Arrays.toString(bytes)*/, 1).show();
                                    Log.v(TAG, "BYTES");
                                }});
                        //super.onAudioAvailable(id,bytes);
    
                    }
    
                });
    
            Locale enEn = new Locale("en_EN");
            if (tts.isLanguageAvailable(enEn) == TextToSpeech.LANG_AVAILABLE)
            {
                tts.setLanguage(enEn);
            }
    
            /*public int synthesizeToFile(java.lang.CharSequence text, android.os.Bundle params, java.io.File file, java.lang.String utteranceId);*/
            //@java.lang.Deprecated()
            // public int synthesizeToFile(java.lang.String text, java.util.HashMap<java.lang.String, java.lang.String> params, java.lang.String filename);
                  mTTSMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "abcde"); tts.synthesizeToFile("Hello",mTTSMap,"/storage/emulated/0/a.wav");
    synchronized(MainActivity.this){
                     try{
                          MainActivity.this.wait();
                         }catch(InterruptedException e){}
                         ReadTheFile();    
                     }
            }
    

Затем ваша задача - загрузить a.wav в нужный вам буфер. Использование библиотек, как это было упомянуто в этом ответе SO.

Резюме:

  1. Создать TTS Engine.
  2. Инициализируйте это.
  3. OnInit называется.
  4. В OnInit(), вы устанавливаете новый HashMap и ставите идентификатор высказывания.
  5. регистр setOnUtteranceProgressListener,
  6. Синтезируйте что-нибудь в файл.
  7. Вызов wait();
  8. В onDone() вызов метода notify();
  9. После wait(); прочитать синтезированный файл в буфер.
Другие вопросы по тегам