Как получить результат распознавания — КиберПедия 

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Как получить результат распознавания

2019-12-27 136
Как получить результат распознавания 0.00 из 5.00 0 оценок
Заказать работу


Чтобы получить результат распознавания, нужно также указать слушателя событий, имплементирующего интерфейс RecognitionListener.
У него есть несколько методов, которые вызываются pocketsphinx-ом при наступлении одного из событий:

  • onBeginningOfSpeech — движок услышал какой-то звук, может быть это речь (а может быть и нет)
  • onEndOfSpeech — звук закончился
  • onPartialResult — есть промежуточные результаты распознавания. Для активационной фразы это значит, что она сработала. Аргумент Hypothesis содержит данные о распознавании (строка и score)
  • onResult — конечный результат распознавания. Этот метод будет вызыван после вызова метода stop у SpeechRecognizer. Аргумент Hypothesis содержит данные о распознавании (строка и score)

 

Реализуя тем или иным способом методы onPartialResult и onResult, можно изменять логику распознавания и получать окончательный результат. Вот как это сделано в случае с нашим приложением:

@Overridepublic void onEndOfSpeech() { Log.d(TAG, "onEndOfSpeech"); if (mRecognizer.getSearchName().equals(COMMAND_SEARCH)) { mRecognizer.stop(); }}@Overridepublic void onPartialResult(Hypothesis hypothesis) { if (hypothesis == null) return; String text = hypothesis.getHypstr(); if (KWS_SEARCH.equals(mRecognizer.getSearchName())) { startRecognition(); } else { Log.d(TAG, text); }}@Overridepublic void onResult(Hypothesis hypothesis) { mMicView.setBackgroundResource(R.drawable.background_big_mic); mHandler.removeCallbacks(mStopRecognitionCallback); String text = hypothesis!= null? hypothesis.getHypstr(): null; Log.d(TAG, "onResult " + text);   if (COMMAND_SEARCH.equals(mRecognizer.getSearchName())) { if (text!= null) { Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); process(text); } mRecognizer.startListening(KWS_SEARCH); }}

 

Когда мы получаем событие onEndOfSpeech, и если при этом мы распознаем команду для выполнения, то необходимо остановить распознавание, после чего сразу будет вызван onResult.
В onResult нужно проверить, что только что было распознано. Если это команда, то нужно запустить ее на выполнение и переключить движок на распознавание активационной фразы.
В onPartialResult нас интересует только распознавание активационной фразы. Если мы его обнаруживаем, то сразу запускаем процесс распознавания команды. Вот как он выглядит:

private synchronized void startRecognition() { if (mRecognizer == null || COMMAND_SEARCH.equals(mRecognizer.getSearchName())) return; mRecognizer.cancel(); new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOLUME).startTone(ToneGenerator.TONE_CDMA_PIP, 200); post(400, new Runnable() { @Override public void run() { mMicView.setBackgroundResource(R.drawable.background_big_mic_green);     mRecognizer.startListening(COMMAND_SEARCH, 3000); Log.d(TAG, "Listen commands"); post(4000, mStopRecognitionCallback); } });}


Здесь мы сперва играем небольшой сигнал для оповещения пользователя, что мы его услышали и готовы к его команде. На это время микрофон долже быть выключен. Поэтому мы запускаем распознавание после небольшого таймаута (чуть больше, чем длительность сигнала, чтобы не услышать его эха). Также запускается поток, который остановит распознавание принудительно, если пользователь говорит слишком долго. В данном случае это 3 секунды.

Как превратить распознанную строку в команды


Ну тут все уже специфично для конкретного приложения. В случае с нагим примером, мы просто вытаскиваем из строчки названия устройств, ищем по ним нужное устройство и либо меняем его состояние с помощью HTTP запроса на контроллер умного дома, либо сообщаем его текущее состояние (как в случае с термостатом). Эту логику можно увидеть в классе Controller.

Как синтезировать речь


Синтез речи — это операция, обратная распознаванию. Здесь наоборот — нужно превратить строку текста в речь, чтобы ее услышал пользователь.
В случае с термостатом мы должны заставить наше Android устройство произнести текущую температуру. С помощью API TextToSpeech это сделать довольно просто (спасибо гуглу за прекрасный женский TTS для русского языка):

private void speak(String text) { synchronized (mSpeechQueue) { mRecognizer.stop(); mSpeechQueue.add(text); HashMap<String, String> params = new HashMap<String, String>(2); params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UUID.randomUUID().toString()); params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC)); params.put(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, "true"); mTextToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params); }}

 

Скажу наверное банальность, но перед процессом синтеза нужно обязательно отключить распознавание. На некоторых устройствах (например, все самсунги) вообще невозсожно одновременно и слушать микрофон, и что-то синтезировать.
Окончание синтеза речи (то есть окончание процесса говорения текста синтезатором) можно отследить в слушателе:

private final TextToSpeech.OnUtteranceCompletedListener mUtteranceCompletedListener = new TextToSpeech.OnUtteranceCompletedListener() { @Override public void onUtteranceCompleted(String utteranceId) { synchronized (mSpeechQueue) { mSpeechQueue.poll(); if (mSpeechQueue.isEmpty()) {   mRecognizer.startListening(KWS_SEARCH); } } }};

 

В нем мы просто проверяем, нет ли еще чего-то в очереди на синтез, и включаем распозанвание активационной фразы, если ничего больше нет.

И это все?


Да! Как видите, быстро и качественно распознать речь прямо на устройстве совсем несложно, благодаря наличию таких замечательных проектов, как Pocketsphinx. Он предоставляет очень удобный API, который можно использовать в решении задач, связанных с распознаванием голосовых команд.

В данном примере мы прикрутили распознавание к вполне кокрентной задаче — голосовому управлению устройствами умного дома. За счет локального распознавания мы добились очень высокой скорости работы и минимизировали ошибки.
Понятно, что тот же код можно использовать и для других задач, связанных с голосом. Это не обязательно должен быть именно умный дом.

Все исходники, а также саму сборку приложения вы можете найти в репозитории на GitHub.
Также на моем канале в YouTube вы можете увидеть некоторые другие реализации голосового управления, и не только системами умных домов.

Теги:


Поделиться с друзьями:

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.008 с.