diff --git a/commands/interaction/tts/microsoft.js b/commands/interaction/tts/microsoft.js new file mode 100644 index 0000000..b9bfc45 --- /dev/null +++ b/commands/interaction/tts/microsoft.js @@ -0,0 +1,42 @@ +const { Constants } = require('detritus-client'); +const { InteractionCallbackTypes, ApplicationCommandOptionTypes } = Constants; + +const { sapi4 } = require('../../../labscore/api'); +const { MICROSOFT_VOICES, MICROSOFT_VOICE_CONFIG } = require('../../../labscore/constants'); + +const { createEmbed } = require('../../../labscore/utils/embed'); +const { icon, highlight } = require('../../../labscore/utils/markdown'); + +module.exports = { + description: 'Microsoft Sam Text to Speech', + name: 'mstts', + options: [ + { + name: 'voice', + description: 'TTS Voice to use', + choices: MICROSOFT_VOICES, + required: true, + }, + { + name: 'text', + description: 'Text', + type: ApplicationCommandOptionTypes.STRING, + required: true, + maxLength: 256 + } + ], + run: async (context, args) => { + try{ + await context.respond({data: {}, type: InteractionCallbackTypes.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE}) + let audio = await sapi4(context, args.text, args.voice, MICROSOFT_VOICE_CONFIG[args.voice].pitch, MICROSOFT_VOICE_CONFIG[args.voice].speed) + await context.editOrRespond({ + embeds: [createEmbed("defaultNoFooter", context, { description: `${icon("audio")} Audio Generated in ${highlight(audio.timings + "s")}.` })], + file: { value: audio.response.body, filename: "tts.wav" } + }) + }catch(e){ + await context.editOrRespond({ + embeds: [createEmbed("error", context, "Unable to generate audio file.")] + }) + } + }, +}; \ No newline at end of file diff --git a/labscore/api/endpoints.js b/labscore/api/endpoints.js index e208343..f7d22e8 100644 --- a/labscore/api/endpoints.js +++ b/labscore/api/endpoints.js @@ -46,6 +46,7 @@ const Api = Object.freeze({ TTS_IMTRANSLATOR: '/tts/imtranslator', TTS_PLAYHT: '/tts/playht', TTS_POLLY: '/tts/polly', + TTS_SAPI4: '/tts/sapi4', TTS_TIKTOK: '/tts/tiktok', TTS_VOICEFORGE: '/tts/voiceforge', diff --git a/labscore/api/index.js b/labscore/api/index.js index 39aaf06..24fe043 100644 --- a/labscore/api/index.js +++ b/labscore/api/index.js @@ -268,6 +268,15 @@ module.exports.polly = async function(context, text, voice){ }) } +module.exports.sapi4 = async function(context, text, voice, pitch = 50, speed = 150){ + return await request(Api.TTS_SAPI4, "GET", {}, { + text, + voice, + pitch, + speed + }) +} + module.exports.tiktok = async function(context, text, voice){ return await request(Api.TTS_TIKTOK, "GET", {}, { text: text, diff --git a/labscore/constants.js b/labscore/constants.js index 6534ccc..3b112fa 100644 --- a/labscore/constants.js +++ b/labscore/constants.js @@ -278,6 +278,26 @@ module.exports.IMTRANSLATOR_VOICES = [ { name: "Korean (Female)", value: "ko" } ] +module.exports.MICROSOFT_VOICES = [ + { name: "Microsoft Sam", value: "Sam" }, + { name: "BonziBUDDY", value: "Bonzi" }, + { name: "Mary", value: "Mary" }, + { name: "Mike", value: "Mike" }, + { name: "Robot", value: "RoboSoft Four" }, + { name: "Whisper (Female)", value: "Female Whisper" }, + { name: "Whisper (Male)", value: "Male Whisper" } +] + +module.exports.MICROSOFT_VOICE_CONFIG = { + "Sam": { pitch: 100, speed: 150 }, + "Bonzi": { pitch: 140, speed: 157 }, + "Mary": { pitch: 169, speed: 170 }, + "Mike": { pitch: 113, speed: 170 }, + "RoboSoft Four": { pitch: 169, speed: 170 }, + "Female Whisper": { pitch: 169, speed: 170 }, + "Male Whisper": { pitch: 113, speed: 170 } +} + module.exports.TRANSLATE_LANGUAGE_MAPPINGS = Object.freeze({ "af": "πŸ‡ΏπŸ‡¦", "sq": "πŸ‡¦πŸ‡±",