@jambonz/speech-utils 0.2.23 → 0.2.24

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.
@@ -210,13 +210,14 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
210
210
  case 'polly':
211
211
  vendorLabel = 'aws';
212
212
  audioData = await synthPolly(createHash, retrieveHash, logger,
213
- {credentials, stats, language, voice, key, text, engine, renderForCaching, disableTtsStreaming});
213
+ {credentials, stats, language, voice, key, text, engine, renderForCaching, disableTtsStreaming,
214
+ disableTtsCache});
214
215
  break;
215
216
  case 'azure':
216
217
  case 'microsoft':
217
218
  vendorLabel = 'microsoft';
218
219
  audioData = await synthMicrosoft(logger, {credentials, stats, language, voice, key, text, deploymentId,
219
- renderForCaching, disableTtsStreaming});
220
+ renderForCaching, disableTtsStreaming, disableTtsCache});
220
221
  break;
221
222
  case 'nuance':
222
223
  model = model || 'enhanced';
@@ -224,7 +225,7 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
224
225
  break;
225
226
  case 'nvidia':
226
227
  audioData = await synthNvidia(client, logger, {credentials, stats, language, voice, model, key, text,
227
- renderForCaching, disableTtsStreaming});
228
+ renderForCaching, disableTtsStreaming, disableTtsCache});
228
229
  break;
229
230
  case 'ibm':
230
231
  audioData = await synthIbm(logger, {credentials, stats, voice, key, text});
@@ -234,44 +235,50 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
234
235
  break;
235
236
  case 'elevenlabs':
236
237
  audioData = await synthElevenlabs(logger, {
237
- credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
238
+ credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming,
239
+ disableTtsCache});
238
240
  break;
239
241
  case 'playht':
240
242
  audioData = await synthPlayHT(client, logger, {
241
- credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
243
+ credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming,
244
+ disableTtsCache});
242
245
  break;
243
246
  case 'cartesia':
244
247
  audioData = await synthCartesia(logger, {
245
- credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
248
+ credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming,
249
+ disableTtsCache});
246
250
  break;
247
251
  case 'inworld':
248
252
  audioData = await synthInworld(logger, {
249
- credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
253
+ credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming,
254
+ disableTtsCache});
250
255
  break;
251
256
  case 'rimelabs':
252
257
  audioData = await synthRimelabs(logger, {
253
- credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming});
258
+ credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming,
259
+ disableTtsCache});
254
260
  break;
255
261
  case 'whisper':
256
262
  audioData = await synthWhisper(logger, {
257
- credentials, stats, voice, key, text, instructions, renderForCaching, disableTtsStreaming});
263
+ credentials, stats, voice, key, text, instructions, renderForCaching, disableTtsStreaming,
264
+ disableTtsCache});
258
265
  break;
259
266
  case 'verbio':
260
267
  audioData = await synthVerbio(client, logger, {
261
- credentials, stats, voice, key, text, renderForCaching, disableTtsStreaming});
268
+ credentials, stats, voice, key, text, renderForCaching, disableTtsStreaming, disableTtsCache});
262
269
  if (audioData?.filePath) return audioData;
263
270
  break;
264
271
  case 'deepgram':
265
272
  audioData = await synthDeepgram(logger, {credentials, stats, model, key, text,
266
- renderForCaching, disableTtsStreaming});
273
+ renderForCaching, disableTtsStreaming, disableTtsCache});
267
274
  break;
268
275
  case 'resemble':
269
276
  audioData = await synthResemble(logger, {
270
- credentials, stats, voice, key, text, options, renderForCaching, disableTtsStreaming});
277
+ credentials, stats, voice, key, text, options, renderForCaching, disableTtsStreaming, disableTtsCache});
271
278
  break;
272
279
  case vendor.startsWith('custom') ? vendor : 'cant_match_value':
273
280
  audioData = await synthCustomVendor(logger,
274
- {credentials, stats, language, voice, key, text});
281
+ {credentials, stats, language, voice, key, text, renderForCaching, disableTtsStreaming, disableTtsCache});
275
282
  break;
276
283
  default:
277
284
  assert(`synthAudio: unsupported speech vendor ${vendor}`);
@@ -306,14 +313,14 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
306
313
  }
307
314
 
