@jambonz/speech-utils 1.0.14 → 1.0.16

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.
@@ -941,8 +941,9 @@ const synthInworld = async(logger, {
941
941
  params += `,voice=${voice}`;
942
942
  params += `,write_cache_file=${disableTtsCache ? 0 : 1}`;
943
943
  if (opts.temperature) params += `,temperature=${opts.temperature}`;
944
- if (opts.audioConfig?.pitch) params += `,pitch=${opts.pitch}`;
945
- if (opts.audioConfig?.speakingRate) params += `,speakingRate=${opts.speakingRate}`;
944
+ /* pitch and speakingRate are nested under audioConfig, matching Inworld's API */
945
+ if (opts.audioConfig?.pitch) params += `,pitch=${opts.audioConfig.pitch}`;
946
+ if (opts.audioConfig?.speakingRate) params += `,speakingRate=${opts.audioConfig.speakingRate}`;
946
947
  params += '}';
947
948
 
948
949
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jambonz/speech-utils",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "TTS-related speech utilities for jambonz",
5
5
  "main": "index.js",
6
6
  "author": "Dave Horton",
@@ -25,7 +25,6 @@
25
25
  },
26
26
  "homepage": "https://github.com/jambonz/speech-utils#readme",
27
27
  "dependencies": {
28
- "23": "^0.0.0",
29
28
  "@aws-sdk/client-polly": "^3.496.0",
30
29
  "@aws-sdk/client-sts": "^3.496.0",
31
30
  "@cartesia/cartesia-js": "^2.2.7",
package/test/synth.js CHANGED
@@ -1147,6 +1147,69 @@ test('inworld speech synth', async(t) => {
1147
1147
  client.quit();
1148
1148
  });
1149
1149
 
1150
+ test('inworld streaming say: params', async(t) => {
1151
+ /* This test asserts the streaming say: path, so it must run with streaming
1152
+ enabled. The Google non-streaming test above sets
1153
+ JAMBONES_DISABLE_TTS_STREAMING and, on its no-credentials skip path,
1154
+ deletes the env var WITHOUT clearing the require cache — so lib/config can
1155
+ still be holding 'true' by the time we get here. Re-require to be
1156
+ independent of what ran before us.
1157
+ */
1158
+ delete process.env.JAMBONES_DISABLE_TTS_STREAMING;
1159
+ delete require.cache[require.resolve('../lib/config')];
1160
+ delete require.cache[require.resolve('../lib/synth-audio')];
1161
+ delete require.cache[require.resolve('..')];
1162
+
1163
+ const fn = require('..');
1164
+ const {synthAudio, client} = fn(opts, logger);
1165
+
1166
+ if (!process.env.INWORLD_API_KEY) {
1167
+ t.pass('skipping inworld streaming say: param tests since INWORLD_API_KEY is not provided');
1168
+ client.quit();
1169
+ return t.end();
1170
+ }
1171
+
1172
+ try {
1173
+ let result = await synthAudio(stats, {
1174
+ vendor: 'inworld',
1175
+ credentials: {api_key: process.env.INWORLD_API_KEY, model_id: 'inworld-tts-1.5-mini'},
1176
+ language: 'en',
1177
+ voice: 'Ashley',
1178
+ text: 'This is a test of inworld streaming.',
1179
+ options: {temperature: 0.9, audioConfig: {pitch: 2.5, speakingRate: 1.2}},
1180
+ disableTtsCache: true
1181
+ });
1182
+ t.ok(result.filePath.startsWith('say:'), 'inworld returns streaming say: path');
1183
+ t.ok(result.filePath.includes('vendor=inworld'), 'streaming path contains vendor=inworld');
1184
+ t.ok(result.filePath.includes('voice=Ashley'), 'streaming path contains voice');
1185
+ t.ok(result.filePath.includes('model_id=inworld-tts-1.5-mini'), 'streaming path contains model_id');
1186
+ t.ok(result.filePath.includes('temperature=0.9'), 'streaming path contains temperature');
1187
+ /* pitch and speakingRate are nested under audioConfig; they used to be read
1188
+ from the top level and emitted as "undefined"
1189
+ */
1190
+ t.ok(result.filePath.includes('speakingRate=1.2'), 'audioConfig.speakingRate reaches the say: params');
1191
+ t.ok(result.filePath.includes('pitch=2.5'), 'audioConfig.pitch reaches the say: params');
1192
+ t.ok(!result.filePath.includes('undefined'), 'no undefined values in the say: params');
1193
+
1194
+ /* options omitted entirely: no stray keys */
1195
+ result = await synthAudio(stats, {
1196
+ vendor: 'inworld',
1197
+ credentials: {api_key: process.env.INWORLD_API_KEY, model_id: 'inworld-tts-1.5-mini'},
1198
+ language: 'en',
1199
+ voice: 'Ashley',
1200
+ text: 'This is a test of inworld streaming.',
1201
+ disableTtsCache: true
1202
+ });
1203
+ t.ok(!result.filePath.includes('speakingRate='), 'speakingRate omitted when unset');
1204
+ t.ok(!result.filePath.includes('pitch='), 'pitch omitted when unset');
1205
+ t.ok(!result.filePath.includes('undefined'), 'no undefined values when options are omitted');
1206
+ } catch (err) {
1207
+ console.error(JSON.stringify(err));
1208
+ t.end(err);
1209
+ }
1210
+ client.quit();
1211
+ });
1212
+
1150
1213
  test('resemble speech synth', async(t) => {
1151
1214
  const fn = require('..');
1152
1215
  const {synthAudio, client} = fn(opts, logger);