{"version":3,"sources":["src/sdk/SpeechSynthesizer.ts"],"names":[],"mappings":"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","file":"SpeechSynthesizer.d.ts","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport {PathLike} from \"fs\";\nimport {\n    AutoDetectSourceLanguagesOpenRangeOptionName,\n    CognitiveSubscriptionKeyAuthentication,\n    CognitiveTokenAuthentication,\n    Context,\n    IAuthentication,\n    ISynthesisConnectionFactory,\n    OS,\n    SpeechServiceConfig,\n    SpeechSynthesisConnectionFactory,\n    SynthesisAdapterBase,\n    SynthesizerConfig,\n} from \"../common.speech/Exports\";\nimport {\n    createNoDashGuid,\n    IAudioDestination,\n    IStringDictionary,\n    Promise,\n    PromiseHelper,\n    Queue\n} from \"../common/Exports\";\nimport { AudioOutputConfigImpl } from \"./Audio/AudioConfig\";\nimport { AudioFileWriter } from \"./Audio/AudioFileWriter\";\nimport { AudioOutputFormatImpl } from \"./Audio/AudioOutputFormat\";\nimport {\n    PullAudioOutputStreamImpl,\n    PushAudioOutputStreamImpl\n} from \"./Audio/AudioOutputStream\";\nimport { Contracts } from \"./Contracts\";\nimport {\n    AudioConfig,\n    AudioOutputStream,\n    AutoDetectSourceLanguageConfig,\n    PropertyCollection,\n    PropertyId,\n    PullAudioOutputStream,\n    PushAudioOutputStreamCallback,\n    SpeechConfig,\n    SpeechSynthesisEventArgs,\n    SpeechSynthesisOutputFormat,\n    SpeechSynthesisResult,\n    SpeechSynthesisWordBoundaryEventArgs,\n} from \"./Exports\";\nimport { SpeechConfigImpl } from \"./SpeechConfig\";\n\n/**\n * Defines the class SpeechSynthesizer for text to speech.\n * Added in version 1.11.0\n * @class SpeechSynthesizer\n */\nexport class SpeechSynthesizer {\n    protected audioConfig: AudioConfig;\n    protected privAdapter: SynthesisAdapterBase;\n    protected privProperties: PropertyCollection;\n    protected synthesisRequestQueue: Queue<SynthesisRequest>;\n\n    /**\n     * Defines event handler for synthesis start events.\n     * @member SpeechSynthesizer.prototype.synthesisStarted\n     * @function\n     * @public\n     */\n    public synthesisStarted: (sender: SpeechSynthesizer, event: SpeechSynthesisEventArgs) => void;\n\n    /**\n     * Defines event handler for synthesizing events.\n     * @member SpeechSynthesizer.prototype.synthesizing\n     * @function\n     * @public\n     */\n    public synthesizing: (sender: SpeechSynthesizer, event: SpeechSynthesisEventArgs) => void;\n\n    /**\n     * Defines event handler for synthesis completed events.\n     * @member SpeechSynthesizer.prototype.synthesisCompleted\n     * @function\n     * @public\n     */\n    public synthesisCompleted: (sender: SpeechSynthesizer, event: SpeechSynthesisEventArgs) => void;\n\n    /**\n     * Defines event handler for synthesis cancelled events.\n     * @member SpeechSynthesizer.prototype.SynthesisCanceled\n     * @function\n     * @public\n     */\n    public SynthesisCanceled: (sender: SpeechSynthesizer, event: SpeechSynthesisEventArgs) => void;\n\n    /**\n     * Defines event handler for word boundary events\n     * @member SpeechSynthesizer.prototype.wordBoundary\n     * @function\n     * @public\n     */\n    public wordBoundary: (sender: SpeechSynthesizer, event: SpeechSynthesisWordBoundaryEventArgs) => void;\n\n    /**\n     * Gets the authorization token used to communicate with the service.\n     * @member SpeechSynthesizer.prototype.authorizationToken\n     * @function\n     * @public\n     * @returns {string} Authorization token.\n     */\n    public get authorizationToken(): string {\n        return this.properties.getProperty(PropertyId.SpeechServiceAuthorization_Token);\n    }\n\n    /**\n     * Gets/Sets the authorization token used to communicate with the service.\n     * @member SpeechSynthesizer.prototype.authorizationToken\n     * @function\n     * @public\n     * @param {string} token - Authorization token.\n     */\n    public set authorizationToken(token: string) {\n        Contracts.throwIfNullOrWhitespace(token, \"token\");\n        this.properties.setProperty(PropertyId.SpeechServiceAuthorization_Token, token);\n    }\n\n    /**\n     * The collection of properties and their values defined for this SpeechSynthesizer.\n     * @member SpeechSynthesizer.prototype.properties\n     * @function\n     * @public\n     * @returns {PropertyCollection} The collection of properties and their values defined for this SpeechSynthesizer.\n     */\n    public get properties(): PropertyCollection {\n        return this.privProperties;\n    }\n\n    /**\n     * Indicates if auto detect source language is enabled\n     * @member SpeechSynthesizer.prototype.properties\n     * @function\n     * @public\n     * @returns {boolean} if auto detect source language is enabled\n     */\n    public get autoDetectSourceLanguage(): boolean {\n        return this.properties.getProperty(PropertyId.SpeechServiceConnection_AutoDetectSourceLanguages) === AutoDetectSourceLanguagesOpenRangeOptionName;\n    }\n\n    private privDisposed: boolean;\n    private privConnectionFactory: ISynthesisConnectionFactory;\n    private privSynthesizing: boolean;\n\n    /**\n     * SpeechSynthesizer constructor.\n     * @constructor\n     * @param {SpeechConfig} speechConfig - An set of initial properties for this synthesizer\n     * @param {AudioConfig} audioConfig - An optional audio configuration associated with the synthesizer\n     */\n    public constructor(speechConfig: SpeechConfig, audioConfig?: AudioConfig) {\n        const speechConfigImpl: SpeechConfigImpl = speechConfig as SpeechConfigImpl;\n        Contracts.throwIfNull(speechConfigImpl, \"speechConfig\");\n\n        if (audioConfig !== null) {\n            this.audioConfig = (audioConfig !== undefined) ? audioConfig : AudioConfig.fromDefaultSpeakerOutput();\n        }\n        this.privProperties = speechConfigImpl.properties.clone();\n        this.privDisposed = false;\n        this.privSynthesizing = false;\n        this.privConnectionFactory = new SpeechSynthesisConnectionFactory();\n        this.synthesisRequestQueue = new Queue<SynthesisRequest>();\n        this.implCommonSynthesizeSetup();\n    }\n\n    /**\n     * SpeechSynthesizer constructor.\n     * @constructor\n     * @param {SpeechConfig} speechConfig - an set of initial properties for this synthesizer\n     * @param {AutoDetectSourceLanguageConfig} autoDetectSourceLanguageConfig - An source language detection configuration associated with the synthesizer\n     * @param {AudioConfig} audioConfig - An optional audio configuration associated with the synthesizer\n     */\n    public static FromConfig(speechConfig: SpeechConfig, autoDetectSourceLanguageConfig: AutoDetectSourceLanguageConfig, audioConfig?: AudioConfig): SpeechSynthesizer {\n        const speechConfigImpl: SpeechConfigImpl = speechConfig as SpeechConfigImpl;\n        autoDetectSourceLanguageConfig.properties.mergeTo(speechConfigImpl.properties);\n        return new SpeechSynthesizer(speechConfig, audioConfig);\n    }\n\n    public buildSsml(text: string): string {\n        const languageToDefaultVoice: IStringDictionary<string>  = {\n            [\"ar-EG\"]: \"Microsoft Server Speech Text to Speech Voice (ar-EG, Hoda)\",\n            [\"ar-SA\"]: \"Microsoft Server Speech Text to Speech Voice (ar-SA, Naayf)\",\n            [\"bg-BG\"]: \"Microsoft Server Speech Text to Speech Voice (bg-BG, Ivan)\",\n            [\"ca-ES\"]: \"Microsoft Server Speech Text to Speech Voice (ca-ES, HerenaRUS)\",\n            [\"cs-CZ\"]: \"Microsoft Server Speech Text to Speech Voice (cs-CZ, Jakub)\",\n            [\"da-DK\"]: \"Microsoft Server Speech Text to Speech Voice (da-DK, HelleRUS)\",\n            [\"de-AT\"]: \"Microsoft Server Speech Text to Speech Voice (de-AT, Michael)\",\n            [\"de-CH\"]: \"Microsoft Server Speech Text to Speech Voice (de-CH, Karsten)\",\n            [\"de-DE\"]: \"Microsoft Server Speech Text to Speech Voice (de-DE, HeddaRUS)\",\n            [\"el-GR\"]: \"Microsoft Server Speech Text to Speech Voice (el-GR, Stefanos)\",\n            [\"en-AU\"]: \"Microsoft Server Speech Text to Speech Voice (en-AU, HayleyRUS)\",\n            [\"en-CA\"]: \"Microsoft Server Speech Text to Speech Voice (en-CA, HeatherRUS)\",\n            [\"en-GB\"]: \"Microsoft Server Speech Text to Speech Voice (en-GB, HazelRUS)\",\n            [\"en-IE\"]: \"Microsoft Server Speech Text to Speech Voice (en-IE, Sean)\",\n            [\"en-IN\"]: \"Microsoft Server Speech Text to Speech Voice (en-IN, PriyaRUS)\",\n            [\"en-US\"]: \"Microsoft Server Speech Text to Speech Voice (en-US, AriaRUS)\",\n            [\"es-ES\"]: \"Microsoft Server Speech Text to Speech Voice (es-ES, HelenaRUS)\",\n            [\"es-MX\"]: \"Microsoft Server Speech Text to Speech Voice (es-MX, HildaRUS)\",\n            [\"fi-FI\"]: \"Microsoft Server Speech Text to Speech Voice (fi-FI, HeidiRUS)\",\n            [\"fr-CA\"]: \"Microsoft Server Speech Text to Speech Voice (fr-CA, HarmonieRUS)\",\n            [\"fr-CH\"]: \"Microsoft Server Speech Text to Speech Voice (fr-CH, Guillaume)\",\n            [\"fr-FR\"]: \"Microsoft Server Speech Text to Speech Voice (fr-FR, HortenseRUS)\",\n            [\"he-IL\"]: \"Microsoft Server Speech Text to Speech Voice (he-IL, Asaf)\",\n            [\"hi-IN\"]: \"Microsoft Server Speech Text to Speech Voice (hi-IN, Kalpana)\",\n            [\"hr-HR\"]: \"Microsoft Server Speech Text to Speech Voice (hr-HR, Matej)\",\n            [\"hu-HU\"]: \"Microsoft Server Speech Text to Speech Voice (hu-HU, Szabolcs)\",\n            [\"id-ID\"]: \"Microsoft Server Speech Text to Speech Voice (id-ID, Andika)\",\n            [\"it-IT\"]: \"Microsoft Server Speech Text to Speech Voice (it-IT, LuciaRUS)\",\n            [\"ja-JP\"]: \"Microsoft Server Speech Text to Speech Voice (ja-JP, HarukaRUS)\",\n            [\"ko-KR\"]: \"Microsoft Server Speech Text to Speech Voice (ko-KR, HeamiRUS)\",\n            [\"ms-MY\"]: \"Microsoft Server Speech Text to Speech Voice (ms-MY, Rizwan)\",\n            [\"nb-NO\"]: \"Microsoft Server Speech Text to Speech Voice (nb-NO, HuldaRUS)\",\n            [\"nl-NL\"]: \"Microsoft Server Speech Text to Speech Voice (nl-NL, HannaRUS)\",\n            [\"pl-PL\"]: \"Microsoft Server Speech Text to Speech Voice (pl-PL, PaulinaRUS)\",\n            [\"pt-BR\"]: \"Microsoft Server Speech Text to Speech Voice (pt-BR, HeloisaRUS)\",\n            [\"pt-PT\"]: \"Microsoft Server Speech Text to Speech Voice (pt-PT, HeliaRUS)\",\n            [\"ro-RO\"]: \"Microsoft Server Speech Text to Speech Voice (ro-RO, Andrei)\",\n            [\"ru-RU\"]: \"Microsoft Server Speech Text to Speech Voice (ru-RU, EkaterinaRUS)\",\n            [\"sk-SK\"]: \"Microsoft Server Speech Text to Speech Voice (sk-SK, Filip)\",\n            [\"sl-SI\"]: \"Microsoft Server Speech Text to Speech Voice (sl-SI, Lado)\",\n            [\"sv-SE\"]: \"Microsoft Server Speech Text to Speech Voice (sv-SE, HedvigRUS)\",\n            [\"ta-IN\"]: \"Microsoft Server Speech Text to Speech Voice (ta-IN, Valluvar)\",\n            [\"te-IN\"]: \"Microsoft Server Speech Text to Speech Voice (te-IN, Chitra)\",\n            [\"th-TH\"]: \"Microsoft Server Speech Text to Speech Voice (th-TH, Pattara)\",\n            [\"tr-TR\"]: \"Microsoft Server Speech Text to Speech Voice (tr-TR, SedaRUS)\",\n            [\"vi-VN\"]: \"Microsoft Server Speech Text to Speech Voice (vi-VN, An)\",\n            [\"zh-CN\"]: \"Microsoft Server Speech Text to Speech Voice (zh-CN, HuihuiRUS)\",\n            [\"zh-HK\"]: \"Microsoft Server Speech Text to Speech Voice (zh-HK, TracyRUS)\",\n            [\"zh-TW\"]: \"Microsoft Server Speech Text to Speech Voice (zh-TW, HanHanRUS)\",\n        };\n\n        let language = this.properties.getProperty(PropertyId.SpeechServiceConnection_SynthLanguage, \"en-US\");\n        let voice = this.properties.getProperty(PropertyId.SpeechServiceConnection_SynthVoice, \"\");\n        let ssml: string = SpeechSynthesizer.XMLEncode(text);\n        if (this.autoDetectSourceLanguage) {\n            language = \"en-US\";\n        } else {\n            voice = voice || languageToDefaultVoice[language];\n        }\n        if (voice) {\n            ssml = `<voice name='${voice}'>${ssml}</voice>`;\n        }\n        ssml = `<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts' xmlns:emo='http://www.w3.org/2009/10/emotionml' xml:lang='${language}'>${ssml}</speak>`;\n        return ssml;\n    }\n\n    /**\n     * Executes speech synthesis on plain text.\n     * The task returns the synthesis result.\n     * @member SpeechSynthesizer.prototype.speakTextAsync\n     * @function\n     * @public\n     * @param text - Text to be synthesized.\n     * @param cb - Callback that received the SpeechSynthesisResult.\n     * @param err - Callback invoked in case of an error.\n     * @param stream - AudioOutputStream to receive the synthesized audio.\n     */\n    public speakTextAsync(text: string, cb?: (e: SpeechSynthesisResult) => void, err?: (e: string) => void, stream?: AudioOutputStream | PushAudioOutputStreamCallback | PathLike): void {\n        this.speakImpl(text, false, cb, err, stream);\n    }\n\n    /**\n     * Executes speech synthesis on SSML.\n     * The task returns the synthesis result.\n     * @member SpeechSynthesizer.prototype.speakSsmlAsync\n     * @function\n     * @public\n     * @param ssml - SSML to be synthesized.\n     * @param cb - Callback that received the SpeechSynthesisResult.\n     * @param err - Callback invoked in case of an error.\n     * @param stream - AudioOutputStream to receive the synthesized audio.\n     */\n    public speakSsmlAsync(ssml: string, cb?: (e: SpeechSynthesisResult) => void, err?: (e: string) => void, stream?: AudioOutputStream | PushAudioOutputStreamCallback | PathLike): void {\n        this.speakImpl(ssml, true, cb, err, stream);\n    }\n\n    /**\n     * Dispose of associated resources.\n     * @member SpeechSynthesizer.prototype.close\n     * @function\n     * @public\n     */\n    public close(): void {\n        Contracts.throwIfDisposed(this.privDisposed);\n\n        this.dispose(true);\n    }\n\n    /**\n     * @Internal\n     * Do not use externally, object returned will change without warning or notice.\n     */\n    public get internalData(): object {\n        return this.privAdapter;\n    }\n\n    /**\n     * This method performs cleanup of resources.\n     * The Boolean parameter disposing indicates whether the method is called\n     * from Dispose (if disposing is true) or from the finalizer (if disposing is false).\n     * Derived classes should override this method to dispose resource if needed.\n     * @member SpeechSynthesizer.prototype.dispose\n     * @function\n     * @public\n     * @param {boolean} disposing - Flag to request disposal.\n     */\n    protected dispose(disposing: boolean): void {\n        if (this.privDisposed) {\n            return;\n        }\n\n        if (disposing) {\n            if (this.privAdapter) {\n                this.privAdapter.dispose();\n            }\n        }\n\n        this.privDisposed = true;\n    }\n\n    //\n    // ################################################################################################################\n    // IMPLEMENTATION.\n    // Move to independent class\n    // ################################################################################################################\n    //\n    protected createSynthesizerConfig(speechConfig: SpeechServiceConfig): SynthesizerConfig {\n        return new SynthesizerConfig(\n            speechConfig,\n            this.privProperties);\n    }\n\n    // Creates the synthesis adapter\n    protected createSynthesisAdapter(\n        authentication: IAuthentication,\n        connectionFactory: ISynthesisConnectionFactory,\n        audioConfig: AudioConfig,\n        synthesizerConfig: SynthesizerConfig): SynthesisAdapterBase {\n            return new SynthesisAdapterBase(authentication, connectionFactory,\n                synthesizerConfig, this, this.audioConfig as AudioOutputConfigImpl);\n        }\n\n    protected implCommonSynthesizeSetup(): void {\n\n        let osPlatform = (typeof window !== \"undefined\") ? \"Browser\" : \"Node\";\n        let osName = \"unknown\";\n        let osVersion = \"unknown\";\n\n        if (typeof navigator !== \"undefined\") {\n            osPlatform = osPlatform + \"/\" + navigator.platform;\n            osName = navigator.userAgent;\n            osVersion = navigator.appVersion;\n        }\n\n        const synthesizerConfig = this.createSynthesizerConfig(\n            new SpeechServiceConfig(\n                new Context(new OS(osPlatform, osName, osVersion))));\n\n        const subscriptionKey = this.privProperties.getProperty(PropertyId.SpeechServiceConnection_Key, undefined);\n        const authentication = (subscriptionKey && subscriptionKey !== \"\") ?\n            new CognitiveSubscriptionKeyAuthentication(subscriptionKey) :\n            new CognitiveTokenAuthentication(\n                (authFetchEventId: string): Promise<string> => {\n                    const authorizationToken = this.privProperties.getProperty(PropertyId.SpeechServiceAuthorization_Token, undefined);\n                    return PromiseHelper.fromResult(authorizationToken);\n                },\n                (authFetchEventId: string): Promise<string> => {\n                    const authorizationToken = this.privProperties.getProperty(PropertyId.SpeechServiceAuthorization_Token, undefined);\n                    return PromiseHelper.fromResult(authorizationToken);\n                });\n\n        this.privAdapter = this.createSynthesisAdapter(\n            authentication,\n            this.privConnectionFactory,\n            this.audioConfig,\n            synthesizerConfig);\n\n        this.privAdapter.audioOutputFormat = AudioOutputFormatImpl.fromSpeechSynthesisOutputFormat(\n            (SpeechSynthesisOutputFormat as any)[this.properties.getProperty(PropertyId.SpeechServiceConnection_SynthOutputFormat, undefined)]\n        );\n    }\n\n    protected speakImpl(text: string, IsSsml: boolean, cb?: (e: SpeechSynthesisResult) => void, err?: (e: string) => void, dataStream?: AudioOutputStream | PushAudioOutputStreamCallback | PathLike): void {\n        try {\n            Contracts.throwIfDisposed(this.privDisposed);\n            const requestId = createNoDashGuid();\n            let audioDestination;\n            if (dataStream instanceof PushAudioOutputStreamCallback) {\n                audioDestination = new PushAudioOutputStreamImpl(dataStream);\n            } else if (dataStream instanceof PullAudioOutputStream) {\n                audioDestination = dataStream as PullAudioOutputStreamImpl;\n            } else if (dataStream !== undefined) {\n                audioDestination = new AudioFileWriter(dataStream as PathLike);\n            } else {\n                audioDestination = undefined;\n            }\n            this.synthesisRequestQueue.enqueue(new SynthesisRequest(requestId, text, IsSsml, (e: SpeechSynthesisResult): void => {\n                this.privSynthesizing = false;\n                if (!!cb) {\n                    try {\n                        cb(e);\n                    } catch (e) {\n                        if (!!err) {\n                            err(e);\n                        }\n                    }\n                }\n                cb = undefined;\n                this.adapterSpeak();\n            }, (e: string): void => {\n                if (!!err) {\n                    err(e);\n                }\n            }, audioDestination));\n\n            this.adapterSpeak();\n\n        } catch (error) {\n            if (!!err) {\n                if (error instanceof Error) {\n                    const typedError: Error = error as Error;\n                    err(typedError.name + \": \" + typedError.message);\n                } else {\n                    err(error);\n                }\n            }\n\n            // Destroy the synthesizer.\n            this.dispose(true);\n        }\n    }\n\n    protected adapterSpeak(): Promise<boolean> {\n        if (!this.privDisposed && !this.privSynthesizing) {\n            this.privSynthesizing = true;\n            return this.synthesisRequestQueue.dequeue().\n                onSuccessContinueWithPromise((request: SynthesisRequest): Promise<boolean> => {\n                    return this.privAdapter.Speak(request.text, request.isSSML, request.requestId, request.cb, request.err, request.dataStream);\n            });\n        }\n        return PromiseHelper.fromResult(true);\n    }\n\n    private static XMLEncode(text: string): string {\n        return text.replace(/&/g, \"&amp;\")\n            .replace(/</g, \"&lt;\")\n            .replace(/>/g, \"&gt;\")\n            .replace(/\"/g, \"&quot;\")\n            .replace(/'/g, \"&apos;\");\n    }\n}\n\n// tslint:disable-next-line:max-classes-per-file\nexport class SynthesisRequest {\n    public requestId: string;\n    public text: string;\n    public isSSML: boolean;\n    public cb: (e: SpeechSynthesisResult) => void;\n    public err: (e: string) => void;\n    public dataStream: IAudioDestination;\n\n    constructor(requestId: string, text: string, isSSML: boolean, cb?: (e: SpeechSynthesisResult) => void, err?: (e: string) => void, dataStream?: IAudioDestination) {\n        this.requestId = requestId;\n        this.text = text;\n        this.isSSML = isSSML;\n        this.cb = cb;\n        this.err = err;\n        this.dataStream = dataStream;\n    }\n}\n"]}