2016-08-05 3 views
0

Я использую Microsoft Cognitive Services - распознавание речи в приложении для Android. Все работает нормально, когда код находится в моем основном действии, но когда я хочу переместить часть, соответствующую распознаванию речи, новому классу, она выдает ошибку.Microsoft Cognitive Speech Service - Android

Вот примеры кода:

В основной деятельности

int m_waitSeconds = 0; 
MicrophoneRecognitionClient micClient = null; 
FinalResponseStatus isReceivedResponse = FinalResponseStatus.NotReceived; 
Boolean speechIntent = false; 
SpeechRecognitionMode speechMode = SpeechRecognitionMode.ShortPhrase; 

public enum FinalResponseStatus { NotReceived, OK } 

/** 
* Gets the primary subscription key 
*/ 
public String getPrimaryKey() { 
    return this.getString(R.string.primaryKey); 
} 

/** 
* Gets the secondary subscription key 
*/ 
public String getSecondaryKey() { 
    return this.getString(R.string.secondaryKey); 
} 

/** 
* Gets the LUIS application identifier. 
* @return The LUIS application identifier. 
*/ 
private String getLuisAppId() { 
    return this.getString(R.string.luisAppID); 
} 

/** 
* Gets the LUIS subscription identifier. 
* @return The LUIS subscription identifier. 
*/ 
private String getLuisSubscriptionID() { 
    return this.getString(R.string.luisSubscriptionID); 
} 

/** 
* Gets the default locale. 
* @return The default locale. 
*/ 
private String getDefaultLocale() { 
    return "en-us"; 
} 


/** 
* Handles the Click event of the _startButton control. 
*/ 
private void StartButton_Click(View v) { 

    this.m_waitSeconds = this.speechMode == SpeechRecognitionMode.ShortPhrase ? 20 : 200; 

    if (this.micClient == null) { 
     if (this.speechIntent) { 
      this.WriteLine("--- Start microphone dictation with Intent detection ----"); 

      this.micClient = SpeechRecognitionServiceFactory.createMicrophoneClientWithIntent(
          this, 
          this.getDefaultLocale(), 
          this, 
          this.getPrimaryKey(), 
          this.getSecondaryKey(), 
          this.getLuisAppId(), 
          this.getLuisSubscriptionID()); 
     } 
     else 
     { 
      this.micClient = SpeechRecognitionServiceFactory.createMicrophoneClient(
        this, 
        this.speechMode, 
        this.getDefaultLocale(), 
        this, 
        this.getPrimaryKey(), 
        this.getSecondaryKey()); 
     } 
    } 

    this.micClient.startMicAndRecognition(); 
} 

public void onFinalResponseReceived(final RecognitionResult response) { 
    boolean isFinalDicationMessage = this.speechMode == SpeechRecognitionMode.LongDictation && 
      (response.RecognitionStatus == RecognitionStatus.EndOfDictation || 
        response.RecognitionStatus == RecognitionStatus.DictationEndSilenceTimeout); 
    if (null != this.micClient && ((this.speechMode == SpeechRecognitionMode.ShortPhrase) || isFinalDicationMessage)) { 
     // we got the final result, so it we can end the mic reco. No need to do this 
     // for dataReco, since we already called endAudio() on it as soon as we were done 
     // sending all the data. 
     this.micClient.endMicAndRecognition(); 
    } 

    if (isFinalDicationMessage) { 
     this.isReceivedResponse = FinalResponseStatus.OK; 
    } 

    Confidence cMax = Confidence.Low; 
    int iMax = 0; 
    if (!isFinalDicationMessage && response.Results.length != 0) { 
     for (int i = 0; i < response.Results.length; i++) { 
      //get the text with highest confidence: 
      if(response.Results[i].Confidence.getValue() > cMax.getValue()){ 
       cMax = response.Results[i].Confidence; 
       iMax = i; 
      } 
     } 
     this.WriteLine(response.Results[iMax].DisplayText); 
    } 

} 



/** 
* Called when a final response is received and its intent is parsed 
*/ 

public void onIntentReceived(final String payload) { 
    this.WriteLine("--- Intent received by onIntentReceived() ---"); 
    this.WriteLine(payload); 
    this.WriteLine(); 
} 

public void onPartialResponseReceived(final String response) { 
    this.WriteLine("--- Partial result received by onPartialResponseReceived() ---"); 
    this.WriteLine(response); 
    this.WriteLine(); 
} 

public void onError(final int errorCode, final String response) { 
    this.WriteLine("--- Error received by onError() ---"); 
    this.WriteLine("Error code: " + SpeechClientStatus.fromInt(errorCode) + " " + errorCode); 
    this.WriteLine("Error text: " + response); 
    this.WriteLine(); 
} 

/** 
* Called when the microphone status has changed. 
* @param recording The current recording state 
*/ 
public void onAudioEvent(boolean recording) { 
    if (!recording) { 
     this.micClient.endMicAndRecognition(); 
    } 
} 

/** 
* Writes the line. 
*/ 
private void WriteLine() { 
    this.WriteLine(""); 
} 

/** 
* Writes the line. 
* @param text The line to write. 
*/ 
private void WriteLine(String text) { 
    System.out.println(text); 
} 

В отдельный класс

