Как вы получаете аудио байт [] из синтезированной речи, созданной механизмом 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()
устарела и мой обратный вызов тоже не вызывается.
Итак, обходной путь:
В деятельности:
try { tts.shutdown(); tts = null; } catch (Exception e) {} tts = new TextToSpeech(this, this);
В
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.
Резюме:
- Создать TTS Engine.
- Инициализируйте это.
OnInit
называется.- В
OnInit()
, вы устанавливаете новый HashMap и ставите идентификатор высказывания. - регистр
setOnUtteranceProgressListener
, - Синтезируйте что-нибудь в файл.
- Вызов
wait();
- В
onDone()
вызов методаnotify();
- После
wait();
прочитать синтезированный файл в буфер.