support verbio speech (#323)

* support verbio speech

* wip

* update speech version

* update verb specification
This commit is contained in:
Hoan Luu Huu
2024-05-29 18:35:40 +07:00
committed by GitHub
parent ffe9cb23eb
commit d33d0aa519
8 changed files with 212 additions and 15 deletions
+88
View File
@@ -18,6 +18,7 @@ const TtsNvidiaLanguagesVoices = require('./speech-data/tts-nvidia');
const TtsElevenlabsLanguagesVoices = require('./speech-data/tts-elevenlabs');
const TtsWhisperLanguagesVoices = require('./speech-data/tts-whisper');
const TtsPlayHtLanguagesVoices = require('./speech-data/tts-playht');
const TtsVerbioLanguagesVoices = require('./speech-data/tts-verbio');
const TtsModelDeepgram = require('./speech-data/tts-model-deepgram');
const TtsModelElevenLabs = require('./speech-data/tts-model-elevenlabs');
@@ -35,6 +36,7 @@ const SttNvidiaLanguagesVoices = require('./speech-data/stt-nvidia');
const SttCobaltLanguagesVoices = require('./speech-data/stt-cobalt');
const SttSonioxLanguagesVoices = require('./speech-data/stt-soniox');
const SttAssemblyaiLanguagesVoices = require('./speech-data/stt-assemblyai');
const SttVerbioLanguagesVoices = require('./speech-data/stt-verbio');
const testSonioxStt = async(logger, credentials) => {
const api_key = credentials;
@@ -366,6 +368,43 @@ const testWellSaidStt = async(logger, credentials) => {
return true;
};
const testVerbioTts = async(logger, synthAudio, credentials) => {
try {
await synthAudio(
{
increment: () => {},
histogram: () => {}
},
{
vendor: 'verbio',
credentials,
language: 'en-US',
voice: 'tommy_en-us',
text: 'Hi there and welcome to jambones!'
}
);
} catch (err) {
logger.info({err}, 'synth Verbio returned error');
throw err;
}
};
const testVerbioStt = async(logger, getVerbioAccessToken, credentials) => {
const token = await getVerbioAccessToken(credentials);
try {
const post = bent('https://us.rest.speechcenter.verbio.com', 'POST', 'json', {
'Authorization': `Bearer ${token.access_token}`,
'User-Agent': 'jambonz',
'Content-Type': 'audio/wav'
});
const json = await post('/api/v1/recognize?language=en-US&version=V1',
fs.readFileSync(`${__dirname}/../../data/test_audio.wav`));
logger.debug({json}, 'successfully speech to text from verbio');
} catch (err) {
logger.info({err}, 'testWellSaidTts returned error');
throw err;
}
};
const testAssemblyStt = async(logger, credentials) => {
const {api_key} = credentials;
@@ -512,6 +551,11 @@ function decryptCredential(obj, credential, logger, isObscureKey = true) {
const o = JSON.parse(decrypt(credential));
obj.api_key = isObscureKey ? obscureKey(o.api_key) : o.api_key;
obj.model_id = o.model_id;
} else if ('verbio' === obj.vendor) {
const o = JSON.parse(decrypt(credential));
obj.client_id = o.client_id;
obj.client_secret = isObscureKey ? obscureKey(o.client_secret) : o.client_secret;
obj.engine_version = o.engine_version;
}
}
@@ -568,6 +612,8 @@ async function getLanguagesAndVoicesForVendor(logger, vendor, credential, getTts
return await getLanguagesVoicesForAssemblyAI(credential, getTtsVoices, logger);
case 'whisper':
return await getLanguagesVoicesForWhisper(credential, getTtsVoices, logger);
case 'verbio':
return await getLanguagesVoicesForVerbio(credential, getTtsVoices, logger);
default:
logger.info(`invalid vendor ${vendor}, return empty result`);
throw new Error(`Invalid vendor ${vendor}`);
@@ -816,6 +862,23 @@ async function getLanguagesVoicesForWhisper(credential) {
return tranform(TtsWhisperLanguagesVoices, undefined, TtsModelWhisper);
}
async function getLanguagesVoicesForVerbio(credentials, getTtsVoices, logger) {
const stt = SttVerbioLanguagesVoices.reduce((acc, v) => {
if (!v.version || credentials.engine_version === v.version) {
acc.push(v);
}
return acc;
}, []);
try {
const data = await getTtsVoices({vendor: 'verbio', credentials});
const voices = parseVerbioLanguagesVoices(data);
return tranform(voices, stt, undefined);
} catch (err) {
logger.info({err}, 'there is error while fetching verbio speech voices');
return tranform(TtsVerbioLanguagesVoices, stt, undefined);
}
}
function tranform(tts, stt, models) {
return {
...(tts && {tts}),
@@ -943,6 +1006,29 @@ function parseMicrosoftLanguagesVoices(data) {
}, []);
}
function parseVerbioLanguagesVoices(data) {
return data.reduce((acc, voice) => {
const languageCode = voice.language;
const existingLanguage = acc.find((lang) => lang.value === languageCode);
if (existingLanguage) {
existingLanguage.voices.push({
value: voice.voice_id,
name: voice.name,
});
} else {
acc.push({
value: voice.language,
name: voice.language,
voices: [{
value: voice.voice_id,
name: voice.name,
}]
});
}
return acc;
}, []);
}
module.exports = {
testGoogleTts,
testGoogleStt,
@@ -966,5 +1052,7 @@ module.exports = {
getSpeechCredential,
decryptCredential,
testWhisper,
testVerbioTts,
testVerbioStt,
getLanguagesAndVoicesForVendor
};