{"version":3,"sources":["src/sdk/Synthesizer.ts"],"names":[],"mappings":"AAMA,OAAO,EAKH,eAAe,EACf,2BAA2B,EAE3B,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAqB,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAEnF,OAAO,EAAE,kBAAkB,EAAc,YAAY,EAAoB,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErH,8BAAsB,WAAW;IAC7B,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,SAAS,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC5C,SAAS,CAAC,eAAe,EAAE,oBAAoB,CAAC;IAChD,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAC7C,SAAS,CAAC,qBAAqB,EAAE,2BAA2B,CAAC;IAC7D,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC;IAChC,SAAS,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,qBAAqB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAEzD;;;;;;OAMG;IACH,IAAW,kBAAkB,IAAI,MAAM,CAEtC;IAED;;;;;;OAMG;IACH,IAAW,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAG1C;IAED;;;;;;OAMG;IACH,IAAW,UAAU,IAAI,kBAAkB,CAE1C;IAED;;;;;;OAMG;IACH,IAAW,wBAAwB,IAAI,OAAO,CAE7C;IAED;;;;OAIG;IACH,SAAS,aAAa,YAAY,EAAE,YAAY;IAWzC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAoJtC;;;;;;;;;OASG;cACa,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;cAc1C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB7C,SAAS,CAAC,QAAQ,CAAC,sBAAsB,CACrC,cAAc,EAAE,eAAe,EAC/B,iBAAiB,EAAE,2BAA2B,EAC9C,iBAAiB,EAAE,iBAAiB,GAAG,oBAAoB;IAG/D,SAAS,CAAC,QAAQ,CAAC,0BAA0B,CACzC,cAAc,EAAE,eAAe,EAC/B,iBAAiB,EAAE,iBAAiB,GAAG,oBAAoB;IAE/D,SAAS,CAAC,uBAAuB,CAAC,YAAY,EAAE,mBAAmB,GAAG,iBAAiB;IAOvF,SAAS,CAAC,yBAAyB,IAAI,IAAI;IA2D3C,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAOnD;AAED,qBAAa,gBAAgB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACvC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;gBAElB,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAAE,UAAU,CAAC,EAAE,iBAAiB;CAQ1K","file":"Synthesizer.d.ts","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n/* eslint-disable max-classes-per-file */\n\nimport { TokenCredential } from \"@azure/core-auth\";\nimport {\n    AutoDetectSourceLanguagesOpenRangeOptionName,\n    CognitiveSubscriptionKeyAuthentication,\n    CognitiveTokenAuthentication,\n    Context,\n    IAuthentication,\n    ISynthesisConnectionFactory,\n    OS,\n    SpeechServiceConfig,\n    SynthesisAdapterBase,\n    SynthesisRestAdapter,\n    SynthesizerConfig } from \"../common.speech/Exports.js\";\nimport { IAudioDestination, IStringDictionary, Queue } from \"../common/Exports.js\";\nimport { Contracts } from \"./Contracts.js\";\nimport { PropertyCollection, PropertyId, SpeechConfig, SpeechConfigImpl, SpeechSynthesisResult } from \"./Exports.js\";\n\nexport abstract class Synthesizer {\n    private tokenCredential?: TokenCredential;\n    protected privAdapter: SynthesisAdapterBase;\n    protected privRestAdapter: SynthesisRestAdapter;\n    protected privProperties: PropertyCollection;\n    protected privConnectionFactory: ISynthesisConnectionFactory;\n    protected privDisposed: boolean;\n    protected privSynthesizing: boolean;\n    protected synthesisRequestQueue: Queue<SynthesisRequest>;\n\n    /**\n     * Gets the authorization token used to communicate with the service.\n     * @member Synthesizer.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 Synthesizer.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 Synthesizer.\n     * @member Synthesizer.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 Synthesizer.prototype.autoDetectSourceLanguage\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    /**\n     * Creates and initializes an instance of a Recognizer\n     * @constructor\n     * @param {SpeechConfig} speechConfig - The speech config to initialize the synthesizer.\n     */\n    protected constructor(speechConfig: SpeechConfig) {\n        const speechConfigImpl: SpeechConfigImpl = speechConfig as SpeechConfigImpl;\n        Contracts.throwIfNull(speechConfigImpl, \"speechConfig\");\n\n        this.privProperties = speechConfigImpl.properties.clone();\n        this.privDisposed = false;\n        this.privSynthesizing = false;\n        this.synthesisRequestQueue = new Queue<SynthesisRequest>();\n        this.tokenCredential = speechConfig.tokenCredential;\n    }\n\n    public buildSsml(text: string): string {\n        const languageToDefaultVoice: IStringDictionary<string>  = {\n            [\"af-ZA\"]: \"af-ZA-AdriNeural\",\n            [\"am-ET\"]: \"am-ET-AmehaNeural\",\n            [\"ar-AE\"]: \"ar-AE-FatimaNeural\",\n            [\"ar-BH\"]: \"ar-BH-AliNeural\",\n            [\"ar-DZ\"]: \"ar-DZ-AminaNeural\",\n            [\"ar-EG\"]: \"ar-EG-SalmaNeural\",\n            [\"ar-IQ\"]: \"ar-IQ-BasselNeural\",\n            [\"ar-JO\"]: \"ar-JO-SanaNeural\",\n            [\"ar-KW\"]: \"ar-KW-FahedNeural\",\n            [\"ar-LY\"]: \"ar-LY-ImanNeural\",\n            [\"ar-MA\"]: \"ar-MA-JamalNeural\",\n            [\"ar-QA\"]: \"ar-QA-AmalNeural\",\n            [\"ar-SA\"]: \"ar-SA-HamedNeural\",\n            [\"ar-SY\"]: \"ar-SY-AmanyNeural\",\n            [\"ar-TN\"]: \"ar-TN-HediNeural\",\n            [\"ar-YE\"]: \"ar-YE-MaryamNeural\",\n            [\"bg-BG\"]: \"bg-BG-BorislavNeural\",\n            [\"bn-BD\"]: \"bn-BD-NabanitaNeural\",\n            [\"bn-IN\"]: \"bn-IN-BashkarNeural\",\n            [\"ca-ES\"]: \"ca-ES-JoanaNeural\",\n            [\"cs-CZ\"]: \"cs-CZ-AntoninNeural\",\n            [\"cy-GB\"]: \"cy-GB-AledNeural\",\n            [\"da-DK\"]: \"da-DK-ChristelNeural\",\n            [\"de-AT\"]: \"de-AT-IngridNeural\",\n            [\"de-CH\"]: \"de-CH-JanNeural\",\n            [\"de-DE\"]: \"de-DE-KatjaNeural\",\n            [\"el-GR\"]: \"el-GR-AthinaNeural\",\n            [\"en-AU\"]: \"en-AU-NatashaNeural\",\n            [\"en-CA\"]: \"en-CA-ClaraNeural\",\n            [\"en-GB\"]: \"en-GB-LibbyNeural\",\n            [\"en-HK\"]: \"en-HK-SamNeural\",\n            [\"en-IE\"]: \"en-IE-ConnorNeural\",\n            [\"en-IN\"]: \"en-IN-NeerjaNeural\",\n            [\"en-KE\"]: \"en-KE-AsiliaNeural\",\n            [\"en-NG\"]: \"en-NG-AbeoNeural\",\n            [\"en-NZ\"]: \"en-NZ-MitchellNeural\",\n            [\"en-PH\"]: \"en-PH-JamesNeural\",\n            [\"en-SG\"]: \"en-SG-LunaNeural\",\n            [\"en-TZ\"]: \"en-TZ-ElimuNeural\",\n            [\"en-US\"]: \"en-US-AvaMultilingualNeural\",\n            [\"en-ZA\"]: \"en-ZA-LeahNeural\",\n            [\"es-AR\"]: \"es-AR-ElenaNeural\",\n            [\"es-BO\"]: \"es-BO-MarceloNeural\",\n            [\"es-CL\"]: \"es-CL-CatalinaNeural\",\n            [\"es-CO\"]: \"es-CO-GonzaloNeural\",\n            [\"es-CR\"]: \"es-CR-JuanNeural\",\n            [\"es-CU\"]: \"es-CU-BelkysNeural\",\n            [\"es-DO\"]: \"es-DO-EmilioNeural\",\n            [\"es-EC\"]: \"es-EC-AndreaNeural\",\n            [\"es-ES\"]: \"es-ES-AlvaroNeural\",\n            [\"es-GQ\"]: \"es-GQ-JavierNeural\",\n            [\"es-GT\"]: \"es-GT-AndresNeural\",\n            [\"es-HN\"]: \"es-HN-CarlosNeural\",\n            [\"es-MX\"]: \"es-MX-DaliaNeural\",\n            [\"es-NI\"]: \"es-NI-FedericoNeural\",\n            [\"es-PA\"]: \"es-PA-MargaritaNeural\",\n            [\"es-PE\"]: \"es-PE-AlexNeural\",\n            [\"es-PR\"]: \"es-PR-KarinaNeural\",\n            [\"es-PY\"]: \"es-PY-MarioNeural\",\n            [\"es-SV\"]: \"es-SV-LorenaNeural\",\n            [\"es-US\"]: \"es-US-AlonsoNeural\",\n            [\"es-UY\"]: \"es-UY-MateoNeural\",\n            [\"es-VE\"]: \"es-VE-PaolaNeural\",\n            [\"et-EE\"]: \"et-EE-AnuNeural\",\n            [\"fa-IR\"]: \"fa-IR-DilaraNeural\",\n            [\"fi-FI\"]: \"fi-FI-SelmaNeural\",\n            [\"fil-PH\"]: \"fil-PH-AngeloNeural\",\n            [\"fr-BE\"]: \"fr-BE-CharlineNeural\",\n            [\"fr-CA\"]: \"fr-CA-SylvieNeural\",\n            [\"fr-CH\"]: \"fr-CH-ArianeNeural\",\n            [\"fr-FR\"]: \"fr-FR-DeniseNeural\",\n            [\"ga-IE\"]: \"ga-IE-ColmNeural\",\n            [\"gl-ES\"]: \"gl-ES-RoiNeural\",\n            [\"gu-IN\"]: \"gu-IN-DhwaniNeural\",\n            [\"he-IL\"]: \"he-IL-AvriNeural\",\n            [\"hi-IN\"]: \"hi-IN-MadhurNeural\",\n            [\"hr-HR\"]: \"hr-HR-GabrijelaNeural\",\n            [\"hu-HU\"]: \"hu-HU-NoemiNeural\",\n            [\"id-ID\"]: \"id-ID-ArdiNeural\",\n            [\"is-IS\"]: \"is-IS-GudrunNeural\",\n            [\"it-IT\"]: \"it-IT-IsabellaNeural\",\n            [\"ja-JP\"]: \"ja-JP-NanamiNeural\",\n            [\"jv-ID\"]: \"jv-ID-DimasNeural\",\n            [\"kk-KZ\"]: \"kk-KZ-AigulNeural\",\n            [\"km-KH\"]: \"km-KH-PisethNeural\",\n            [\"kn-IN\"]: \"kn-IN-GaganNeural\",\n            [\"ko-KR\"]: \"ko-KR-SunHiNeural\",\n            [\"lo-LA\"]: \"lo-LA-ChanthavongNeural\",\n            [\"lt-LT\"]: \"lt-LT-LeonasNeural\",\n            [\"lv-LV\"]: \"lv-LV-EveritaNeural\",\n            [\"mk-MK\"]: \"mk-MK-AleksandarNeural\",\n            [\"ml-IN\"]: \"ml-IN-MidhunNeural\",\n            [\"mr-IN\"]: \"mr-IN-AarohiNeural\",\n            [\"ms-MY\"]: \"ms-MY-OsmanNeural\",\n            [\"mt-MT\"]: \"mt-MT-GraceNeural\",\n            [\"my-MM\"]: \"my-MM-NilarNeural\",\n            [\"nb-NO\"]: \"nb-NO-PernilleNeural\",\n            [\"nl-BE\"]: \"nl-BE-ArnaudNeural\",\n            [\"nl-NL\"]: \"nl-NL-ColetteNeural\",\n            [\"pl-PL\"]: \"pl-PL-AgnieszkaNeural\",\n            [\"ps-AF\"]: \"ps-AF-GulNawazNeural\",\n            [\"pt-BR\"]: \"pt-BR-FranciscaNeural\",\n            [\"pt-PT\"]: \"pt-PT-DuarteNeural\",\n            [\"ro-RO\"]: \"ro-RO-AlinaNeural\",\n            [\"ru-RU\"]: \"ru-RU-SvetlanaNeural\",\n            [\"si-LK\"]: \"si-LK-SameeraNeural\",\n            [\"sk-SK\"]: \"sk-SK-LukasNeural\",\n            [\"sl-SI\"]: \"sl-SI-PetraNeural\",\n            [\"so-SO\"]: \"so-SO-MuuseNeural\",\n            [\"sr-RS\"]: \"sr-RS-NicholasNeural\",\n            [\"su-ID\"]: \"su-ID-JajangNeural\",\n            [\"sv-SE\"]: \"sv-SE-SofieNeural\",\n            [\"sw-KE\"]: \"sw-KE-RafikiNeural\",\n            [\"sw-TZ\"]: \"sw-TZ-DaudiNeural\",\n            [\"ta-IN\"]: \"ta-IN-PallaviNeural\",\n            [\"ta-LK\"]: \"ta-LK-KumarNeural\",\n            [\"ta-SG\"]: \"ta-SG-AnbuNeural\",\n            [\"te-IN\"]: \"te-IN-MohanNeural\",\n            [\"th-TH\"]: \"th-TH-PremwadeeNeural\",\n            [\"tr-TR\"]: \"tr-TR-AhmetNeural\",\n            [\"uk-UA\"]: \"uk-UA-OstapNeural\",\n            [\"ur-IN\"]: \"ur-IN-GulNeural\",\n            [\"ur-PK\"]: \"ur-PK-AsadNeural\",\n            [\"uz-UZ\"]: \"uz-UZ-MadinaNeural\",\n            [\"vi-VN\"]: \"vi-VN-HoaiMyNeural\",\n            [\"zh-CN\"]: \"zh-CN-XiaoxiaoNeural\",\n            [\"zh-HK\"]: \"zh-HK-HiuMaanNeural\",\n            [\"zh-TW\"]: \"zh-TW-HsiaoChenNeural\",\n            [\"zu-ZA\"]: \"zu-ZA-ThandoNeural\",\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 = Synthesizer.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     * 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 Synthesizer.prototype.dispose\n     * @function\n     * @public\n     * @param {boolean} disposing - Flag to request disposal.\n     */\n    protected async dispose(disposing: boolean): Promise<void> {\n        if (this.privDisposed) {\n            return;\n        }\n\n        if (disposing) {\n            if (this.privAdapter) {\n                await this.privAdapter.dispose();\n            }\n        }\n\n        this.privDisposed = true;\n    }\n\n    protected async adapterSpeak(): Promise<void> {\n        if (!this.privDisposed && !this.privSynthesizing) {\n            this.privSynthesizing = true;\n            const request: SynthesisRequest = await this.synthesisRequestQueue.dequeue();\n            return this.privAdapter.Speak(request.text, request.isSSML, request.requestId, request.cb, request.err, request.dataStream);\n        }\n    }\n\n    //\n    // ################################################################################################################\n    // IMPLEMENTATION.\n    // Move to independent class\n    // ################################################################################################################\n    //\n\n    // Creates the synthesis adapter\n    protected abstract createSynthesisAdapter(\n        authentication: IAuthentication,\n        connectionFactory: ISynthesisConnectionFactory,\n        synthesizerConfig: SynthesizerConfig): SynthesisAdapterBase;\n\n    // Creates the REST synthesis adapter\n    protected abstract createRestSynthesisAdapter(\n        authentication: IAuthentication,\n        synthesizerConfig: SynthesizerConfig): SynthesisRestAdapter;\n\n    protected createSynthesizerConfig(speechConfig: SpeechServiceConfig): SynthesizerConfig {\n        return new SynthesizerConfig(\n            speechConfig,\n            this.privProperties);\n    }\n\n    // Does the generic synthesizer setup that is common across all synthesizer types.\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: 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        : (this.tokenCredential)\n            ? new CognitiveTokenAuthentication(\n                async (): Promise<string> => {\n                    try {\n                        const tokenResponse = await this.tokenCredential.getToken(\"https://cognitiveservices.azure.com/.default\");\n                        return tokenResponse?.token ?? \"\";\n                    } catch (err) {\n                        throw err;\n                    }\n                },\n                async (): Promise<string> => {\n                    try {\n                        const tokenResponse = await this.tokenCredential.getToken(\"https://cognitiveservices.azure.com/.default\");\n                        return tokenResponse?.token ?? \"\";\n                    } catch (err) {\n                        throw err;\n                    }\n                }\n            )\n            : new CognitiveTokenAuthentication(\n                (): Promise<string> => {\n                    const authorizationToken = this.privProperties.getProperty(PropertyId.SpeechServiceAuthorization_Token, undefined);\n                    return Promise.resolve(authorizationToken);\n                },\n                (): Promise<string> => {\n                    const authorizationToken = this.privProperties.getProperty(PropertyId.SpeechServiceAuthorization_Token, undefined);\n                    return Promise.resolve(authorizationToken);\n                }\n            );\n\n        this.privAdapter = this.createSynthesisAdapter(\n            authentication,\n            this.privConnectionFactory,\n            synthesizerConfig);\n\n        this.privRestAdapter = this.createRestSynthesisAdapter(\n            authentication,\n            synthesizerConfig);\n    }\n\n    protected 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\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    public 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"]}