308
315
  const synthPolly = async(createHash, retrieveHash, logger,
309
- {credentials, stats, language, voice, engine, key, text, renderForCaching, disableTtsStreaming}) => {
316
+ {credentials, stats, language, voice, engine, key, text, renderForCaching, disableTtsStreaming, disableTtsCache}) => {
310
317
  const {region, accessKeyId, secretAccessKey, roleArn} = credentials;
311
318
  if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
312
319
 
313
320
  let params = '{';
314
321
  params += `language=${language}`;
315
322
  params += `,playback_id=${key}`;
316
- params += ',write_cache_file=1';
323
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
317
324
  params += ',vendor=aws';
318
325
  if (accessKeyId && secretAccessKey) {
319
326
  if (accessKeyId) params += `,accessKeyId=${accessKeyId}`;
@@ -563,7 +570,8 @@ const synthMicrosoft = async(logger, {
563
570
  key,
564
571
  text,
565
572
  renderForCaching,
566
- disableTtsStreaming
573
+ disableTtsStreaming,
574
+ disableTtsCache
567
575
  }) => {
568
576
  try {
569
577
  const {api_key: apiKey, region, use_custom_tts, custom_tts_endpoint, custom_tts_endpoint_url} = credentials;
@@ -596,7 +604,7 @@ const synthMicrosoft = async(logger, {
596
604
  params += `,language=${language}`;
597
605
  params += ',vendor=microsoft';
598
606
  params += `,voice=${voice}`;
599
- params += ',write_cache_file=1';
607
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
600
608
  if (region) params += `,region=${region}`;
601
609
  if (custom_tts_endpoint) params += `,endpointId=${custom_tts_endpoint}`;
602
610
  if (custom_tts_endpoint_url) params += `,endpoint=${custom_tts_endpoint_url}`;
@@ -769,7 +777,7 @@ const synthNuance = async(client, logger, {credentials, stats, voice, model, tex
769
777
  };
770
778
 
771
779
  const synthNvidia = async(client, logger, {
772
- credentials, stats, language, voice, model, key, text, renderForCaching, disableTtsStreaming
780
+ credentials, stats, language, voice, model, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
773
781
  }) => {
774
782
  const {riva_server_uri} = credentials;
775
783
  if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
@@ -778,7 +786,7 @@ const synthNvidia = async(client, logger, {
778
786
  params += `,playback_id=${key}`;
779
787
  params += `,voice=${voice}`;
780
788
  params += `,language=${language}`;
781
- params += ',write_cache_file=1';
789
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
782
790
  params += '}';
783
791
 
784
792
  return {
@@ -818,9 +826,27 @@ const synthNvidia = async(client, logger, {
818
826
  };
819
827
 
820
828
 
821
- const synthCustomVendor = async(logger, {credentials, stats, language, voice, text, filePath}) => {
829
+ const synthCustomVendor = async(logger, {credentials, stats, language, voice,
830
+ text, filePath, renderForCaching, disableTtsStreaming, key, disableTtsCache}) => {
822
831
  const {vendor, auth_token, custom_tts_url} = credentials;
823
832
 
833
+ if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
834
+ let params = '{';
835
+ params += `auth_token=${auth_token}`;
836
+ params += `,playback_id=${key}`;
837
+ params += `,custom_tts_url=${custom_tts_url}`;
838
+ params += ',vendor=custom';
839
+ params += `,voice=${voice}`;
840
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
841
+ params += '}';
842
+
843
+ return {
844
+ filePath: `say:${params}${text.replace(/\n/g, ' ').replace(/\r/g, ' ')}`,
845
+ servedFromCache: false,
846
+ rtt: 0
847
+ };
848
+ }
849
+
824
850
  try {
825
851
  const post = bent('POST', {
826
852
  'Authorization': `Bearer ${auth_token}`,
@@ -849,7 +875,7 @@ const synthCustomVendor = async(logger, {credentials, stats, language, voice, te
849
875
  };
850
876
 
851
877
  const synthElevenlabs = async(logger, {
852
- credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming
878
+ credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
853
879
  }) => {
854
880
  const {api_key, model_id, options: credOpts} = credentials;
855
881
  const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
@@ -862,7 +888,7 @@ const synthElevenlabs = async(logger, {
862
888
  params += ',vendor=elevenlabs';
863
889
  params += `,voice=${voice}`;
864
890
  params += `,model_id=${model_id}`;
865
- params += ',write_cache_file=1';
891
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
866
892
  if (opts.optimize_streaming_latency !== null && opts.optimize_streaming_latency !== undefined) {
867
893
  params += `,optimize_streaming_latency=${opts.optimize_streaming_latency}`;
868
894
  }
@@ -915,7 +941,7 @@ const synthElevenlabs = async(logger, {
915
941
  };
916
942
 
917
943
  const synthPlayHT = async(client, logger, {
918
- credentials, options, stats, voice, language, key, text, renderForCaching, disableTtsStreaming
944
+ credentials, options, stats, voice, language, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
919
945
  }) => {
920
946
  const {api_key, user_id, voice_engine, playht_tts_uri, options: credOpts} = credentials;
921
947
  const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
@@ -957,7 +983,7 @@ const synthPlayHT = async(client, logger, {
957
983
  params += `,voice=${voice}`;
958
984
  params += `,voice_engine=${voice_engine}`;
959
985
  params += `,synthesize_url=${synthesizeUrl}`;
960
- params += ',write_cache_file=1';
986
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
961
987
  params += `,language=${language}`;
962
988
  if (opts.quality) params += `,quality=${opts.quality}`;
963
989
  if (opts.speed) params += `,speed=${opts.speed}`;
@@ -1010,7 +1036,7 @@ const synthPlayHT = async(client, logger, {
1010
1036
  };
1011
1037
 
1012
1038
  const synthInworld = async(logger, {
1013
- credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming
1039
+ credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
1014
1040
  }) => {
1015
1041
  const {api_key, model_id, options: credOpts} = credentials;
1016
1042
  const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
@@ -1023,7 +1049,7 @@ const synthInworld = async(logger, {
1023
1049
  params += `,model_id=${model_id}`;
1024
1050
  params += ',vendor=inworld';
1025
1051
  params += `,voice=${voice}`;
1026
- params += ',write_cache_file=1';
1052
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
1027
1053
  if (opts.temperature) params += `,temperature=${opts.temperature}`;
1028
1054
  if (opts.audioConfig?.pitch) params += `,pitch=${opts.pitch}`;
1029
1055
  if (opts.audioConfig?.speakingRate) params += `,speakingRate=${opts.speakingRate}`;
@@ -1075,7 +1101,7 @@ const synthInworld = async(logger, {
1075
1101
  };
1076
1102
 
1077
1103
  const synthRimelabs = async(logger, {
1078
- credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming
1104
+ credentials, options, stats, language, voice, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
1079
1105
  }) => {
1080
1106
  const {api_key, model_id, options: credOpts} = credentials;
1081
1107
  const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
@@ -1089,7 +1115,7 @@ const synthRimelabs = async(logger, {
1089
1115
  params += ',vendor=rimelabs';
1090
1116
  params += `,language=${language}`;
1091
1117
  params += `,voice=${voice}`;
1092
- params += ',write_cache_file=1';
1118
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
1093
1119
  if (opts.speedAlpha) params += `,speed_alpha=${opts.speedAlpha}`;
1094
1120
  if (opts.reduceLatency) params += `,reduce_latency=${opts.reduceLatency}`;
1095
1121
  // Arcana model parameters
@@ -1133,7 +1159,7 @@ const synthRimelabs = async(logger, {
1133
1159
  }
1134
1160
  };
1135
1161
  const synthVerbio = async(client, logger, {
1136
- credentials, stats, voice, key, text, renderForCaching, disableTtsStreaming
1162
+ credentials, stats, voice, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
1137
1163
  }) => {
1138
1164
  //https://doc.speechcenter.verbio.com/#tag/Text-To-Speech-REST-API
1139
1165
  if (text.length > 2000) {
@@ -1146,7 +1172,7 @@ const synthVerbio = async(client, logger, {
1146
1172
  params += `,playback_id=${key}`;
1147
1173
  params += ',vendor=verbio';
1148
1174
  params += `,voice=${voice}`;
1149
- params += ',write_cache_file=1';
1175
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
1150
1176
  params += '}';
1151
1177
 
1152
1178
  return {
@@ -1181,7 +1207,7 @@ const synthVerbio = async(client, logger, {
1181
1207
  };
1182
1208
 
1183
1209
  const synthWhisper = async(logger, {credentials, stats, voice, key, text, instructions,
1184
- renderForCaching, disableTtsStreaming}) => {
1210
+ renderForCaching, disableTtsStreaming, disableTtsCache}) => {
1185
1211
  const {api_key, model_id, baseURL, timeout, speed} = credentials;
1186
1212
  /* if the env is set to stream then bag out, unless we are specifically rendering to generate a cache file */
1187
1213
  if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
@@ -1191,7 +1217,7 @@ const synthWhisper = async(logger, {credentials, stats, voice, key, text, instru
1191
1217
  params += `,model_id=${model_id}`;
1192
1218
  params += ',vendor=whisper';
1193
1219
  params += `,voice=${voice}`;
1194
- params += ',write_cache_file=1';
1220
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
1195
1221
  if (speed) params += `,speed=${speed}`;
1196
1222
  // comma is used to separated parameters in freeswitch tts module
1197
1223
  if (instructions) params += `,instructions=${instructions.replace(/\n/g, ' ').replace(/,/g, ';')}`;
@@ -1229,7 +1255,8 @@ const synthWhisper = async(logger, {credentials, stats, voice, key, text, instru
1229
1255
  }
1230
1256
  };
1231
1257
 
1232
- const synthDeepgram = async(logger, {credentials, stats, model, key, text, renderForCaching, disableTtsStreaming}) => {
1258
+ const synthDeepgram = async(logger, {credentials, stats, model, key, text, renderForCaching,
1259
+ disableTtsStreaming, disableTtsCache}) => {
1233
1260
  const {api_key, deepgram_tts_uri} = credentials;
1234
1261
  if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
1235
1262
  let params = '{';
@@ -1237,7 +1264,7 @@ const synthDeepgram = async(logger, {credentials, stats, model, key, text, rende
1237
1264
  params += `,playback_id=${key}`;
1238
1265
  params += ',vendor=deepgram';
1239
1266
  params += `,voice=${model}`;
1240
- params += ',write_cache_file=1';
1267
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
1241
1268
  if (deepgram_tts_uri) params += `,endpoint=${deepgram_tts_uri}`;
1242
1269
  params += '}';
1243
1270
 
@@ -1270,7 +1297,7 @@ const synthDeepgram = async(logger, {credentials, stats, model, key, text, rende
1270
1297
  };
1271
1298
 
1272
1299
  const synthCartesia = async(logger, {
1273
- credentials, options, stats, voice, language, key, text, renderForCaching, disableTtsStreaming
1300
+ credentials, options, stats, voice, language, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
1274
1301
  }) => {
1275
1302
  const {api_key, model_id, embedding, options: credOpts} = credentials;
1276
1303
  const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
@@ -1282,7 +1309,7 @@ const synthCartesia = async(logger, {
1282
1309
  params += `,model_id=${model_id}`;
1283
1310
  params += ',vendor=cartesia';
1284
1311
  params += `,voice=${voice}`;
1285
- params += ',write_cache_file=1';
1312
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
1286
1313
  params += `,language=${language}`;
1287
1314
  params += `,voice_mode=${embedding ? 'embedding' : 'id'}`;
1288
1315
  if (embedding) params += `,embedding=${embedding}`;
@@ -1341,7 +1368,7 @@ const synthCartesia = async(logger, {
1341
1368
  };
1342
1369
 
1343
1370
  const synthResemble = async(logger, {
1344
- credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming
1371
+ credentials, options, stats, voice, key, text, renderForCaching, disableTtsStreaming, disableTtsCache
1345
1372
  }) => {
1346
1373
  const {api_key, resemble_tts_uri, resemble_tts_use_tls} = credentials;
1347
1374
  const {project_uuid, use_hd} = options || {};
@@ -1353,7 +1380,7 @@ const synthResemble = async(logger, {
1353
1380
  params += `,playback_id=${key}`;
1354
1381
  params += ',vendor=resemble';
1355
1382
  params += `,voice=${voice}`;
1356
- params += ',write_cache_file=1';
1383
+ params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
1357
1384
  if (project_uuid) params += `,project_uuid=${project_uuid}`;
1358
1385
  if (use_hd) params += `,use_hd=${use_hd}`;
1359
1386
  if (resemble_tts_uri) params += `,endpoint=${resemble_tts_uri}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jambonz/speech-utils",
3
- "version": "0.2.23",
3
+ "version": "0.2.24",
4
4
  "description": "TTS-related speech utilities for jambonz",
5
5
  "main": "index.js",
6
6
  "author": "Dave Horton",
package/test/synth.js CHANGED
@@ -554,6 +554,7 @@ test('Custom Vendor speech synth tests', async(t) => {
554
554
  language: 'en-US',
555
555
  voice: 'English-US.Female-1',
556
556
  text: 'This is a test. This is only a test',
557
+ renderForCaching: true
557
558
  });
558
559
  t.ok(!opts.servedFromCache, `successfully synthesized custom vendor audio to ${opts.filePath}`);
559
560
  t.ok(opts.filePath.endsWith('wav'), 'audio is cached as wav file');
@@ -575,6 +576,7 @@ test('Custom Vendor speech synth tests', async(t) => {
575
576
  language: 'en-US',
576
577
  voice: 'English-US.Female-1',
577
578
  text: 'This is a test. This is only a test',
579
+ renderForCaching: true
578
580
  });
579
581
  t.ok(opts.servedFromCache, `successfully get custom vendor cached audio to ${opts.filePath}`);
580
582
  t.ok(opts.filePath.endsWith('wav'), 'audio is cached as wav file');
@@ -589,6 +591,7 @@ test('Custom Vendor speech synth tests', async(t) => {
589
591
  language: 'en-US',
590
592
  voice: 'English-US.Female-1',
591
593
  text: '<speak>This is a test. This is only a test</speak>',
594
+ renderForCaching: true
592
595
  });
593
596
  t.ok(!opts.servedFromCache, `successfully synthesized Custom Vendor audio to ${opts.filePath}`);
594
597
  obj = await getJSON(`http://127.0.0.1:3100/lastRequest/somethingnew2`);