@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.
Files changed (2) hide show
  1. package/lib/synth-audio.js +46 -44
  2. package/package.json +1 -1
@@ -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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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, {credentials, stats, voice, text, renderForCaching, disableTtsStreaming}) => {
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
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=${playbackIdCounter++}`;
1353
+ params += `,playback_id=${key}`;
1352
1354
  params += ',vendor=resemble';
1353
1355
  params += `,voice=${voice}`;
1354
1356
  params += ',write_cache_file=1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jambonz/speech-utils",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "TTS-related speech utilities for jambonz",
5
5
  "main": "index.js",
6
6
  "author": "Dave Horton",