public class SpeechRecognition implements ISpeechRecognitionServerEvents 
{ 
int m_waitSeconds = 0; 
private MicrophoneRecognitionClient micClient = null; 
private FinalResponseStatus isReceivedResponse =FinalResponseStatus.NotReceived; 

private Boolean speechIntent = false; 
private SpeechRecognitionMode speechMode=SpeechRecognitionMode.ShortPhrase; 

public enum FinalResponseStatus { NotReceived, OK } 

/** 
* Gets the primary subscription key 
*/ 
public String getPrimaryKey() { 
    return Integer.toString(R.string.primaryKey); 
} 
/** 
* Gets the secondary subscription key 
*/ 
public String getSecondaryKey() { 
    return Integer.toString(R.string.secondaryKey); 
} 

/** 
* Gets the LUIS application identifier. 
* @return The LUIS application identifier. 
*/ 
private String getLuisAppId() { 
    return Integer.toString(R.string.luisAppID); 
} 

/** 
* Gets the LUIS subscription identifier. 
* @return The LUIS subscription identifier. 
*/ 
private String getLuisSubscriptionID() { 
    return Integer.toString(R.string.luisSubscriptionID); 
} 

/** 
* Gets the default locale. 
* @return The default locale. 
*/ 
private String getDefaultLocale() { 
    return "en-us"; 
} 

public void startSpeechRecognition() { 

    this.m_waitSeconds = this.speechMode == SpeechRecognitionMode.ShortPhrase ? 20 : 200; 

    if (this.micClient == null) { 
     if (this.speechIntent) { 
      this.micClient = SpeechRecognitionServiceFactory.createMicrophoneClientWithIntent(
          this.getDefaultLocale(), 
          this, 
          this.getPrimaryKey(), 
          this.getSecondaryKey(), 
          this.getLuisAppId(), 
          this.getLuisSubscriptionID()); 
     } 
     else 
     { 
      this.micClient = SpeechRecognitionServiceFactory.createMicrophoneClient(
        this.speechMode, 
        this.getDefaultLocale(), 
        this, 
        this.getPrimaryKey(), 
        this.getSecondaryKey()); 

     } 
    } 

    this.micClient.startMicAndRecognition(); 


} 

public void endSpeechRecognition(){ 
    this.micClient.endMicAndRecognition(); 
} 


public void onFinalResponseReceived(final RecognitionResult response) { 
    boolean isFinalDicationMessage = this.speechMode == SpeechRecognitionMode.LongDictation && 
      (response.RecognitionStatus == RecognitionStatus.EndOfDictation || 
        response.RecognitionStatus == RecognitionStatus.DictationEndSilenceTimeout); 
    if (null != this.micClient && ((this.speechMode == SpeechRecognitionMode.ShortPhrase) || isFinalDicationMessage)) { 
     // we got the final result, so it we can end the mic reco. No need to do this 
     // for dataReco, since we already called endAudio() on it as soon as we were done 
     // sending all the data. 
     this.micClient.endMicAndRecognition(); 
    } 

    if (isFinalDicationMessage) { 
     this.isReceivedResponse = FinalResponseStatus.OK; 
    } 

    Confidence cMax = Confidence.Low; 
    int iMax = 0; 
    if (!isFinalDicationMessage && response.Results.length != 0) { 
     for (int i = 0; i < response.Results.length; i++) { 
      //get the text with highest confidence: 
      if(response.Results[i].Confidence.getValue() > cMax.getValue()){ 
       cMax = response.Results[i].Confidence; 
       iMax = i; 
      } 
     } 
     System.out.println("Action to take: " + response.Results[iMax].DisplayText); 
    } 

} 

/** 
* Called when a final response is received and its intent is parsed 
*/ 
public void onIntentReceived(final String payload) { 
    System.out.println("--- Intent received by onIntentReceived() ---"); 
    System.out.println(payload); 
} 

public void onPartialResponseReceived(final String response) { 
    System.out.println("--- Partial result received by onPartialResponseReceived() ---"); 
    System.out.println(response); 
} 

public void onError(final int errorCode, final String response) { 
    System.err.println("--- Error received by onError() ---"); 
    System.err.println("Error code: " + SpeechClientStatus.fromInt(errorCode) + " " + errorCode); 
    System.err.println("Error text: " + response); 
} 

/** 
* Called when the microphone status has changed. 
* @param recording The current recording state 
*/ 
public void onAudioEvent(boolean recording) { 
    System.out.println("--- Microphone status change received by onAudioEvent() ---"); 
    System.out.println("********* Microphone status: " + recording + " *********"); 
    if (recording) { 
     System.out.println("Please start speaking."); 
    } 

    if (!recording) { 
     this.micClient.endMicAndRecognition(); 
    } 
} 

}

Вы можете очистить Посмотрим, что это в основном тот же код, но он дает мне эту ошибку в функции onError после того, как я вызываю this.micClient.startMicAndRecognition(); :

Error code: LoginFailed -1910505470 
+0

Вы намеренно используете разные конструкторы createMicrophoneClient в новом классе? Вы тестировали эти конструкторы в исходном классе? – brandall

+0

Да Я намеренно использую другой конструктор из-за того, что ему не требуется действие как параметр. В любом случае я пробовал оба конструктора в основной деятельности, и они работают отлично. Когда дело доходит до ошибки, оно появляется, когда я начинаю запись, когда не пытаюсь создать MicClient, конструктор возвращает micClient. @brandall – Najj

+0

Хорошо. Тогда все, что осталось, это проблема с потоками? Попробуйте запустить код из потока пользовательского интерфейса, а затем протестируйте фоновый поток. Убедитесь, что вы не вызываете конструктор и 'startSpeechRecognition' из разных потоков. Задайте настройку 'MicrophoneRecognitionClient'' volatile', если это ваше намерение. – brandall

ответ

0

Я решил проблему. я получаю неправильный первичный ключ в этой строке кода:

public String getPrimaryKey() { 
    return Integer.toString(R.string.primaryKey); 
} 

Это происходит потому, что первичный ключ слишком долго, чтобы быть считаны процессором как целое, то преобразованного в строку. Я должен был получить первичный ключ от основного действия через getString (R.string.primaryKey) затем передать его как параметр конструктору класса SpeechRecognition.

Смежные вопросы