{"version":3,"sources":["src/common.speech/TranslationServiceRecognizer.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,YAAY,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,qBAAqB,EACrB,kBAAkB,EAIlB,uBAAuB,EAGvB,4BAA4B,EAC5B,qBAAqB,EAIxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAIH,qBAAqB,EAKxB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAG7E,qBAAa,4BAA6B,SAAQ,qBAAqB;IACnE,OAAO,CAAC,yBAAyB,CAAwB;gBAGrD,cAAc,EAAE,eAAe,EAC/B,iBAAiB,EAAE,kBAAkB,EACrC,WAAW,EAAE,YAAY,EACzB,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;IAOhD,SAAS,CAAC,2BAA2B,CACjC,iBAAiB,EAAE,uBAAuB,EAC1C,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,4BAA4B,KAAK,IAAI,EAC3D,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAyK9C,SAAS,CAAC,iBAAiB,CACvB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,kBAAkB,EACtC,SAAS,EAAE,qBAAqB,EAChC,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,CAAC,CAAC,EAAE,uBAAuB,KAAK,IAAI,GAAG,IAAI;IAsCnE,OAAO,CAAC,kBAAkB;IAsC1B,OAAO,CAAC,kBAAkB;CAgB7B","file":"TranslationServiceRecognizer.d.ts","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport {\n    IAudioSource,\n    MessageType,\n    TranslationStatus,\n} from \"../common/Exports\";\nimport {\n    CancellationErrorCode,\n    CancellationReason,\n    PropertyCollection,\n    PropertyId,\n    ResultReason,\n    SpeechRecognitionResult,\n    TranslationRecognitionCanceledEventArgs,\n    TranslationRecognitionEventArgs,\n    TranslationRecognitionResult,\n    TranslationRecognizer,\n    Translations,\n    TranslationSynthesisEventArgs,\n    TranslationSynthesisResult,\n} from \"../sdk/Exports\";\nimport {\n    CancellationErrorCodePropertyName,\n    EnumTranslation,\n    RecognitionStatus,\n    ServiceRecognizerBase,\n    SynthesisStatus,\n    TranslationHypothesis,\n    TranslationPhrase,\n    TranslationSynthesisEnd,\n} from \"./Exports\";\nimport { IAuthentication } from \"./IAuthentication\";\nimport { IConnectionFactory } from \"./IConnectionFactory\";\nimport { RecognizerConfig } from \"./RecognizerConfig\";\nimport { SpeechConnectionMessage } from \"./SpeechConnectionMessage.Internal\";\n\n// tslint:disable-next-line:max-classes-per-file\nexport class TranslationServiceRecognizer extends ServiceRecognizerBase {\n    private privTranslationRecognizer: TranslationRecognizer;\n\n    public constructor(\n        authentication: IAuthentication,\n        connectionFactory: IConnectionFactory,\n        audioSource: IAudioSource,\n        recognizerConfig: RecognizerConfig,\n        translationRecognizer: TranslationRecognizer) {\n\n        super(authentication, connectionFactory, audioSource, recognizerConfig, translationRecognizer);\n        this.privTranslationRecognizer = translationRecognizer;\n\n    }\n\n    protected processTypeSpecificMessages(\n        connectionMessage: SpeechConnectionMessage,\n        successCallback?: (e: TranslationRecognitionResult) => void,\n        errorCallBack?: (e: string) => void): void {\n\n        const resultProps: PropertyCollection = new PropertyCollection();\n        if (connectionMessage.messageType === MessageType.Text) {\n            resultProps.setProperty(PropertyId.SpeechServiceResponse_JsonResult, connectionMessage.textBody);\n        }\n\n        switch (connectionMessage.path.toLowerCase()) {\n            case \"translation.hypothesis\":\n\n                const result: TranslationRecognitionEventArgs = this.fireEventForResult(TranslationHypothesis.fromJSON(connectionMessage.textBody), resultProps);\n                this.privRequestSession.onHypothesis(this.privRequestSession.currentTurnAudioOffset + result.offset);\n\n                if (!!this.privTranslationRecognizer.recognizing) {\n                    try {\n                        this.privTranslationRecognizer.recognizing(this.privTranslationRecognizer, result);\n                        /* tslint:disable:no-empty */\n                    } catch (error) {\n                        // Not going to let errors in the event handler\n                        // trip things up.\n                    }\n                }\n\n                break;\n            case \"translation.phrase\":\n                const translatedPhrase: TranslationPhrase = TranslationPhrase.fromJSON(connectionMessage.textBody);\n\n                this.privRequestSession.onPhraseRecognized(this.privRequestSession.currentTurnAudioOffset + translatedPhrase.Offset + translatedPhrase.Duration);\n\n                if (translatedPhrase.RecognitionStatus === RecognitionStatus.Success) {\n\n                    // OK, the recognition was successful. How'd the translation do?\n                    const result: TranslationRecognitionEventArgs = this.fireEventForResult(translatedPhrase, resultProps);\n                    if (!!this.privTranslationRecognizer.recognized) {\n                        try {\n                            this.privTranslationRecognizer.recognized(this.privTranslationRecognizer, result);\n                            /* tslint:disable:no-empty */\n                        } catch (error) {\n                            // Not going to let errors in the event handler\n                            // trip things up.\n                        }\n                    }\n\n                    // report result to promise.\n                    if (!!successCallback) {\n                        try {\n                            successCallback(result.result);\n                        } catch (e) {\n                            if (!!errorCallBack) {\n                                errorCallBack(e);\n                            }\n                        }\n                        // Only invoke the call back once.\n                        // and if it's successful don't invoke the\n                        // error after that.\n                        successCallback = undefined;\n                        errorCallBack = undefined;\n                    }\n\n                    break;\n                } else {\n                    const reason: ResultReason = EnumTranslation.implTranslateRecognitionResult(translatedPhrase.RecognitionStatus);\n\n                    const result = new TranslationRecognitionResult(\n                        undefined,\n                        this.privRequestSession.requestId,\n                        reason,\n                        translatedPhrase.Text,\n                        translatedPhrase.Duration,\n                        this.privRequestSession.currentTurnAudioOffset + translatedPhrase.Offset,\n                        undefined,\n                        connectionMessage.textBody,\n                        resultProps);\n\n                    if (reason === ResultReason.Canceled) {\n                        const cancelReason: CancellationReason = EnumTranslation.implTranslateCancelResult(translatedPhrase.RecognitionStatus);\n\n                        this.cancelRecognitionLocal(\n                            cancelReason,\n                            EnumTranslation.implTranslateCancelErrorCode(translatedPhrase.RecognitionStatus),\n                            undefined,\n                            successCallback);\n                    } else {\n                        if (!(this.privRequestSession.isSpeechEnded && reason === ResultReason.NoMatch && translatedPhrase.RecognitionStatus !== RecognitionStatus.InitialSilenceTimeout)) {\n                            const ev = new TranslationRecognitionEventArgs(result, result.offset, this.privRequestSession.sessionId);\n\n                            if (!!this.privTranslationRecognizer.recognized) {\n                                try {\n                                    this.privTranslationRecognizer.recognized(this.privTranslationRecognizer, ev);\n                                    /* tslint:disable:no-empty */\n                                } catch (error) {\n                                    // Not going to let errors in the event handler\n                                    // trip things up.\n                                }\n                            }\n                        }\n\n                        // report result to promise.\n                        if (!!successCallback) {\n                            try {\n                                successCallback(result);\n                            } catch (e) {\n                                if (!!errorCallBack) {\n                                    errorCallBack(e);\n                                }\n                            }\n                            // Only invoke the call back once.\n                            // and if it's successful don't invoke the\n                            // error after that.\n                            successCallback = undefined;\n                            errorCallBack = undefined;\n                        }\n                    }\n                }\n                break;\n\n            case \"translation.synthesis\":\n                this.sendSynthesisAudio(connectionMessage.binaryBody, this.privRequestSession.sessionId);\n                break;\n\n            case \"translation.synthesis.end\":\n                const synthEnd: TranslationSynthesisEnd = TranslationSynthesisEnd.fromJSON(connectionMessage.textBody);\n\n                switch (synthEnd.SynthesisStatus) {\n                    case SynthesisStatus.Error:\n                        if (!!this.privTranslationRecognizer.synthesizing) {\n                            const result = new TranslationSynthesisResult(ResultReason.Canceled, undefined);\n                            const retEvent: TranslationSynthesisEventArgs = new TranslationSynthesisEventArgs(result, this.privRequestSession.sessionId);\n\n                            try {\n                                this.privTranslationRecognizer.synthesizing(this.privTranslationRecognizer, retEvent);\n                                /* tslint:disable:no-empty */\n                            } catch (error) {\n                                // Not going to let errors in the event handler\n                                // trip things up.\n                            }\n                        }\n\n                        if (!!this.privTranslationRecognizer.canceled) {\n                            // And raise a canceled event to send the rich(er) error message back.\n                            const canceledResult: TranslationRecognitionCanceledEventArgs = new TranslationRecognitionCanceledEventArgs(\n                                this.privRequestSession.sessionId,\n                                CancellationReason.Error,\n                                synthEnd.FailureReason,\n                                CancellationErrorCode.ServiceError,\n                                null);\n\n                            try {\n                                this.privTranslationRecognizer.canceled(this.privTranslationRecognizer, canceledResult);\n                                /* tslint:disable:no-empty */\n                            } catch (error) {\n                                // Not going to let errors in the event handler\n                                // trip things up.\n                            }\n                        }\n                        break;\n                    case SynthesisStatus.Success:\n                        this.sendSynthesisAudio(undefined, this.privRequestSession.sessionId);\n                        break;\n                    default:\n                        break;\n                }\n                break;\n            default:\n                break;\n        }\n    }\n\n    // Cancels recognition.\n    protected cancelRecognition(\n        sessionId: string,\n        requestId: string,\n        cancellationReason: CancellationReason,\n        errorCode: CancellationErrorCode,\n        error: string,\n        cancelRecoCallback: (e: SpeechRecognitionResult) => void): void {\n\n        const properties: PropertyCollection = new PropertyCollection();\n        properties.setProperty(CancellationErrorCodePropertyName, CancellationErrorCode[errorCode]);\n\n        if (!!this.privTranslationRecognizer.canceled) {\n\n            const cancelEvent: TranslationRecognitionCanceledEventArgs = new TranslationRecognitionCanceledEventArgs(\n                sessionId,\n                cancellationReason,\n                error,\n                errorCode,\n                undefined);\n\n            try {\n                this.privTranslationRecognizer.canceled(this.privTranslationRecognizer, cancelEvent);\n                /* tslint:disable:no-empty */\n            } catch { }\n        }\n\n        if (!!cancelRecoCallback) {\n            const result: TranslationRecognitionResult = new TranslationRecognitionResult(\n                undefined, // Translations\n                requestId,\n                ResultReason.Canceled,\n                undefined, // Text\n                undefined, // Druation\n                undefined, // Offset\n                error,\n                undefined, // Json\n                properties);\n            try {\n                cancelRecoCallback(result);\n                /* tslint:disable:no-empty */\n            } catch { }\n        }\n    }\n\n    private fireEventForResult(serviceResult: TranslationHypothesis | TranslationPhrase, properties: PropertyCollection): TranslationRecognitionEventArgs {\n        let translations: Translations;\n\n        if (undefined !== serviceResult.Translation.Translations) {\n            translations = new Translations();\n            for (const translation of serviceResult.Translation.Translations) {\n                translations.set(translation.Language, translation.Text);\n            }\n        }\n\n        let resultReason: ResultReason;\n        if (serviceResult instanceof TranslationPhrase) {\n            if (serviceResult.Translation.TranslationStatus === TranslationStatus.Success) {\n                resultReason = ResultReason.TranslatedSpeech;\n            } else {\n                resultReason = ResultReason.RecognizedSpeech;\n            }\n        } else {\n            resultReason = ResultReason.TranslatingSpeech;\n        }\n\n        const offset: number = serviceResult.Offset + this.privRequestSession.currentTurnAudioOffset;\n\n        const result = new TranslationRecognitionResult(\n            translations,\n            this.privRequestSession.requestId,\n            resultReason,\n            serviceResult.Text,\n            serviceResult.Duration,\n            offset,\n            serviceResult.Translation.FailureReason,\n            JSON.stringify(serviceResult),\n            properties);\n\n        const ev = new TranslationRecognitionEventArgs(result, offset, this.privRequestSession.sessionId);\n        return ev;\n    }\n\n    private sendSynthesisAudio(audio: ArrayBuffer, sessionId: string): void {\n        const reason = (undefined === audio) ? ResultReason.SynthesizingAudioCompleted : ResultReason.SynthesizingAudio;\n        const result = new TranslationSynthesisResult(reason, audio);\n        const retEvent: TranslationSynthesisEventArgs = new TranslationSynthesisEventArgs(result, sessionId);\n\n        if (!!this.privTranslationRecognizer.synthesizing) {\n            try {\n                this.privTranslationRecognizer.synthesizing(this.privTranslationRecognizer, retEvent);\n                /* tslint:disable:no-empty */\n            } catch (error) {\n                // Not going to let errors in the event handler\n                // trip things up.\n            }\n        }\n\n    }\n}\n"]}