in src/common.speech/TranslationServiceRecognizer.ts [64:245]
protected async processTypeSpecificMessages(connectionMessage: SpeechConnectionMessage): Promise<boolean> {
const resultProps: PropertyCollection = new PropertyCollection();
let processed: boolean = false;
const handleTranslationPhrase = async (translatedPhrase: TranslationPhrase): Promise<void> => {
this.privRequestSession.onPhraseRecognized(this.privRequestSession.currentTurnAudioOffset + translatedPhrase.Offset + translatedPhrase.Duration);
if (translatedPhrase.RecognitionStatus === RecognitionStatus.Success) {
// OK, the recognition was successful. How'd the translation do?
const result: TranslationRecognitionEventArgs = this.fireEventForResult(translatedPhrase, resultProps);
if (!!this.privTranslationRecognizer.recognized) {
try {
this.privTranslationRecognizer.recognized(this.privTranslationRecognizer, result);
/* tslint:disable:no-empty */
} catch (error) {
// Not going to let errors in the event handler
// trip things up.
}
}
// report result to promise.
if (!!this.privSuccessCallback) {
try {
this.privSuccessCallback(result.result);
} catch (e) {
if (!!this.privErrorCallback) {
this.privErrorCallback(e);
}
}
// Only invoke the call back once.
// and if it's successful don't invoke the
// error after that.
this.privSuccessCallback = undefined;
this.privErrorCallback = undefined;
}
} else {
const reason: ResultReason = EnumTranslation.implTranslateRecognitionResult(translatedPhrase.RecognitionStatus);
const result = new TranslationRecognitionResult(
undefined,
this.privRequestSession.requestId,
reason,
translatedPhrase.Text,
translatedPhrase.Duration,
this.privRequestSession.currentTurnAudioOffset + translatedPhrase.Offset,
undefined,
connectionMessage.textBody,
resultProps);
if (reason === ResultReason.Canceled) {
const cancelReason: CancellationReason = EnumTranslation.implTranslateCancelResult(translatedPhrase.RecognitionStatus);
const cancellationErrorCode: CancellationErrorCode = EnumTranslation.implTranslateCancelErrorCode(translatedPhrase.RecognitionStatus);
await this.cancelRecognitionLocal(
cancelReason,
cancellationErrorCode,
EnumTranslation.implTranslateErrorDetails(cancellationErrorCode));
} else {
if (!(this.privRequestSession.isSpeechEnded && reason === ResultReason.NoMatch && translatedPhrase.RecognitionStatus !== RecognitionStatus.InitialSilenceTimeout)) {
const ev = new TranslationRecognitionEventArgs(result, result.offset, this.privRequestSession.sessionId);
if (!!this.privTranslationRecognizer.recognized) {
try {
this.privTranslationRecognizer.recognized(this.privTranslationRecognizer, ev);
/* tslint:disable:no-empty */
} catch (error) {
// Not going to let errors in the event handler
// trip things up.
}
}
}
// report result to promise.
if (!!this.privSuccessCallback) {
try {
this.privSuccessCallback(result);
} catch (e) {
if (!!this.privErrorCallback) {
this.privErrorCallback(e);
}
}
// Only invoke the call back once.
// and if it's successful don't invoke the
// error after that.
this.privSuccessCallback = undefined;
this.privErrorCallback = undefined;
}
}
processed = true;
}
};
if (connectionMessage.messageType === MessageType.Text) {
resultProps.setProperty(PropertyId.SpeechServiceResponse_JsonResult, connectionMessage.textBody);
}
switch (connectionMessage.path.toLowerCase()) {
case "translation.hypothesis":
const result: TranslationRecognitionEventArgs = this.fireEventForResult(TranslationHypothesis.fromJSON(connectionMessage.textBody), resultProps);
this.privRequestSession.onHypothesis(this.privRequestSession.currentTurnAudioOffset + result.offset);
if (!!this.privTranslationRecognizer.recognizing) {
try {
this.privTranslationRecognizer.recognizing(this.privTranslationRecognizer, result);
/* tslint:disable:no-empty */
} catch (error) {
// Not going to let errors in the event handler
// trip things up.
}
}
processed = true;
break;
case "translation.response":
const phrase: { SpeechPhrase: ITranslationPhrase } = JSON.parse(connectionMessage.textBody);
if (!!phrase.SpeechPhrase) {
await handleTranslationPhrase(TranslationPhrase.fromTranslationResponse(phrase));
}
break;
case "translation.phrase":
await handleTranslationPhrase(TranslationPhrase.fromJSON(connectionMessage.textBody));
break;
case "translation.synthesis":
this.sendSynthesisAudio(connectionMessage.binaryBody, this.privRequestSession.sessionId);
processed = true;
break;
case "translation.synthesis.end":
const synthEnd: TranslationSynthesisEnd = TranslationSynthesisEnd.fromJSON(connectionMessage.textBody);
switch (synthEnd.SynthesisStatus) {
case SynthesisStatus.Error:
if (!!this.privTranslationRecognizer.synthesizing) {
const result = new TranslationSynthesisResult(ResultReason.Canceled, undefined);
const retEvent: TranslationSynthesisEventArgs = new TranslationSynthesisEventArgs(result, this.privRequestSession.sessionId);
try {
this.privTranslationRecognizer.synthesizing(this.privTranslationRecognizer, retEvent);
/* tslint:disable:no-empty */
} catch (error) {
// Not going to let errors in the event handler
// trip things up.
}
}
if (!!this.privTranslationRecognizer.canceled) {
// And raise a canceled event to send the rich(er) error message back.
const canceledResult: TranslationRecognitionCanceledEventArgs = new TranslationRecognitionCanceledEventArgs(
this.privRequestSession.sessionId,
CancellationReason.Error,
synthEnd.FailureReason,
CancellationErrorCode.ServiceError,
null);
try {
this.privTranslationRecognizer.canceled(this.privTranslationRecognizer, canceledResult);
/* tslint:disable:no-empty */
} catch (error) {
// Not going to let errors in the event handler
// trip things up.
}
}
break;
case SynthesisStatus.Success:
this.sendSynthesisAudio(undefined, this.privRequestSession.sessionId);
break;
default:
break;
}
processed = true;
break;
default:
break;
}
return processed;
}