@jambonz/speech-utils 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/add-file-to-cache.js +2 -1
- package/lib/config.js +20 -0
- package/lib/get-ibm-access-token.js +1 -1
- package/lib/get-nuance-access-token.js +1 -1
- package/lib/get-tts-voices.js +1 -1
- package/lib/get-verbio-token.js +1 -1
- package/lib/synth-audio.js +28 -39
- package/lib/utils.js +41 -3
- package/package.json +2 -1
- package/stubs/nuance/synthesizer_grpc_pb.js +3 -3
- package/stubs/riva/proto/riva_audio_grpc_pb.js +1 -1
- package/stubs/riva/proto/riva_tts_grpc_pb.js +5 -5
- package/test/synth.js +13 -2
- package/lib/constants.js +0 -3
package/lib/add-file-to-cache.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs/promises');
|
|
2
2
|
const {noopLogger, makeSynthKey} = require('./utils');
|
|
3
|
-
const
|
|
3
|
+
const {JAMBONES_TTS_CACHE_DURATION_MINS} = require('./config');
|
|
4
|
+
const EXPIRES = JAMBONES_TTS_CACHE_DURATION_MINS;
|
|
4
5
|
|
|
5
6
|
async function addFileToCache(client, logger, path,
|
|
6
7
|
{account_sid, vendor, language, voice, deploymentId, engine, text}) {
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const JAMBONES_TTS_TRIM_SILENCE = process.env.JAMBONES_TTS_TRIM_SILENCE;
|
|
2
|
+
const JAMBONES_DISABLE_TTS_STREAMING = process.env.JAMBONES_DISABLE_TTS_STREAMING;
|
|
3
|
+
|
|
4
|
+
const JAMBONES_HTTP_PROXY_IP = process.env.JAMBONES_HTTP_PROXY_IP;
|
|
5
|
+
const JAMBONES_HTTP_PROXY_PORT = process.env.JAMBONES_HTTP_PROXY_PORT;
|
|
6
|
+
const JAMBONES_TTS_CACHE_DURATION_MINS = (parseInt(process.env.JAMBONES_TTS_CACHE_DURATION_MINS) || 4 * 60) * 60; // cache tts for 4 hours
|
|
7
|
+
|
|
8
|
+
const TMP_FOLDER = '/tmp';
|
|
9
|
+
|
|
10
|
+
const HTTP_TIMEOUT = 5000;
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
JAMBONES_TTS_TRIM_SILENCE,
|
|
14
|
+
JAMBONES_DISABLE_TTS_STREAMING,
|
|
15
|
+
JAMBONES_HTTP_PROXY_IP,
|
|
16
|
+
JAMBONES_HTTP_PROXY_PORT,
|
|
17
|
+
JAMBONES_TTS_CACHE_DURATION_MINS,
|
|
18
|
+
TMP_FOLDER,
|
|
19
|
+
HTTP_TIMEOUT
|
|
20
|
+
};
|
|
@@ -2,7 +2,7 @@ const formurlencoded = require('form-urlencoded');
|
|
|
2
2
|
const {Pool} = require('undici');
|
|
3
3
|
const pool = new Pool('https://iam.cloud.ibm.com');
|
|
4
4
|
const {makeIbmKey, noopLogger} = require('./utils');
|
|
5
|
-
const { HTTP_TIMEOUT } = require('./
|
|
5
|
+
const { HTTP_TIMEOUT } = require('./config');
|
|
6
6
|
const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
7
7
|
|
|
8
8
|
async function getIbmAccessToken(client, logger, apiKey) {
|
|
@@ -2,7 +2,7 @@ const formurlencoded = require('form-urlencoded');
|
|
|
2
2
|
const {Pool} = require('undici');
|
|
3
3
|
const pool = new Pool('https://auth.crt.nuance.com');
|
|
4
4
|
const {makeNuanceKey, makeBasicAuthHeader, noopLogger} = require('./utils');
|
|
5
|
-
const { HTTP_TIMEOUT } = require('./
|
|
5
|
+
const { HTTP_TIMEOUT } = require('./config');
|
|
6
6
|
const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
7
7
|
|
|
8
8
|
async function getNuanceAccessToken(client, logger, clientId, secret, scope) {
|
package/lib/get-tts-voices.js
CHANGED
|
@@ -9,7 +9,7 @@ const ttsGoogle = require('@google-cloud/text-to-speech');
|
|
|
9
9
|
const { PollyClient, DescribeVoicesCommand } = require('@aws-sdk/client-polly');
|
|
10
10
|
const getAwsAuthToken = require('./get-aws-sts-token');
|
|
11
11
|
const {Pool} = require('undici');
|
|
12
|
-
const { HTTP_TIMEOUT } = require('./
|
|
12
|
+
const { HTTP_TIMEOUT } = require('./config');
|
|
13
13
|
const verbioVoicePool = new Pool('https://us.rest.speechcenter.verbio.com');
|
|
14
14
|
|
|
15
15
|
const getIbmVoices = async(client, logger, credentials) => {
|
package/lib/get-verbio-token.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const {Pool} = require('undici');
|
|
2
2
|
const { noopLogger, makeVerbioKey } = require('./utils');
|
|
3
|
-
const { HTTP_TIMEOUT } = require('./
|
|
3
|
+
const { HTTP_TIMEOUT } = require('./config');
|
|
4
4
|
const pool = new Pool('https://auth.speechcenter.verbio.com:444');
|
|
5
5
|
const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
6
6
|
|
package/lib/synth-audio.js
CHANGED
|
@@ -19,7 +19,8 @@ const {
|
|
|
19
19
|
createNuanceClient,
|
|
20
20
|
createKryptonClient,
|
|
21
21
|
createRivaClient,
|
|
22
|
-
noopLogger
|
|
22
|
+
noopLogger,
|
|
23
|
+
makeFilePath
|
|
23
24
|
} = require('./utils');
|
|
24
25
|
const getNuanceAccessToken = require('./get-nuance-access-token');
|
|
25
26
|
const getVerbioAccessToken = require('./get-verbio-token');
|
|
@@ -37,8 +38,13 @@ const {
|
|
|
37
38
|
const {SynthesizeSpeechRequest} = require('../stubs/riva/proto/riva_tts_pb');
|
|
38
39
|
const {AudioEncoding} = require('../stubs/riva/proto/riva_audio_pb');
|
|
39
40
|
const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
40
|
-
const
|
|
41
|
-
|
|
41
|
+
const {
|
|
42
|
+
JAMBONES_DISABLE_TTS_STREAMING,
|
|
43
|
+
JAMBONES_HTTP_PROXY_IP,
|
|
44
|
+
JAMBONES_HTTP_PROXY_PORT,
|
|
45
|
+
JAMBONES_TTS_CACHE_DURATION_MINS,
|
|
46
|
+
} = require('./config');
|
|
47
|
+
const EXPIRES = JAMBONES_TTS_CACHE_DURATION_MINS;
|
|
42
48
|
const OpenAI = require('openai');
|
|
43
49
|
const getAwsAuthToken = require('./get-aws-sts-token');
|
|
44
50
|
|
|
@@ -154,19 +160,7 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
154
160
|
text
|
|
155
161
|
});
|
|
156
162
|
let filePath;
|
|
157
|
-
|
|
158
|
-
(
|
|
159
|
-
(process.env.JAMBONES_TTS_TRIM_SILENCE || !process.env.JAMBONES_DISABLE_TTS_STREAMING) &&
|
|
160
|
-
['microsoft', 'azure'].includes(vendor)
|
|
161
|
-
) ||
|
|
162
|
-
(
|
|
163
|
-
!process.env.JAMBONES_DISABLE_TTS_STREAMING &&
|
|
164
|
-
['elevenlabs', 'deepgram', 'rimelabs'].includes(vendor)
|
|
165
|
-
)
|
|
166
|
-
) {
|
|
167
|
-
filePath = `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt || ''}`)}.r8`;
|
|
168
|
-
}
|
|
169
|
-
else filePath = `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt || ''}`)}.mp3`;
|
|
163
|
+
filePath = makeFilePath(vendor, key, salt);
|
|
170
164
|
debug(`synth key is ${key}`);
|
|
171
165
|
let cached;
|
|
172
166
|
if (!disableTtsCache) {
|
|
@@ -200,8 +194,7 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
200
194
|
case 'microsoft':
|
|
201
195
|
vendorLabel = 'microsoft';
|
|
202
196
|
audioBuffer = await synthMicrosoft(logger, {credentials, stats, language, voice, text, deploymentId,
|
|
203
|
-
filePath, renderForCaching, disableTtsStreaming});
|
|
204
|
-
if (audioBuffer?.filePath) return audioBuffer;
|
|
197
|
+
filePath, renderForCaching, disableTtsStreaming});
|
|
205
198
|
break;
|
|
206
199
|
case 'nuance':
|
|
207
200
|
model = model || 'enhanced';
|
|
@@ -219,25 +212,21 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
219
212
|
case 'elevenlabs':
|
|
220
213
|
audioBuffer = await synthElevenlabs(logger, {
|
|
221
214
|
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming, filePath
|
|
222
|
-
});
|
|
223
|
-
if (audioBuffer?.filePath) return audioBuffer;
|
|
215
|
+
});
|
|
224
216
|
break;
|
|
225
217
|
case 'playht':
|
|
226
218
|
audioBuffer = await synthPlayHT(logger, {
|
|
227
219
|
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming, filePath
|
|
228
|
-
});
|
|
229
|
-
if (audioBuffer?.filePath) return audioBuffer;
|
|
220
|
+
});
|
|
230
221
|
break;
|
|
231
222
|
case 'rimelabs':
|
|
232
223
|
audioBuffer = await synthRimelabs(logger, {
|
|
233
224
|
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming, filePath
|
|
234
|
-
});
|
|
235
|
-
if (audioBuffer?.filePath) return audioBuffer;
|
|
225
|
+
});
|
|
236
226
|
break;
|
|
237
227
|
case 'whisper':
|
|
238
228
|
audioBuffer = await synthWhisper(logger, {
|
|
239
|
-
credentials, stats, voice, text, renderForCaching, disableTtsStreaming});
|
|
240
|
-
if (audioBuffer?.filePath) return audioBuffer;
|
|
229
|
+
credentials, stats, voice, text, renderForCaching, disableTtsStreaming});
|
|
241
230
|
break;
|
|
242
231
|
case 'verbio':
|
|
243
232
|
audioBuffer = await synthVerbio(client, logger, {
|
|
@@ -246,8 +235,7 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
246
235
|
break;
|
|
247
236
|
case 'deepgram':
|
|
248
237
|
audioBuffer = await synthDeepgram(logger, {credentials, stats, model, text,
|
|
249
|
-
renderForCaching, disableTtsStreaming});
|
|
250
|
-
if (audioBuffer?.filePath) return audioBuffer;
|
|
238
|
+
renderForCaching, disableTtsStreaming});
|
|
251
239
|
break;
|
|
252
240
|
case vendor.startsWith('custom') ? vendor : 'cant_match_value':
|
|
253
241
|
({ audioBuffer, filePath } = await synthCustomVendor(logger,
|
|
@@ -256,6 +244,7 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
256
244
|
default:
|
|
257
245
|
assert(`synthAudio: unsupported speech vendor ${vendor}`);
|
|
258
246
|
}
|
|
247
|
+
if('filePath' in audioBuffer) return audioBuffer;
|
|
259
248
|
const diff = process.hrtime(startAt);
|
|
260
249
|
const time = diff[0] * 1e3 + diff[1] * 1e-6;
|
|
261
250
|
rtt = time.toFixed(0);
|
|
@@ -454,7 +443,7 @@ const synthMicrosoft = async(logger, {
|
|
|
454
443
|
content = `<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="${language}"><voice name="${voice}">${words}</voice></speak>`;
|
|
455
444
|
logger.info({content}, 'synthMicrosoft');
|
|
456
445
|
}
|
|
457
|
-
if (!
|
|
446
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
458
447
|
let params = '';
|
|
459
448
|
params += `{api_key=${apiKey}`;
|
|
460
449
|
params += `,language=${language}`;
|
|
@@ -464,8 +453,8 @@ const synthMicrosoft = async(logger, {
|
|
|
464
453
|
if (region) params += `,region=${region}`;
|
|
465
454
|
if (custom_tts_endpoint) params += `,endpointId=${custom_tts_endpoint}`;
|
|
466
455
|
if (custom_tts_endpoint_url) params += `,endpoint=${custom_tts_endpoint_url}`;
|
|
467
|
-
if (
|
|
468
|
-
if (
|
|
456
|
+
if (JAMBONES_HTTP_PROXY_IP) params += `,http_proxy_ip=${JAMBONES_HTTP_PROXY_IP}`;
|
|
457
|
+
if (JAMBONES_HTTP_PROXY_PORT) params += `,http_proxy_port=${JAMBONES_HTTP_PROXY_PORT}`;
|
|
469
458
|
params += '}';
|
|
470
459
|
return {
|
|
471
460
|
filePath: `say:${params}${content.replace(/\n/g, ' ')}`,
|
|
@@ -494,10 +483,10 @@ const synthMicrosoft = async(logger, {
|
|
|
494
483
|
SpeechSynthesisOutputFormat.Raw8Khz16BitMonoPcm :
|
|
495
484
|
SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
|
|
496
485
|
|
|
497
|
-
if (
|
|
486
|
+
if (JAMBONES_HTTP_PROXY_IP && JAMBONES_HTTP_PROXY_PORT) {
|
|
498
487
|
logger.debug(
|
|
499
|
-
`synthMicrosoft: using proxy ${
|
|
500
|
-
speechConfig.setProxy(
|
|
488
|
+
`synthMicrosoft: using proxy ${JAMBONES_HTTP_PROXY_IP}:${JAMBONES_HTTP_PROXY_PORT}`);
|
|
489
|
+
speechConfig.setProxy(JAMBONES_HTTP_PROXY_IP, JAMBONES_HTTP_PROXY_PORT);
|
|
501
490
|
}
|
|
502
491
|
const synthesizer = new SpeechSynthesizer(speechConfig);
|
|
503
492
|
|
|
@@ -683,7 +672,7 @@ const synthElevenlabs = async(logger, {
|
|
|
683
672
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
684
673
|
|
|
685
674
|
/* default to using the streaming interface, unless disabled by env var OR we want just a cache file */
|
|
686
|
-
if (!
|
|
675
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
687
676
|
let params = '';
|
|
688
677
|
params += `{api_key=${api_key}`;
|
|
689
678
|
params += ',vendor=elevenlabs';
|
|
@@ -736,7 +725,7 @@ const synthPlayHT = async(logger, {
|
|
|
736
725
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
737
726
|
|
|
738
727
|
/* default to using the streaming interface, unless disabled by env var OR we want just a cache file */
|
|
739
|
-
if (!
|
|
728
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
740
729
|
let params = '';
|
|
741
730
|
params += `{api_key=${api_key}`;
|
|
742
731
|
params += `,user_id=${user_id}`;
|
|
@@ -791,7 +780,7 @@ const synthRimelabs = async(logger, {
|
|
|
791
780
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
792
781
|
|
|
793
782
|
/* default to using the streaming interface, unless disabled by env var OR we want just a cache file */
|
|
794
|
-
if (!
|
|
783
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
795
784
|
let params = '';
|
|
796
785
|
params += `{api_key=${api_key}`;
|
|
797
786
|
params += `,model_id=${model_id}`;
|
|
@@ -873,7 +862,7 @@ const synthVerbio = async(client, logger, {credentials, stats, voice, text, rend
|
|
|
873
862
|
const synthWhisper = async(logger, {credentials, stats, voice, text, renderForCaching, disableTtsStreaming}) => {
|
|
874
863
|
const {api_key, model_id, baseURL, timeout, speed} = credentials;
|
|
875
864
|
/* if the env is set to stream then bag out, unless we are specifically rendering to generate a cache file */
|
|
876
|
-
if (!
|
|
865
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
877
866
|
let params = '';
|
|
878
867
|
params += `{api_key=${api_key}`;
|
|
879
868
|
params += `,model_id=${model_id}`;
|
|
@@ -912,7 +901,7 @@ const synthWhisper = async(logger, {credentials, stats, voice, text, renderForCa
|
|
|
912
901
|
|
|
913
902
|
const synthDeepgram = async(logger, {credentials, stats, model, text, renderForCaching, disableTtsStreaming}) => {
|
|
914
903
|
const {api_key} = credentials;
|
|
915
|
-
if (!
|
|
904
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
916
905
|
let params = '';
|
|
917
906
|
params += `{api_key=${api_key}`;
|
|
918
907
|
params += ',vendor=deepgram';
|
package/lib/utils.js
CHANGED
|
@@ -6,7 +6,7 @@ const pool = new Pool('https://auth.crt.nuance.com');
|
|
|
6
6
|
const NUANCE_AUTH_ENDPOINT = 'tts.api.nuance.com:443';
|
|
7
7
|
const grpc = require('@grpc/grpc-js');
|
|
8
8
|
const formurlencoded = require('form-urlencoded');
|
|
9
|
-
const { HTTP_TIMEOUT } = require('./
|
|
9
|
+
const { JAMBONES_DISABLE_TTS_STREAMING, JAMBONES_TTS_TRIM_SILENCE, TMP_FOLDER, HTTP_TIMEOUT } = require('./config');
|
|
10
10
|
|
|
11
11
|
const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
12
12
|
/**
|
|
@@ -19,7 +19,44 @@ const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
|
19
19
|
function makeSynthKey({account_sid = '', vendor, language, voice, engine = '', text}) {
|
|
20
20
|
const hash = crypto.createHash('sha1');
|
|
21
21
|
hash.update(`${language}:${vendor}:${voice}:${engine}:${text}`);
|
|
22
|
-
|
|
22
|
+
const hexHashKey = hash.digest('hex');
|
|
23
|
+
const accountKey = account_sid ? `:${account_sid}` : '';
|
|
24
|
+
const namespace = vendor.startsWith('custom') ? vendor : getFileExtension(vendor);
|
|
25
|
+
const key = `tts${accountKey}:${namespace}:${hexHashKey}`;
|
|
26
|
+
return key;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function makeFilePath(vendor, key, salt = '') {
|
|
30
|
+
const extension = getFileExtension(vendor);
|
|
31
|
+
return `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt}`)}.${extension}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getFileExtension(vendor) {
|
|
35
|
+
const mp3Extension = 'mp3';
|
|
36
|
+
const r8Extension = 'r8';
|
|
37
|
+
|
|
38
|
+
switch (vendor) {
|
|
39
|
+
case 'azure':
|
|
40
|
+
case 'microsoft':
|
|
41
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING || JAMBONES_TTS_TRIM_SILENCE) {
|
|
42
|
+
return r8Extension;
|
|
43
|
+
} else {
|
|
44
|
+
return mp3Extension;
|
|
45
|
+
}
|
|
46
|
+
case 'deepgram':
|
|
47
|
+
case 'elevenlabs':
|
|
48
|
+
case 'rimlabs':
|
|
49
|
+
if (!JAMBONES_DISABLE_TTS_STREAMING) {
|
|
50
|
+
return r8Extension;
|
|
51
|
+
} else {
|
|
52
|
+
return mp3Extension;
|
|
53
|
+
}
|
|
54
|
+
case 'nuance':
|
|
55
|
+
case 'nvidia':
|
|
56
|
+
return r8Extension;
|
|
57
|
+
default:
|
|
58
|
+
return mp3Extension;
|
|
59
|
+
}
|
|
23
60
|
}
|
|
24
61
|
|
|
25
62
|
const noopLogger = {
|
|
@@ -130,5 +167,6 @@ module.exports = {
|
|
|
130
167
|
createRivaClient,
|
|
131
168
|
makeBasicAuthHeader,
|
|
132
169
|
NUANCE_AUTH_ENDPOINT,
|
|
133
|
-
noopLogger
|
|
170
|
+
noopLogger,
|
|
171
|
+
makeFilePath
|
|
134
172
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jambonz/speech-utils",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "TTS-related speech utilities for jambonz",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Dave Horton",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"test": "NODE_ENV=test node test/ ",
|
|
13
13
|
"coverage": "nyc --reporter html --report-dir ./coverage npm run test",
|
|
14
14
|
"jslint": "eslint index.js lib",
|
|
15
|
+
"jslint:fix": "eslint --fix '**/*.js'",
|
|
15
16
|
"build": "./build_stubs.sh"
|
|
16
17
|
},
|
|
17
18
|
"repository": {
|
|
@@ -62,9 +62,9 @@ function deserialize_nuance_tts_v1_UnarySynthesisResponse(buffer_arg) {
|
|
|
62
62
|
|
|
63
63
|
//
|
|
64
64
|
// The Synthesizer service offers these functionalities:
|
|
65
|
-
// - GetVoices: Queries the list of available voices, with filters to reduce the search space.
|
|
66
|
-
// - Synthesize: Synthesizes audio from input text and parameters, and returns an audio stream.
|
|
67
|
-
// - UnarySynthesize: Synthesizes audio from input text and parameters, and returns a single audio response.
|
|
65
|
+
// - GetVoices: Queries the list of available voices, with filters to reduce the search space.
|
|
66
|
+
// - Synthesize: Synthesizes audio from input text and parameters, and returns an audio stream.
|
|
67
|
+
// - UnarySynthesize: Synthesizes audio from input text and parameters, and returns a single audio response.
|
|
68
68
|
var SynthesizerService = exports.SynthesizerService = {
|
|
69
69
|
getVoices: {
|
|
70
70
|
path: '/nuance.tts.v1.Synthesizer/GetVoices',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
// GENERATED CODE -- NO SERVICES IN PROTO
|
|
1
|
+
// GENERATED CODE -- NO SERVICES IN PROTO
|
|
@@ -57,7 +57,7 @@ function deserialize_nvidia_riva_tts_SynthesizeSpeechResponse(buffer_arg) {
|
|
|
57
57
|
var RivaSpeechSynthesisService = exports.RivaSpeechSynthesisService = {
|
|
58
58
|
// Used to request text-to-speech from the service. Submit a request containing the
|
|
59
59
|
// desired text and configuration, and receive audio bytes in the requested format.
|
|
60
|
-
synthesize: {
|
|
60
|
+
synthesize: {
|
|
61
61
|
path: '/nvidia.riva.tts.RivaSpeechSynthesis/Synthesize',
|
|
62
62
|
requestStream: false,
|
|
63
63
|
responseStream: false,
|
|
@@ -69,9 +69,9 @@ synthesize: {
|
|
|
69
69
|
responseDeserialize: deserialize_nvidia_riva_tts_SynthesizeSpeechResponse,
|
|
70
70
|
},
|
|
71
71
|
// Used to request text-to-speech returned via stream as it becomes available.
|
|
72
|
-
// Submit a SynthesizeSpeechRequest with desired text and configuration,
|
|
73
|
-
// and receive stream of bytes in the requested format.
|
|
74
|
-
synthesizeOnline: {
|
|
72
|
+
// Submit a SynthesizeSpeechRequest with desired text and configuration,
|
|
73
|
+
// and receive stream of bytes in the requested format.
|
|
74
|
+
synthesizeOnline: {
|
|
75
75
|
path: '/nvidia.riva.tts.RivaSpeechSynthesis/SynthesizeOnline',
|
|
76
76
|
requestStream: false,
|
|
77
77
|
responseStream: true,
|
|
@@ -83,7 +83,7 @@ synthesizeOnline: {
|
|
|
83
83
|
responseDeserialize: deserialize_nvidia_riva_tts_SynthesizeSpeechResponse,
|
|
84
84
|
},
|
|
85
85
|
// Enables clients to request the configuration of the current Synthesize service, or a specific model within the service.
|
|
86
|
-
getRivaSynthesisConfig: {
|
|
86
|
+
getRivaSynthesisConfig: {
|
|
87
87
|
path: '/nvidia.riva.tts.RivaSpeechSynthesis/GetRivaSynthesisConfig',
|
|
88
88
|
requestStream: false,
|
|
89
89
|
responseStream: false,
|
package/test/synth.js
CHANGED
|
@@ -789,8 +789,19 @@ test('TTS Cache tests', async(t) => {
|
|
|
789
789
|
t.ok(error, `error returned when specified key was not found`);
|
|
790
790
|
|
|
791
791
|
// make sure other tts keys are still there
|
|
792
|
-
const cached =
|
|
793
|
-
t.ok(cached >= 1, `successfully kept all non-specified tts records in cache`);
|
|
792
|
+
const cached = await client.keys('tts:*')
|
|
793
|
+
t.ok(cached.length >= 1, `successfully kept all non-specified tts records in cache`);
|
|
794
|
+
|
|
795
|
+
// retrieve keys from cache and check the key contains the file extension
|
|
796
|
+
let key = cached[0];
|
|
797
|
+
t.ok(key.includes('mp3'), `tts cache extension shoult be part of the key and equal mp3`);
|
|
798
|
+
|
|
799
|
+
process.env.VG_TRIM_TTS_SILENCE = 'true';
|
|
800
|
+
await client.set(makeSynthKey({ vendor: 'azure' }), 'value');
|
|
801
|
+
|
|
802
|
+
const r8Keys = await client.keys('tts:r8*');
|
|
803
|
+
key = r8Keys[0];
|
|
804
|
+
t.ok(key.includes('r8'), `tts cache extension shoult be part of the key and equal r8`);
|
|
794
805
|
|
|
795
806
|
} catch (err) {
|
|
796
807
|
console.error(JSON.stringify(err));
|
package/lib/constants.js
DELETED