@jambonz/speech-utils 0.2.21 → 0.2.23
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/synth-audio.js +46 -44
- package/package.json +1 -1
package/lib/synth-audio.js
CHANGED
|
@@ -53,9 +53,6 @@ const EXPIRES = JAMBONES_TTS_CACHE_DURATION_MINS;
|
|
|
53
53
|
const OpenAI = require('openai');
|
|
54
54
|
const getAwsAuthToken = require('./get-aws-sts-token');
|
|
55
55
|
|
|
56
|
-
/* counter for playback id */
|
|
57
|
-
let playbackIdCounter = 0;
|
|
58
|
-
|
|
59
56
|
const trimTrailingSilence = (buffer) => {
|
|
60
57
|
assert.ok(buffer instanceof Buffer, 'trimTrailingSilence - argument is not a Buffer');
|
|
61
58
|
|
|
@@ -207,74 +204,74 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
207
204
|
const startAt = process.hrtime();
|
|
208
205
|
switch (vendor) {
|
|
209
206
|
case 'google':
|
|
210
|
-
audioData = await synthGoogle(logger, {credentials, stats, language, voice, gender, text});
|
|
207
|
+
audioData = await synthGoogle(logger, {credentials, stats, language, voice, gender, key, text});
|
|
211
208
|
break;
|
|
212
209
|
case 'aws':
|
|
213
210
|
case 'polly':
|
|
214
211
|
vendorLabel = 'aws';
|
|
215
212
|
audioData = await synthPolly(createHash, retrieveHash, logger,
|
|
216
|
-
{credentials, stats, language, voice, text, engine, renderForCaching, disableTtsStreaming});
|
|
213
|
+
{credentials, stats, language, voice, key, text, engine, renderForCaching, disableTtsStreaming});
|
|
217
214
|
break;
|
|
218
215
|
case 'azure':
|
|
219
216
|
case 'microsoft':
|
|
220
217
|
vendorLabel = 'microsoft';
|
|
221
|
-
audioData = await synthMicrosoft(logger, {credentials, stats, language, voice, text, deploymentId,
|
|
218
|
+
audioData = await synthMicrosoft(logger, {credentials, stats, language, voice, key, text, deploymentId,
|
|
222
219
|
renderForCaching, disableTtsStreaming});
|
|
223
220
|
break;
|
|
224
221
|
case 'nuance':
|
|
225
222
|
model = model || 'enhanced';
|
|
226
|
-
audioData = await synthNuance(client, logger, {credentials, stats, voice, model, text});
|
|
223
|
+
audioData = await synthNuance(client, logger, {credentials, stats, voice, model, key, text});
|
|
227
224
|
break;
|
|
228
225
|
case 'nvidia':
|
|
229
|
-
audioData = await synthNvidia(client, logger, {credentials, stats, language, voice, model, text,
|
|
226
|
+
audioData = await synthNvidia(client, logger, {credentials, stats, language, voice, model, key, text,
|
|
230
227
|
renderForCaching, disableTtsStreaming});
|
|
231
228
|
break;
|
|
232
229
|
case 'ibm':
|
|
233
|
-
audioData = await synthIbm(logger, {credentials, stats, voice, text});
|
|
230
|
+
audioData = await synthIbm(logger, {credentials, stats, voice, key, text});
|
|
234
231
|
break;
|
|
235
232
|
case 'wellsaid':
|
|
236
|
-
audioData = await synthWellSaid(logger, {credentials, stats, language, voice, text});
|
|
233
|
+
audioData = await synthWellSaid(logger, {credentials, stats, language, voice, key, text});
|
|
237
234
|
break;
|
|
238
235
|
case 'elevenlabs':
|
|
239
236
|
audioData = await synthElevenlabs(logger, {
|
|
240
|
-
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming});
|
|
237
|
+
credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
|
|
241
238
|
break;
|
|
242
239
|
case 'playht':
|
|
243
240
|
audioData = await synthPlayHT(client, logger, {
|
|
244
|
-
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming});
|
|
241
|
+
credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
|
|
245
242
|
break;
|
|
246
243
|
case 'cartesia':
|
|
247
244
|
audioData = await synthCartesia(logger, {
|
|
248
|
-
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming});
|
|
245
|
+
credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
|
|
249
246
|
break;
|
|
250
247
|
case 'inworld':
|
|
251
248
|
audioData = await synthInworld(logger, {
|
|
252
|
-
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming});
|
|
249
|
+
credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
|
|
253
250
|
break;
|
|
254
251
|
case 'rimelabs':
|
|
255
252
|
audioData = await synthRimelabs(logger, {
|
|
256
|
-
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming});
|
|
253
|
+
credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
|
|
257
254
|
break;
|
|
258
255
|
case 'whisper':
|
|
259
256
|
audioData = await synthWhisper(logger, {
|
|
260
|
-
credentials, stats, voice, text, instructions, renderForCaching, disableTtsStreaming});
|
|
257
|
+
credentials, stats, voice, key, text, instructions, renderForCaching, disableTtsStreaming});
|
|
261
258
|
break;
|
|
262
259
|
case 'verbio':
|
|
263
260
|
audioData = await synthVerbio(client, logger, {
|
|
264
|
-
credentials, stats, voice, text, renderForCaching, disableTtsStreaming});
|
|
261
|
+
credentials, stats, voice, key, text, renderForCaching, disableTtsStreaming});
|
|
265
262
|
if (audioData?.filePath) return audioData;
|
|
266
263
|
break;
|
|
267
264
|
case 'deepgram':
|
|
268
|
-
audioData = await synthDeepgram(logger, {credentials, stats, model, text,
|
|
265
|
+
audioData = await synthDeepgram(logger, {credentials, stats, model, key, text,
|
|
269
266
|
renderForCaching, disableTtsStreaming});
|
|
270
267
|
break;
|
|
271
268
|
case 'resemble':
|
|
272
269
|
audioData = await synthResemble(logger, {
|
|
273
|
-
credentials, stats, voice, text, options, renderForCaching, disableTtsStreaming});
|
|
270
|
+
credentials, stats, voice, key, text, options, renderForCaching, disableTtsStreaming});
|
|
274
271
|
break;
|
|
275
272
|
case vendor.startsWith('custom') ? vendor : 'cant_match_value':
|
|
276
273
|
audioData = await synthCustomVendor(logger,
|
|
277
|
-
{credentials, stats, language, voice, text});
|
|
274
|
+
{credentials, stats, language, voice, key, text});
|
|
278
275
|
break;
|
|
279
276
|
default:
|
|
280
277
|
assert(`synthAudio: unsupported speech vendor ${vendor}`);
|
|
@@ -309,13 +306,13 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
309
306
|
}
|
|
310
307
|
|
|
311
308
|
const synthPolly = async(createHash, retrieveHash, logger,
|
|
312
|
-
{credentials, stats, language, voice, engine, text, renderForCaching, disableTtsStreaming}) => {
|
|
309
|
+
{credentials, stats, language, voice, engine, key, text, renderForCaching, disableTtsStreaming}) => {
|
|
313
310
|
const {region, accessKeyId, secretAccessKey, roleArn} = credentials;
|
|
314
311
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
315
312
|
|
|
316
313
|
let params = '{';
|
|
317
314
|
params += `language=${language}`;
|
|
318
|
-
params += `,playback_id=${
|
|
315
|
+
params += `,playback_id=${key}`;
|
|
319
316
|
params += ',write_cache_file=1';
|
|
320
317
|
params += ',vendor=aws';
|
|
321
318
|
if (accessKeyId && secretAccessKey) {
|
|
@@ -563,6 +560,7 @@ const synthMicrosoft = async(logger, {
|
|
|
563
560
|
stats,
|
|
564
561
|
language,
|
|
565
562
|
voice,
|
|
563
|
+
key,
|
|
566
564
|
text,
|
|
567
565
|
renderForCaching,
|
|
568
566
|
disableTtsStreaming
|
|
@@ -594,7 +592,7 @@ const synthMicrosoft = async(logger, {
|
|
|
594
592
|
!renderForCaching && !disableTtsStreaming) {
|
|
595
593
|
let params = '{';
|
|
596
594
|
params += `api_key=${apiKey}`;
|
|
597
|
-
params += `,playback_id=${
|
|
595
|
+
params += `,playback_id=${key}`;
|
|
598
596
|
params += `,language=${language}`;
|
|
599
597
|
params += ',vendor=microsoft';
|
|
600
598
|
params += `,voice=${voice}`;
|
|
@@ -771,13 +769,13 @@ const synthNuance = async(client, logger, {credentials, stats, voice, model, tex
|
|
|
771
769
|
};
|
|
772
770
|
|
|
773
771
|
const synthNvidia = async(client, logger, {
|
|
774
|
-
credentials, stats, language, voice, model, text, renderForCaching, disableTtsStreaming
|
|
772
|
+
credentials, stats, language, voice, model, key, text, renderForCaching, disableTtsStreaming
|
|
775
773
|
}) => {
|
|
776
774
|
const {riva_server_uri} = credentials;
|
|
777
775
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
778
776
|
let params = '';
|
|
779
777
|
params += `{riva_server_uri=${riva_server_uri}`;
|
|
780
|
-
params += `,playback_id=${
|
|
778
|
+
params += `,playback_id=${key}`;
|
|
781
779
|
params += `,voice=${voice}`;
|
|
782
780
|
params += `,language=${language}`;
|
|
783
781
|
params += ',write_cache_file=1';
|
|
@@ -851,7 +849,7 @@ const synthCustomVendor = async(logger, {credentials, stats, language, voice, te
|
|
|
851
849
|
};
|
|
852
850
|
|
|
853
851
|
const synthElevenlabs = async(logger, {
|
|
854
|
-
credentials, options, stats, voice, text, renderForCaching, disableTtsStreaming
|
|
852
|
+
credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming
|
|
855
853
|
}) => {
|
|
856
854
|
const {api_key, model_id, options: credOpts} = credentials;
|
|
857
855
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
@@ -860,12 +858,14 @@ const synthElevenlabs = async(logger, {
|
|
|
860
858
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
861
859
|
let params = '{';
|
|
862
860
|
params += `api_key=${api_key}`;
|
|
863
|
-
params += `,playback_id=${
|
|
861
|
+
params += `,playback_id=${key}`;
|
|
864
862
|
params += ',vendor=elevenlabs';
|
|
865
863
|
params += `,voice=${voice}`;
|
|
866
864
|
params += `,model_id=${model_id}`;
|
|
867
|
-
params += `,optimize_streaming_latency=${opts.optimize_streaming_latency || 2}`;
|
|
868
865
|
params += ',write_cache_file=1';
|
|
866
|
+
if (opts.optimize_streaming_latency !== null && opts.optimize_streaming_latency !== undefined) {
|
|
867
|
+
params += `,optimize_streaming_latency=${opts.optimize_streaming_latency}`;
|
|
868
|
+
}
|
|
869
869
|
if (opts.voice_settings?.similarity_boost) params += `,similarity_boost=${opts.voice_settings.similarity_boost}`;
|
|
870
870
|
if (opts.voice_settings?.stability) params += `,stability=${opts.voice_settings.stability}`;
|
|
871
871
|
if (opts.voice_settings?.style) params += `,style=${opts.voice_settings.style}`;
|
|
@@ -915,7 +915,7 @@ const synthElevenlabs = async(logger, {
|
|
|
915
915
|
};
|
|
916
916
|
|
|
917
917
|
const synthPlayHT = async(client, logger, {
|
|
918
|
-
credentials, options, stats, voice, language, text, renderForCaching, disableTtsStreaming
|
|
918
|
+
credentials, options, stats, voice, language, key, text, renderForCaching, disableTtsStreaming
|
|
919
919
|
}) => {
|
|
920
920
|
const {api_key, user_id, voice_engine, playht_tts_uri, options: credOpts} = credentials;
|
|
921
921
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
@@ -951,7 +951,7 @@ const synthPlayHT = async(client, logger, {
|
|
|
951
951
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
952
952
|
let params = '{';
|
|
953
953
|
params += `api_key=${api_key}`;
|
|
954
|
-
params += `,playback_id=${
|
|
954
|
+
params += `,playback_id=${key}`;
|
|
955
955
|
params += `,user_id=${user_id}`;
|
|
956
956
|
params += ',vendor=playht';
|
|
957
957
|
params += `,voice=${voice}`;
|
|
@@ -1010,7 +1010,7 @@ const synthPlayHT = async(client, logger, {
|
|
|
1010
1010
|
};
|
|
1011
1011
|
|
|
1012
1012
|
const synthInworld = async(logger, {
|
|
1013
|
-
credentials, options, stats, voice, text, renderForCaching, disableTtsStreaming
|
|
1013
|
+
credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming
|
|
1014
1014
|
}) => {
|
|
1015
1015
|
const {api_key, model_id, options: credOpts} = credentials;
|
|
1016
1016
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
@@ -1019,7 +1019,7 @@ const synthInworld = async(logger, {
|
|
|
1019
1019
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
1020
1020
|
let params = '{';
|
|
1021
1021
|
params += `api_key=${api_key}`;
|
|
1022
|
-
params += `,playback_id=${
|
|
1022
|
+
params += `,playback_id=${key}`;
|
|
1023
1023
|
params += `,model_id=${model_id}`;
|
|
1024
1024
|
params += ',vendor=inworld';
|
|
1025
1025
|
params += `,voice=${voice}`;
|
|
@@ -1075,7 +1075,7 @@ const synthInworld = async(logger, {
|
|
|
1075
1075
|
};
|
|
1076
1076
|
|
|
1077
1077
|
const synthRimelabs = async(logger, {
|
|
1078
|
-
credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming
|
|
1078
|
+
credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming
|
|
1079
1079
|
}) => {
|
|
1080
1080
|
const {api_key, model_id, options: credOpts} = credentials;
|
|
1081
1081
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
@@ -1084,7 +1084,7 @@ const synthRimelabs = async(logger, {
|
|
|
1084
1084
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
1085
1085
|
let params = '{';
|
|
1086
1086
|
params += `api_key=${api_key}`;
|
|
1087
|
-
params += `,playback_id=${
|
|
1087
|
+
params += `,playback_id=${key}`;
|
|
1088
1088
|
params += `,model_id=${model_id}`;
|
|
1089
1089
|
params += ',vendor=rimelabs';
|
|
1090
1090
|
params += `,language=${language}`;
|
|
@@ -1132,7 +1132,9 @@ const synthRimelabs = async(logger, {
|
|
|
1132
1132
|
throw err;
|
|
1133
1133
|
}
|
|
1134
1134
|
};
|
|
1135
|
-
const synthVerbio = async(client, logger, {
|
|
1135
|
+
const synthVerbio = async(client, logger, {
|
|
1136
|
+
credentials, stats, voice, key, text, renderForCaching, disableTtsStreaming
|
|
1137
|
+
}) => {
|
|
1136
1138
|
//https://doc.speechcenter.verbio.com/#tag/Text-To-Speech-REST-API
|
|
1137
1139
|
if (text.length > 2000) {
|
|
1138
1140
|
throw new Error('Verbio cannot synthesize for the text length larger than 2000 characters');
|
|
@@ -1141,7 +1143,7 @@ const synthVerbio = async(client, logger, {credentials, stats, voice, text, rend
|
|
|
1141
1143
|
if (!process.env.JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
1142
1144
|
let params = '{';
|
|
1143
1145
|
params += `access_token=${token.access_token}`;
|
|
1144
|
-
params += `,playback_id=${
|
|
1146
|
+
params += `,playback_id=${key}`;
|
|
1145
1147
|
params += ',vendor=verbio';
|
|
1146
1148
|
params += `,voice=${voice}`;
|
|
1147
1149
|
params += ',write_cache_file=1';
|
|
@@ -1178,14 +1180,14 @@ const synthVerbio = async(client, logger, {credentials, stats, voice, text, rend
|
|
|
1178
1180
|
}
|
|
1179
1181
|
};
|
|
1180
1182
|
|
|
1181
|
-
const synthWhisper = async(logger, {credentials, stats, voice, text, instructions,
|
|
1183
|
+
const synthWhisper = async(logger, {credentials, stats, voice, key, text, instructions,
|
|
1182
1184
|
renderForCaching, disableTtsStreaming}) => {
|
|
1183
1185
|
const {api_key, model_id, baseURL, timeout, speed} = credentials;
|
|
1184
1186
|
/* if the env is set to stream then bag out, unless we are specifically rendering to generate a cache file */
|
|
1185
1187
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
1186
1188
|
let params = '{';
|
|
1187
1189
|
params += `api_key=${api_key}`;
|
|
1188
|
-
params += `,playback_id=${
|
|
1190
|
+
params += `,playback_id=${key}`;
|
|
1189
1191
|
params += `,model_id=${model_id}`;
|
|
1190
1192
|
params += ',vendor=whisper';
|
|
1191
1193
|
params += `,voice=${voice}`;
|
|
@@ -1227,12 +1229,12 @@ const synthWhisper = async(logger, {credentials, stats, voice, text, instruction
|
|
|
1227
1229
|
}
|
|
1228
1230
|
};
|
|
1229
1231
|
|
|
1230
|
-
const synthDeepgram = async(logger, {credentials, stats, model, text, renderForCaching, disableTtsStreaming}) => {
|
|
1232
|
+
const synthDeepgram = async(logger, {credentials, stats, model, key, text, renderForCaching, disableTtsStreaming}) => {
|
|
1231
1233
|
const {api_key, deepgram_tts_uri} = credentials;
|
|
1232
1234
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
1233
1235
|
let params = '{';
|
|
1234
1236
|
params += `api_key=${api_key}`;
|
|
1235
|
-
params += `,playback_id=${
|
|
1237
|
+
params += `,playback_id=${key}`;
|
|
1236
1238
|
params += ',vendor=deepgram';
|
|
1237
1239
|
params += `,voice=${model}`;
|
|
1238
1240
|
params += ',write_cache_file=1';
|
|
@@ -1268,7 +1270,7 @@ const synthDeepgram = async(logger, {credentials, stats, model, text, renderForC
|
|
|
1268
1270
|
};
|
|
1269
1271
|
|
|
1270
1272
|
const synthCartesia = async(logger, {
|
|
1271
|
-
credentials, options, stats, voice, language, text, renderForCaching, disableTtsStreaming
|
|
1273
|
+
credentials, options, stats, voice, language, key, text, renderForCaching, disableTtsStreaming
|
|
1272
1274
|
}) => {
|
|
1273
1275
|
const {api_key, model_id, embedding, options: credOpts} = credentials;
|
|
1274
1276
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
@@ -1276,7 +1278,7 @@ const synthCartesia = async(logger, {
|
|
|
1276
1278
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
1277
1279
|
let params = '{';
|
|
1278
1280
|
params += `api_key=${api_key}`;
|
|
1279
|
-
params += `,playback_id=${
|
|
1281
|
+
params += `,playback_id=${key}`;
|
|
1280
1282
|
params += `,model_id=${model_id}`;
|
|
1281
1283
|
params += ',vendor=cartesia';
|
|
1282
1284
|
params += `,voice=${voice}`;
|
|
@@ -1339,7 +1341,7 @@ const synthCartesia = async(logger, {
|
|
|
1339
1341
|
};
|
|
1340
1342
|
|
|
1341
1343
|
const synthResemble = async(logger, {
|
|
1342
|
-
credentials, options, stats, voice, text, renderForCaching, disableTtsStreaming
|
|
1344
|
+
credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming
|
|
1343
1345
|
}) => {
|
|
1344
1346
|
const {api_key, resemble_tts_uri, resemble_tts_use_tls} = credentials;
|
|
1345
1347
|
const {project_uuid, use_hd} = options || {};
|
|
@@ -1348,7 +1350,7 @@ const synthResemble = async(logger, {
|
|
|
1348
1350
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
1349
1351
|
let params = '{';
|
|
1350
1352
|
params += `api_key=${api_key}`;
|
|
1351
|
-
params += `,playback_id=${
|
|
1353
|
+
params += `,playback_id=${key}`;
|
|
1352
1354
|
params += ',vendor=resemble';
|
|
1353
1355
|
params += `,voice=${voice}`;
|
|
1354
1356
|
params += ',write_cache_file=1';
|