From 5668bf632b69c678ee25fca88c718a19e42408e1 Mon Sep 17 00:00:00 2001 From: Glenn Harper Date: Fri, 22 Sep 2023 12:43:07 -0700 Subject: [PATCH 1/3] conditionally import audioWorkerUrl method using import.meta --- src/common.browser/PCMRecorder.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common.browser/PCMRecorder.ts b/src/common.browser/PCMRecorder.ts index 5832e539..d3dadc3d 100644 --- a/src/common.browser/PCMRecorder.ts +++ b/src/common.browser/PCMRecorder.ts @@ -2,7 +2,6 @@ // Licensed under the MIT license. import { RiffPcmEncoder, Stream } from "../common/Exports"; -import { getAudioWorkerUrl } from "./AudioWorkerUrl"; import { IRecorder } from "./IRecorder"; export class PcmRecorder implements IRecorder { @@ -91,7 +90,10 @@ export class PcmRecorder implements IRecorder { const skipAudioWorklet = !!this.privSpeechProcessorScript && this.privSpeechProcessorScript.toLowerCase() === "ignore"; if (!!context.audioWorklet && !skipAudioWorklet) { - this.privSpeechProcessorScript = getAudioWorkerUrl(); + /* eslint-disable-next-line */ + const audioUrl = require("./AudioWorkerUrl"); + /* eslint-disable-next-line */ + this.privSpeechProcessorScript = audioUrl.getAudioWorkerUrl(); context.audioWorklet .addModule(this.privSpeechProcessorScript) From 2a593beb255a6498c7eb09fa51356f7060285b47 Mon Sep 17 00:00:00 2001 From: glenn Date: Sun, 24 Sep 2023 09:53:25 -0400 Subject: [PATCH 2/3] remove jest.mock from tests --- tests/AudioOutputStreamTests.ts | 3 --- tests/AutoSourceLangDetectionTests.ts | 4 ---- tests/ConnectionTests.ts | 4 ---- tests/ConversationTranscriberTests.ts | 4 ---- tests/ConversationTranslatorTests.ts | 4 ---- tests/DiagnosticsTests.ts | 4 ---- tests/DialogServiceConnectorTests.ts | 4 ---- tests/DynamicGrammarTests.ts | 4 ---- tests/GeneralRecognizerTests.ts | 4 ---- tests/IntentRecognizerTests.ts | 4 ---- tests/LanguageModelTests.ts | 4 ---- tests/LongRunning/SpeechRecoAuthTokenErrorMessageTests.ts | 3 --- tests/LongRunning/SpeechRecoAuthTokenRefreshTests.ts | 4 ---- tests/LongRunning/SpeechRecoReconnectTests.ts | 4 ---- tests/LongRunning/TranslationRecoReconnectTests.ts | 4 ---- tests/MeetingTranscriberTests.ts | 4 ---- tests/PronunciationAssessmentTests.ts | 4 ---- tests/PullInputStreamTests.ts | 4 ---- tests/PushInputStreamTests.ts | 4 ---- tests/ReplayableAudioNodeTests.ts | 4 ---- tests/SpeechConfigTests.ts | 4 ---- tests/SpeechContextTests.ts | 4 ---- tests/SpeechRecognizerSilenceTests.ts | 5 ----- tests/SpeechRecognizerTests.ts | 4 ---- tests/SpeechSynthesisTests.ts | 4 ---- tests/TranslationRecognizerBasicsTests.ts | 4 ---- tests/TranslationRecognizerTests.ts | 5 ----- tests/TranslationSynthTests.ts | 5 ----- tests/VoiceProfileClientTests.ts | 3 --- 29 files changed, 116 deletions(-) diff --git a/tests/AudioOutputStreamTests.ts b/tests/AudioOutputStreamTests.ts index 982d1455..674a143e 100644 --- a/tests/AudioOutputStreamTests.ts +++ b/tests/AudioOutputStreamTests.ts @@ -7,9 +7,6 @@ import { Settings } from "./Settings"; import { closeAsyncObjects } from "./Utilities"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); beforeAll(() => { // Override inputs, if necessary diff --git a/tests/AutoSourceLangDetectionTests.ts b/tests/AutoSourceLangDetectionTests.ts index 826ad89e..8aba79d1 100644 --- a/tests/AutoSourceLangDetectionTests.ts +++ b/tests/AutoSourceLangDetectionTests.ts @@ -27,10 +27,6 @@ import { Settings } from "./Settings"; import { closeAsyncObjects, WaitForCondition } from "./Utilities"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let objsToClose: any[]; const defaultTargetLanguage: string = "de-DE"; diff --git a/tests/ConnectionTests.ts b/tests/ConnectionTests.ts index 603b9452..60bebfac 100644 --- a/tests/ConnectionTests.ts +++ b/tests/ConnectionTests.ts @@ -22,10 +22,6 @@ import { import * as fs from "fs"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let objsToClose: any[]; beforeAll(() => { diff --git a/tests/ConversationTranscriberTests.ts b/tests/ConversationTranscriberTests.ts index 0035d243..a2f8f842 100644 --- a/tests/ConversationTranscriberTests.ts +++ b/tests/ConversationTranscriberTests.ts @@ -23,10 +23,6 @@ import { Settings } from "./Settings"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; import { closeAsyncObjects, RepeatingPullStream, WaitForCondition } from "./Utilities"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let objsToClose: any[]; beforeAll(() => { diff --git a/tests/ConversationTranslatorTests.ts b/tests/ConversationTranslatorTests.ts index 9fb40052..16b73146 100644 --- a/tests/ConversationTranslatorTests.ts +++ b/tests/ConversationTranslatorTests.ts @@ -26,10 +26,6 @@ import { } from "./Utilities"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - // eslint-disable-next-line no-console const consoleInfo = console.info; diff --git a/tests/DiagnosticsTests.ts b/tests/DiagnosticsTests.ts index f7032744..1a094690 100644 --- a/tests/DiagnosticsTests.ts +++ b/tests/DiagnosticsTests.ts @@ -9,10 +9,6 @@ import { closeAsyncObjects, WaitForCondition } from "./Utilities"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll((): void => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/DialogServiceConnectorTests.ts b/tests/DialogServiceConnectorTests.ts index d5f86965..e4ccaf31 100644 --- a/tests/DialogServiceConnectorTests.ts +++ b/tests/DialogServiceConnectorTests.ts @@ -46,10 +46,6 @@ import { } from "./Utilities"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - // eslint-disable-next-line no-console const consoleInfo = console.info; const simpleMessageObj = { speak: "This is speech", text: "This is text", type: "message" }; diff --git a/tests/DynamicGrammarTests.ts b/tests/DynamicGrammarTests.ts index b49244a0..77d8625e 100644 --- a/tests/DynamicGrammarTests.ts +++ b/tests/DynamicGrammarTests.ts @@ -9,10 +9,6 @@ import { } from "../src/common.speech/Exports"; import { Settings } from "./Settings"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/GeneralRecognizerTests.ts b/tests/GeneralRecognizerTests.ts index 7a3cb4d0..0419343b 100644 --- a/tests/GeneralRecognizerTests.ts +++ b/tests/GeneralRecognizerTests.ts @@ -5,10 +5,6 @@ import * as sdk from "../microsoft.cognitiveservices.speech.sdk"; import { Settings } from "./Settings"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let bufferSize: number; beforeEach(() => { // eslint-disable-next-line no-console diff --git a/tests/IntentRecognizerTests.ts b/tests/IntentRecognizerTests.ts index 8b7f8c12..9e58a03a 100644 --- a/tests/IntentRecognizerTests.ts +++ b/tests/IntentRecognizerTests.ts @@ -18,10 +18,6 @@ import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; import { AudioStreamFormatImpl } from "../src/sdk/Audio/AudioStreamFormat"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let bufferSize: number; beforeAll(() => { diff --git a/tests/LanguageModelTests.ts b/tests/LanguageModelTests.ts index e7e21896..e4640a75 100644 --- a/tests/LanguageModelTests.ts +++ b/tests/LanguageModelTests.ts @@ -5,10 +5,6 @@ import * as sdk from "../microsoft.cognitiveservices.speech.sdk"; import { LanguageUnderstandingModelImpl } from "../src/sdk/LanguageUnderstandingModel"; import { Settings } from "./Settings"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/LongRunning/SpeechRecoAuthTokenErrorMessageTests.ts b/tests/LongRunning/SpeechRecoAuthTokenErrorMessageTests.ts index f4596375..45075f6a 100644 --- a/tests/LongRunning/SpeechRecoAuthTokenErrorMessageTests.ts +++ b/tests/LongRunning/SpeechRecoAuthTokenErrorMessageTests.ts @@ -9,9 +9,6 @@ import { Settings } from "../Settings"; import { CreateRepeatingPullStream, WaitForCondition } from "../Utilities"; let objsToClose: any[]; -jest.mock("../../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); beforeAll(() => { // override inputs, if necessary diff --git a/tests/LongRunning/SpeechRecoAuthTokenRefreshTests.ts b/tests/LongRunning/SpeechRecoAuthTokenRefreshTests.ts index 9d731569..94a24d95 100644 --- a/tests/LongRunning/SpeechRecoAuthTokenRefreshTests.ts +++ b/tests/LongRunning/SpeechRecoAuthTokenRefreshTests.ts @@ -11,10 +11,6 @@ import { CreateRepeatingPullStream, WaitForCondition } from "../Utilities"; let objsToClose: any[]; -jest.mock("../../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/LongRunning/SpeechRecoReconnectTests.ts b/tests/LongRunning/SpeechRecoReconnectTests.ts index 8a0d090c..a911a3ae 100644 --- a/tests/LongRunning/SpeechRecoReconnectTests.ts +++ b/tests/LongRunning/SpeechRecoReconnectTests.ts @@ -11,10 +11,6 @@ import { WaitForCondition } from "../Utilities"; let objsToClose: any[]; -jest.mock("../../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll((): void => { // override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/LongRunning/TranslationRecoReconnectTests.ts b/tests/LongRunning/TranslationRecoReconnectTests.ts index 6a507ecf..73d0305b 100644 --- a/tests/LongRunning/TranslationRecoReconnectTests.ts +++ b/tests/LongRunning/TranslationRecoReconnectTests.ts @@ -12,10 +12,6 @@ import { WaitForCondition } from "../Utilities"; let objsToClose: any[]; -jest.mock("../../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll((): void => { // override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/MeetingTranscriberTests.ts b/tests/MeetingTranscriberTests.ts index 2241ba18..9cfd15c5 100644 --- a/tests/MeetingTranscriberTests.ts +++ b/tests/MeetingTranscriberTests.ts @@ -13,10 +13,6 @@ import { Settings } from "./Settings"; import { closeAsyncObjects } from "./Utilities"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let objsToClose: any[]; function sleep(milliseconds: number): Promise { diff --git a/tests/PronunciationAssessmentTests.ts b/tests/PronunciationAssessmentTests.ts index 1bad8552..5a8c0d59 100644 --- a/tests/PronunciationAssessmentTests.ts +++ b/tests/PronunciationAssessmentTests.ts @@ -17,10 +17,6 @@ import { Settings } from "./Settings"; import { closeAsyncObjects } from "./Utilities"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let objsToClose: any[]; beforeAll((): void => { diff --git a/tests/PullInputStreamTests.ts b/tests/PullInputStreamTests.ts index d006b20b..adf034e0 100644 --- a/tests/PullInputStreamTests.ts +++ b/tests/PullInputStreamTests.ts @@ -16,10 +16,6 @@ import { Settings } from "./Settings"; let bufferSize: number; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/PushInputStreamTests.ts b/tests/PushInputStreamTests.ts index b706e7df..ef526950 100644 --- a/tests/PushInputStreamTests.ts +++ b/tests/PushInputStreamTests.ts @@ -15,10 +15,6 @@ import { } from "../src/sdk/Audio/AudioStreamFormat"; import { Settings } from "./Settings"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - let bufferSize: number; beforeAll(() => { // Override inputs, if necessary diff --git a/tests/ReplayableAudioNodeTests.ts b/tests/ReplayableAudioNodeTests.ts index 57a5c807..1e407ab8 100644 --- a/tests/ReplayableAudioNodeTests.ts +++ b/tests/ReplayableAudioNodeTests.ts @@ -14,10 +14,6 @@ let readCount: number; const targetBytes: number = 4096; const defaultAudioFormat: AudioStreamFormatImpl = sdk.AudioStreamFormat.getDefaultInputFormat() as AudioStreamFormatImpl; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeEach(() => { readCount = 0; }); diff --git a/tests/SpeechConfigTests.ts b/tests/SpeechConfigTests.ts index d4514e82..1304069b 100644 --- a/tests/SpeechConfigTests.ts +++ b/tests/SpeechConfigTests.ts @@ -19,10 +19,6 @@ import { closeAsyncObjects } from "./Utilities"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll((): void => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/SpeechContextTests.ts b/tests/SpeechContextTests.ts index 29881f6d..a03bedd0 100644 --- a/tests/SpeechContextTests.ts +++ b/tests/SpeechContextTests.ts @@ -10,10 +10,6 @@ import { } from "../src/common.speech/Exports"; import { Settings } from "./Settings"; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/SpeechRecognizerSilenceTests.ts b/tests/SpeechRecognizerSilenceTests.ts index b1505615..b5ad6b70 100644 --- a/tests/SpeechRecognizerSilenceTests.ts +++ b/tests/SpeechRecognizerSilenceTests.ts @@ -28,11 +28,6 @@ const Canceled: string = "Canceled"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - - beforeAll(() => { // override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/SpeechRecognizerTests.ts b/tests/SpeechRecognizerTests.ts index bbf689cd..bc9d91a6 100644 --- a/tests/SpeechRecognizerTests.ts +++ b/tests/SpeechRecognizerTests.ts @@ -59,10 +59,6 @@ const Canceled: string = "Canceled"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/SpeechSynthesisTests.ts b/tests/SpeechSynthesisTests.ts index 41ad9bbf..6cfa68ce 100644 --- a/tests/SpeechSynthesisTests.ts +++ b/tests/SpeechSynthesisTests.ts @@ -22,10 +22,6 @@ import { let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/TranslationRecognizerBasicsTests.ts b/tests/TranslationRecognizerBasicsTests.ts index dfc5a6d9..08a31c47 100644 --- a/tests/TranslationRecognizerBasicsTests.ts +++ b/tests/TranslationRecognizerBasicsTests.ts @@ -26,10 +26,6 @@ import { AudioStreamFormatImpl } from "../src/sdk/Audio/AudioStreamFormat"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - beforeAll(() => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/TranslationRecognizerTests.ts b/tests/TranslationRecognizerTests.ts index cf0a5e5f..1933b7c0 100644 --- a/tests/TranslationRecognizerTests.ts +++ b/tests/TranslationRecognizerTests.ts @@ -19,11 +19,6 @@ import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - - beforeAll(() => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/TranslationSynthTests.ts b/tests/TranslationSynthTests.ts index c8eb35e2..374d40f5 100644 --- a/tests/TranslationSynthTests.ts +++ b/tests/TranslationSynthTests.ts @@ -20,11 +20,6 @@ import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); - - beforeAll(() => { // Override inputs, if necessary Settings.LoadSettings(); diff --git a/tests/VoiceProfileClientTests.ts b/tests/VoiceProfileClientTests.ts index 019442f6..f540c676 100644 --- a/tests/VoiceProfileClientTests.ts +++ b/tests/VoiceProfileClientTests.ts @@ -13,9 +13,6 @@ import { closeAsyncObjects } from "./Utilities"; import { WaveFileAudioInput } from "./WaveFileAudioInputStream"; let objsToClose: any[]; -jest.mock("../src/common.browser/AudioWorkerUrl", () => ({ - getAudioWorkerUrl: (): string => "speech-processor.js" -})); beforeAll((): void => { // Override inputs, if necessary From e1ab3cc096363ca6fa5b3c642bd2ccf1fcf347f7 Mon Sep 17 00:00:00 2001 From: glenn Date: Mon, 25 Sep 2023 08:59:14 -0400 Subject: [PATCH 3/3] handle v2 translation hypothesis messages --- .../ServiceMessages/TranslationHypothesis.ts | 15 ++++++-- .../ServiceMessages/TranslationPhrase.ts | 10 ++--- .../TranslationServiceRecognizer.ts | 37 ++++++++++++------- tests/AutoSourceLangDetectionTests.ts | 10 +++++ 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/common.speech/ServiceMessages/TranslationHypothesis.ts b/src/common.speech/ServiceMessages/TranslationHypothesis.ts index 0d3b92a6..34bf818f 100644 --- a/src/common.speech/ServiceMessages/TranslationHypothesis.ts +++ b/src/common.speech/ServiceMessages/TranslationHypothesis.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +import { Contracts } from "../../sdk/Contracts"; import { ITranslations } from "../Exports"; import { TranslationStatus } from "../TranslationStatus"; @@ -15,13 +16,21 @@ export interface ITranslationHypothesis { export class TranslationHypothesis implements ITranslationHypothesis { private privTranslationHypothesis: ITranslationHypothesis; - private constructor(json: string) { - this.privTranslationHypothesis = JSON.parse(json) as ITranslationHypothesis; + private constructor(hypothesis: ITranslationHypothesis) { + this.privTranslationHypothesis = hypothesis; this.privTranslationHypothesis.Translation.TranslationStatus = TranslationStatus[this.privTranslationHypothesis.Translation.TranslationStatus as unknown as keyof typeof TranslationStatus]; } public static fromJSON(json: string): TranslationHypothesis { - return new TranslationHypothesis(json); + return new TranslationHypothesis(JSON.parse(json) as ITranslationHypothesis); + } + + public static fromTranslationResponse(translationHypothesis: { SpeechHypothesis: ITranslationHypothesis }): TranslationHypothesis { + Contracts.throwIfNullOrUndefined(translationHypothesis, "translationHypothesis"); + const hypothesis: ITranslationHypothesis = translationHypothesis.SpeechHypothesis; + translationHypothesis.SpeechHypothesis = undefined; + hypothesis.Translation = (translationHypothesis as unknown as ITranslations); + return new TranslationHypothesis(hypothesis); } public get Duration(): number { diff --git a/src/common.speech/ServiceMessages/TranslationPhrase.ts b/src/common.speech/ServiceMessages/TranslationPhrase.ts index f9da0e57..c6ce1e43 100644 --- a/src/common.speech/ServiceMessages/TranslationPhrase.ts +++ b/src/common.speech/ServiceMessages/TranslationPhrase.ts @@ -11,7 +11,7 @@ export interface ITranslationPhrase { Offset: number; Duration: number; Translation?: ITranslations; - Text: string; + Text?: string; DisplayText?: string; PrimaryLanguage?: IPrimaryLanguage; } @@ -52,19 +52,19 @@ export class TranslationPhrase implements ITranslationPhrase { return this.privTranslationPhrase.Duration; } - public get Text(): string { + public get Text(): string | undefined { return this.privTranslationPhrase.Text; } - public get Language(): string { + public get Language(): string | undefined { return this.privTranslationPhrase.PrimaryLanguage?.Language; } - public get Confidence(): string { + public get Confidence(): string | undefined { return this.privTranslationPhrase.PrimaryLanguage?.Confidence; } - public get Translation(): ITranslations { + public get Translation(): ITranslations | undefined { return this.privTranslationPhrase.Translation; } } diff --git a/src/common.speech/TranslationServiceRecognizer.ts b/src/common.speech/TranslationServiceRecognizer.ts index 17876837..75e197a0 100644 --- a/src/common.speech/TranslationServiceRecognizer.ts +++ b/src/common.speech/TranslationServiceRecognizer.ts @@ -26,6 +26,7 @@ import { CancellationErrorCodePropertyName, ConversationServiceRecognizer, EnumTranslation, + ITranslationHypothesis, RecognitionStatus, SynthesisStatus, TranslationHypothesis, @@ -160,32 +161,40 @@ export class TranslationServiceRecognizer extends ConversationServiceRecognizer }; + const handleTranslationHypothesis = (hypothesis: TranslationHypothesis, resultProperties: PropertyCollection): void => { + const result: TranslationRecognitionEventArgs = this.fireEventForResult(hypothesis, resultProperties); + this.privRequestSession.onHypothesis(this.privRequestSession.currentTurnAudioOffset + result.offset); + + if (!!this.privTranslationRecognizer.recognizing) { + try { + this.privTranslationRecognizer.recognizing(this.privTranslationRecognizer, result); + /* eslint-disable no-empty */ + } catch (error) { + // Not going to let errors in the event handler + // trip things up. + } + } + 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); - /* eslint-disable no-empty */ - } catch (error) { - // Not going to let errors in the event handler - // trip things up. - } - } - processed = true; + handleTranslationHypothesis(TranslationHypothesis.fromJSON(connectionMessage.textBody), resultProps); break; case "translation.response": const phrase: { SpeechPhrase: ITranslationPhrase } = JSON.parse(connectionMessage.textBody) as { SpeechPhrase: ITranslationPhrase }; if (!!phrase.SpeechPhrase) { await handleTranslationPhrase(TranslationPhrase.fromTranslationResponse(phrase)); + } else { + const hypothesis: { SpeechHypothesis: ITranslationHypothesis } = JSON.parse(connectionMessage.textBody) as { SpeechHypothesis: ITranslationHypothesis }; + if (!!hypothesis.SpeechHypothesis) { + handleTranslationHypothesis(TranslationHypothesis.fromTranslationResponse(hypothesis), resultProps); + } } break; case "translation.phrase": diff --git a/tests/AutoSourceLangDetectionTests.ts b/tests/AutoSourceLangDetectionTests.ts index 8aba79d1..70d801dd 100644 --- a/tests/AutoSourceLangDetectionTests.ts +++ b/tests/AutoSourceLangDetectionTests.ts @@ -484,6 +484,16 @@ describe.each([true, false])("Service based tests", (forceNodeWebSocket: boolean } }; + r.recognizing = (o: sdk.Recognizer, e: sdk.TranslationRecognitionEventArgs) => { + expect(e.result).not.toBeUndefined(); + expect(e.result.text).toContain("what's the"); + expect(e.result.properties).not.toBeUndefined(); + expect(e.result.properties.getProperty(sdk.PropertyId.SpeechServiceResponse_JsonResult)).not.toBeUndefined(); + expect(e.result.translations).not.toBeUndefined(); + expect(e.result.translations.languages[0]).toEqual(defaultTargetLanguage); + expect(e.result.translations.get(defaultTargetLanguage)).toContain("Wie ist das"); + } + r.recognized = (o: sdk.Recognizer, e: sdk.TranslationRecognitionEventArgs) => { try { if (e.result.reason === sdk.ResultReason.TranslatedSpeech) {