@jambonz/speech-utils 0.0.6 → 0.0.8
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/get-tts-voices.js +42 -6
- package/lib/synth-audio.js +15 -7
- package/lib/utils.js +6 -0
- package/package.json +1 -1
- package/test/index.js +1 -2
- package/test/list-voices.js +205 -0
- package/test/nuance.js +35 -4
- package/test/synth.js +38 -1
package/lib/get-tts-voices.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const assert = require('assert');
|
|
2
|
-
const {noopLogger, createNuanceClient} = require('./utils');
|
|
2
|
+
const {noopLogger, createNuanceClient, createKryptonClient} = require('./utils');
|
|
3
3
|
const getNuanceAccessToken = require('./get-nuance-access-token');
|
|
4
4
|
const {GetVoicesRequest, Voice} = require('../stubs/nuance/synthesizer_pb');
|
|
5
5
|
const TextToSpeechV1 = require('ibm-watson/text-to-speech/v1');
|
|
6
6
|
const { IamAuthenticator } = require('ibm-watson/auth');
|
|
7
|
+
const ttsGoogle = require('@google-cloud/text-to-speech');
|
|
8
|
+
const { PollyClient, DescribeVoicesCommand } = require('@aws-sdk/client-polly');
|
|
7
9
|
|
|
8
10
|
const getIbmVoices = async(client, logger, credentials) => {
|
|
9
11
|
const {tts_region, tts_api_key} = credentials;
|
|
@@ -21,15 +23,20 @@ const getIbmVoices = async(client, logger, credentials) => {
|
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
const getNuanceVoices = async(client, logger, credentials) => {
|
|
24
|
-
const {client_id: clientId, secret: secret} = credentials;
|
|
26
|
+
const {client_id: clientId, secret: secret, nuance_tts_uri} = credentials;
|
|
25
27
|
|
|
26
28
|
return new Promise(async(resolve, reject) => {
|
|
27
29
|
/* get a nuance access token */
|
|
28
30
|
let token, nuanceClient;
|
|
29
31
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
if (nuance_tts_uri) {
|
|
33
|
+
nuanceClient = await createKryptonClient(nuance_tts_uri);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const access_token = await getNuanceAccessToken(client, logger, clientId, secret, 'tts');
|
|
37
|
+
token = access_token.access_token;
|
|
38
|
+
nuanceClient = await createNuanceClient(token);
|
|
39
|
+
}
|
|
33
40
|
} catch (err) {
|
|
34
41
|
logger.error({err}, 'getTtsVoices: error retrieving access token');
|
|
35
42
|
return reject(err);
|
|
@@ -75,6 +82,30 @@ const getNuanceVoices = async(client, logger, credentials) => {
|
|
|
75
82
|
});
|
|
76
83
|
};
|
|
77
84
|
|
|
85
|
+
const getGoogleVoices = async(_client, logger, credentials) => {
|
|
86
|
+
const client = new ttsGoogle.TextToSpeechClient({credentials});
|
|
87
|
+
return await client.listVoices();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const getAwsVoices = async(_client, logger, credentials) => {
|
|
91
|
+
try {
|
|
92
|
+
const {region, accessKeyId, secretAccessKey} = credentials;
|
|
93
|
+
const client = new PollyClient({
|
|
94
|
+
region,
|
|
95
|
+
credentials: {
|
|
96
|
+
accessKeyId,
|
|
97
|
+
secretAccessKey
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
const command = new DescribeVoicesCommand({LanguageCode: 'en-US'});
|
|
101
|
+
const response = await client.send(command);
|
|
102
|
+
return response;
|
|
103
|
+
} catch (err) {
|
|
104
|
+
logger.info({err}, 'testMicrosoftTts - failed to list voices for region ${region}');
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
78
109
|
/**
|
|
79
110
|
* Synthesize speech to an mp3 file, and also cache the generated speech
|
|
80
111
|
* in redis (base64 format) for 24 hours so as to avoid unnecessarily paying
|
|
@@ -94,7 +125,7 @@ const getNuanceVoices = async(client, logger, credentials) => {
|
|
|
94
125
|
async function getTtsVoices(client, logger, {vendor, credentials}) {
|
|
95
126
|
logger = logger || noopLogger;
|
|
96
127
|
|
|
97
|
-
assert.ok(['nuance', 'ibm'].includes(vendor),
|
|
128
|
+
assert.ok(['nuance', 'ibm', 'google', 'aws', 'polly'].includes(vendor),
|
|
98
129
|
`getTtsVoices not supported for vendor ${vendor}`);
|
|
99
130
|
|
|
100
131
|
switch (vendor) {
|
|
@@ -102,6 +133,11 @@ async function getTtsVoices(client, logger, {vendor, credentials}) {
|
|
|
102
133
|
return getNuanceVoices(client, logger, credentials);
|
|
103
134
|
case 'ibm':
|
|
104
135
|
return getIbmVoices(client, logger, credentials);
|
|
136
|
+
case 'google':
|
|
137
|
+
return getGoogleVoices(client, logger, credentials);
|
|
138
|
+
case 'aws':
|
|
139
|
+
case 'polly':
|
|
140
|
+
return getAwsVoices(client, logger, credentials);
|
|
105
141
|
default:
|
|
106
142
|
break;
|
|
107
143
|
}
|
package/lib/synth-audio.js
CHANGED
|
@@ -16,7 +16,7 @@ const {
|
|
|
16
16
|
CancellationDetails,
|
|
17
17
|
SpeechSynthesisOutputFormat
|
|
18
18
|
} = sdk;
|
|
19
|
-
const {makeSynthKey, createNuanceClient,
|
|
19
|
+
const {makeSynthKey, createNuanceClient, createKryptonClient, createRivaClient, noopLogger} = require('./utils');
|
|
20
20
|
const getNuanceAccessToken = require('./get-nuance-access-token');
|
|
21
21
|
const {
|
|
22
22
|
SynthesisRequest,
|
|
@@ -75,8 +75,10 @@ async function synthAudio(client, logger, stats, { account_sid,
|
|
|
75
75
|
}
|
|
76
76
|
else if ('nuance' === vendor) {
|
|
77
77
|
assert.ok(voice, 'synthAudio requires voice when nuance is used');
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
if (!credentials.nuance_tts_uri) {
|
|
79
|
+
assert.ok(credentials.client_id, 'synthAudio requires client_id in credentials when nuance is used');
|
|
80
|
+
assert.ok(credentials.secret, 'synthAudio requires client_id in credentials when nuance is used');
|
|
81
|
+
}
|
|
80
82
|
}
|
|
81
83
|
else if ('nvidia' === vendor) {
|
|
82
84
|
assert.ok(voice, 'synthAudio requires voice when nvidia is used');
|
|
@@ -371,10 +373,16 @@ const synthWellSaid = async(logger, {credentials, stats, language, voice, gender
|
|
|
371
373
|
};
|
|
372
374
|
|
|
373
375
|
const synthNuance = async(client, logger, {credentials, stats, voice, model, text}) => {
|
|
374
|
-
|
|
375
|
-
const {client_id, secret} = credentials;
|
|
376
|
-
|
|
377
|
-
|
|
376
|
+
let nuanceClient;
|
|
377
|
+
const {client_id, secret, nuance_tts_uri} = credentials;
|
|
378
|
+
if (nuance_tts_uri) {
|
|
379
|
+
nuanceClient = await createKryptonClient(nuance_tts_uri);
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
/* get a nuance access token */
|
|
383
|
+
const {access_token} = await getNuanceAccessToken(client, logger, client_id, secret, 'tts');
|
|
384
|
+
nuanceClient = await createNuanceClient(access_token);
|
|
385
|
+
}
|
|
378
386
|
|
|
379
387
|
const v = new Voice();
|
|
380
388
|
const p = new AudioParameters();
|
package/lib/utils.js
CHANGED
|
@@ -77,6 +77,11 @@ const getNuanceAccessToken = async(clientId, secret, scope = 'asr tts') => {
|
|
|
77
77
|
return json.access_token;
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
+
const createKryptonClient = async(uri) => {
|
|
81
|
+
const client = new SynthesizerClient(uri, grpc.credentials.createInsecure());
|
|
82
|
+
return client;
|
|
83
|
+
};
|
|
84
|
+
|
|
80
85
|
const createNuanceClient = async(access_token) => {
|
|
81
86
|
|
|
82
87
|
//if (nuanceClientMap.has(access_token)) return nuanceClientMap.get(access_token);
|
|
@@ -108,6 +113,7 @@ module.exports = {
|
|
|
108
113
|
makeIbmKey,
|
|
109
114
|
getNuanceAccessToken,
|
|
110
115
|
createNuanceClient,
|
|
116
|
+
createKryptonClient,
|
|
111
117
|
createRivaClient,
|
|
112
118
|
makeBasicAuthHeader,
|
|
113
119
|
NUANCE_AUTH_ENDPOINT,
|
package/package.json
CHANGED
package/test/index.js
CHANGED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
const test = require('tape').test ;
|
|
2
|
+
const config = require('config');
|
|
3
|
+
const opts = config.get('redis');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const logger = require('pino')({level: 'error'});
|
|
6
|
+
process.on('unhandledRejection', (reason, p) => {
|
|
7
|
+
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const stats = {
|
|
11
|
+
increment: () => {},
|
|
12
|
+
histogram: () => {}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
test('IBM - create access key', async(t) => {
|
|
16
|
+
const fn = require('..');
|
|
17
|
+
const {client, getIbmAccessToken} = fn(opts, logger);
|
|
18
|
+
|
|
19
|
+
if (!process.env.IBM_API_KEY ) {
|
|
20
|
+
t.pass('skipping IBM test since no IBM api_key provided');
|
|
21
|
+
t.end();
|
|
22
|
+
client.quit();
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
let obj = await getIbmAccessToken(process.env.IBM_API_KEY);
|
|
27
|
+
//console.log({obj}, 'received access token from IBM');
|
|
28
|
+
t.ok(obj.access_token && !obj.servedFromCache, 'successfull received access token from IBM');
|
|
29
|
+
|
|
30
|
+
obj = await getIbmAccessToken(process.env.IBM_API_KEY);
|
|
31
|
+
//console.log({obj}, 'received access token from IBM - second request');
|
|
32
|
+
t.ok(obj.access_token && obj.servedFromCache, 'successfully received access token from cache');
|
|
33
|
+
|
|
34
|
+
await client.flushallAsync();
|
|
35
|
+
t.end();
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error(err);
|
|
39
|
+
t.end(err);
|
|
40
|
+
}
|
|
41
|
+
client.quit();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('IBM - retrieve tts voices test', async(t) => {
|
|
45
|
+
const fn = require('..');
|
|
46
|
+
const {client, getTtsVoices} = fn(opts, logger);
|
|
47
|
+
|
|
48
|
+
if (!process.env.IBM_TTS_API_KEY || !process.env.IBM_TTS_REGION) {
|
|
49
|
+
t.pass('skipping IBM test since no IBM api_key and/or region provided');
|
|
50
|
+
t.end();
|
|
51
|
+
client.quit();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const opts = {
|
|
56
|
+
vendor: 'ibm',
|
|
57
|
+
credentials: {
|
|
58
|
+
tts_api_key: process.env.IBM_TTS_API_KEY,
|
|
59
|
+
tts_region: process.env.IBM_TTS_REGION
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const obj = await getTtsVoices(opts);
|
|
63
|
+
const {voices} = obj.result;
|
|
64
|
+
//console.log(JSON.stringify(voices));
|
|
65
|
+
t.ok(voices.length > 0 && voices[0].language,
|
|
66
|
+
`GetVoices: successfully retrieved ${voices.length} voices from IBM`);
|
|
67
|
+
|
|
68
|
+
await client.flushallAsync();
|
|
69
|
+
|
|
70
|
+
t.end();
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.error(err);
|
|
75
|
+
t.end(err);
|
|
76
|
+
}
|
|
77
|
+
client.quit();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('Nuance hosted tests', async(t) => {
|
|
81
|
+
const fn = require('..');
|
|
82
|
+
const {client, getTtsVoices} = fn(opts, logger);
|
|
83
|
+
|
|
84
|
+
if (!process.env.NUANCE_CLIENT_ID || !process.env.NUANCE_SECRET ) {
|
|
85
|
+
t.pass('skipping Nuance hosted test since no Nuance client_id and secret provided');
|
|
86
|
+
t.end();
|
|
87
|
+
client.quit();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const opts = {
|
|
92
|
+
vendor: 'nuance',
|
|
93
|
+
credentials: {
|
|
94
|
+
client_id: process.env.NUANCE_CLIENT_ID,
|
|
95
|
+
secret: process.env.NUANCE_SECRET
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
let voices = await getTtsVoices(opts);
|
|
99
|
+
t.ok(voices.length > 0 && voices[0].language,
|
|
100
|
+
`GetVoices: successfully retrieved ${voices.length} voices from Nuance`);
|
|
101
|
+
|
|
102
|
+
await client.flushallAsync();
|
|
103
|
+
|
|
104
|
+
t.end();
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
console.error(err);
|
|
109
|
+
t.end(err);
|
|
110
|
+
}
|
|
111
|
+
client.quit();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('Nuance on-prem tests', async(t) => {
|
|
115
|
+
const fn = require('..');
|
|
116
|
+
const {client, getTtsVoices} = fn(opts, logger);
|
|
117
|
+
|
|
118
|
+
if (!process.env.NUANCE_TTS_URI ) {
|
|
119
|
+
t.pass('skipping Nuance on-prem test since no Nuance uri provided');
|
|
120
|
+
t.end();
|
|
121
|
+
client.quit();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const opts = {
|
|
126
|
+
vendor: 'nuance',
|
|
127
|
+
credentials: {
|
|
128
|
+
nuance_tts_uri: process.env.NUANCE_TTS_URI
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
let voices = await getTtsVoices(opts);
|
|
132
|
+
t.ok(voices.length > 0 && voices[0].language,
|
|
133
|
+
`GetVoices: successfully retrieved ${voices.length} voices from Nuance`);
|
|
134
|
+
|
|
135
|
+
await client.flushallAsync();
|
|
136
|
+
|
|
137
|
+
t.end();
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
console.error(err);
|
|
142
|
+
t.end(err);
|
|
143
|
+
}
|
|
144
|
+
client.quit();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test('Google tests', async(t) => {
|
|
148
|
+
const fn = require('..');
|
|
149
|
+
const {client, getTtsVoices} = fn(opts, logger);
|
|
150
|
+
|
|
151
|
+
if (!process.env.GCP_FILE && !process.env.GCP_JSON_KEY) {
|
|
152
|
+
t.pass('skipping google speech synth tests since neither GCP_FILE nor GCP_JSON_KEY provided');
|
|
153
|
+
return t.end();
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const str = process.env.GCP_JSON_KEY || fs.readFileSync(process.env.GCP_FILE);
|
|
157
|
+
const credentials = JSON.parse(str);
|
|
158
|
+
const opts = {
|
|
159
|
+
vendor: 'google',
|
|
160
|
+
credentials
|
|
161
|
+
};
|
|
162
|
+
let result = await getTtsVoices(opts);
|
|
163
|
+
t.ok(result[0].voices.length > 0, `GetVoices: successfully retrieved ${result[0].voices.length} voices from Google`);
|
|
164
|
+
|
|
165
|
+
await client.flushallAsync();
|
|
166
|
+
|
|
167
|
+
t.end();
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
console.error(err);
|
|
171
|
+
t.end(err);
|
|
172
|
+
}
|
|
173
|
+
client.quit();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('AWS tests', async(t) => {
|
|
177
|
+
const fn = require('..');
|
|
178
|
+
const {client, getTtsVoices} = fn(opts, logger);
|
|
179
|
+
|
|
180
|
+
if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY || !process.env.AWS_REGION) {
|
|
181
|
+
t.pass('skipping AWS speech synth tests since AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, or AWS_REGION not provided');
|
|
182
|
+
return t.end();
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
const opts = {
|
|
186
|
+
vendor: 'aws',
|
|
187
|
+
credentials: {
|
|
188
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
189
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
190
|
+
region: process.env.AWS_REGION,
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
let result = await getTtsVoices(opts);
|
|
194
|
+
t.ok(result?.Voices?.length > 0, `GetVoices: successfully retrieved ${result.Voices.length} voices from AWS`);
|
|
195
|
+
|
|
196
|
+
await client.flushallAsync();
|
|
197
|
+
|
|
198
|
+
t.end();
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
console.error(err);
|
|
202
|
+
t.end(err);
|
|
203
|
+
}
|
|
204
|
+
client.quit();
|
|
205
|
+
});
|
package/test/nuance.js
CHANGED
|
@@ -12,12 +12,12 @@ const stats = {
|
|
|
12
12
|
histogram: () => {}
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
test('Nuance tests', async(t) => {
|
|
15
|
+
test('Nuance hosted tests', async(t) => {
|
|
16
16
|
const fn = require('..');
|
|
17
17
|
const {client, getTtsVoices} = fn(opts, logger);
|
|
18
18
|
|
|
19
19
|
if (!process.env.NUANCE_CLIENT_ID || !process.env.NUANCE_SECRET ) {
|
|
20
|
-
t.pass('skipping Nuance test since no Nuance client_id and secret provided');
|
|
20
|
+
t.pass('skipping Nuance hosted test since no Nuance client_id and secret provided');
|
|
21
21
|
t.end();
|
|
22
22
|
client.quit();
|
|
23
23
|
return;
|
|
@@ -31,8 +31,39 @@ test('Nuance tests', async(t) => {
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
let voices = await getTtsVoices(opts);
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
t.ok(voices.length > 0 && voices[0].language,
|
|
35
|
+
`GetVoices: successfully retrieved ${voices.length} voices from Nuance`);
|
|
36
|
+
|
|
37
|
+
await client.flushallAsync();
|
|
38
|
+
|
|
39
|
+
t.end();
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(err);
|
|
44
|
+
t.end(err);
|
|
45
|
+
}
|
|
46
|
+
client.quit();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('Nuance on-prem tests', async(t) => {
|
|
50
|
+
const fn = require('..');
|
|
51
|
+
const {client, getTtsVoices} = fn(opts, logger);
|
|
52
|
+
|
|
53
|
+
if (!process.env.NUANCE_TTS_URI ) {
|
|
54
|
+
t.pass('skipping Nuance on-prem test since no Nuance uri provided');
|
|
55
|
+
t.end();
|
|
56
|
+
client.quit();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const opts = {
|
|
61
|
+
vendor: 'nuance',
|
|
62
|
+
credentials: {
|
|
63
|
+
nuance_tts_uri: process.env.NUANCE_TTS_URI
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
let voices = await getTtsVoices(opts);
|
|
36
67
|
t.ok(voices.length > 0 && voices[0].language,
|
|
37
68
|
`GetVoices: successfully retrieved ${voices.length} voices from Nuance`);
|
|
38
69
|
|
package/test/synth.js
CHANGED
|
@@ -212,7 +212,7 @@ test('Azure custom voice speech synth tests', async(t) => {
|
|
|
212
212
|
client.quit();
|
|
213
213
|
});
|
|
214
214
|
|
|
215
|
-
test('Nuance speech synth tests', async(t) => {
|
|
215
|
+
test('Nuance hosted speech synth tests', async(t) => {
|
|
216
216
|
const fn = require('..');
|
|
217
217
|
const {synthAudio, client} = fn(opts, logger);
|
|
218
218
|
|
|
@@ -251,6 +251,43 @@ test('Nuance speech synth tests', async(t) => {
|
|
|
251
251
|
client.quit();
|
|
252
252
|
});
|
|
253
253
|
|
|
254
|
+
test('Nuance on-prem speech synth tests', async(t) => {
|
|
255
|
+
const fn = require('..');
|
|
256
|
+
const {synthAudio, client} = fn(opts, logger);
|
|
257
|
+
|
|
258
|
+
if (!process.env.NUANCE_TTS_URI) {
|
|
259
|
+
t.pass('skipping Nuance on prem speech synth tests since NUANCE_TTS_URI not provided');
|
|
260
|
+
return t.end();
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
let opts = await synthAudio(stats, {
|
|
264
|
+
vendor: 'nuance',
|
|
265
|
+
credentials: {
|
|
266
|
+
nuance_tts_uri: process.env.NUANCE_TTS_URI
|
|
267
|
+
},
|
|
268
|
+
language: 'en-US',
|
|
269
|
+
voice: 'Evan',
|
|
270
|
+
text: 'This is a test of on-prem. This is only a test',
|
|
271
|
+
});
|
|
272
|
+
t.ok(!opts.servedFromCache, `successfully synthesized nuance audio to ${opts.filePath}`);
|
|
273
|
+
|
|
274
|
+
opts = await synthAudio(stats, {
|
|
275
|
+
vendor: 'nuance',
|
|
276
|
+
credentials: {
|
|
277
|
+
nuance_tts_uri: process.env.NUANCE_TTS_URI
|
|
278
|
+
},
|
|
279
|
+
language: 'en-US',
|
|
280
|
+
voice: 'Evan',
|
|
281
|
+
text: 'This is a test of on-prem. This is only a test',
|
|
282
|
+
});
|
|
283
|
+
t.ok(opts.servedFromCache, `successfully retrieved nuance audio from cache ${opts.filePath}`);
|
|
284
|
+
} catch (err) {
|
|
285
|
+
console.error(err);
|
|
286
|
+
t.end(err);
|
|
287
|
+
}
|
|
288
|
+
client.quit();
|
|
289
|
+
});
|
|
290
|
+
|
|
254
291
|
test('Nvidia speech synth tests', async(t) => {
|
|
255
292
|
const fn = require('..');
|
|
256
293
|
const {synthAudio, client} = fn(opts, logger);
|