@jambonz/speech-utils 0.2.8 → 0.2.10
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/add-file-to-cache.js +2 -1
- package/lib/purge-tts-cache.js +2 -1
- package/lib/synth-audio.js +11 -7
- package/lib/utils.js +3 -2
- package/package.json +3 -2
- package/test/synth.js +5 -4
package/lib/add-file-to-cache.js
CHANGED
|
@@ -25,7 +25,7 @@ function getExtensionAndSampleRate(path) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async function addFileToCache(client, logger, path,
|
|
28
|
-
{account_sid, vendor, language, voice, deploymentId, engine, model, text}) {
|
|
28
|
+
{account_sid, vendor, language, voice, deploymentId, engine, model, text, instructions}) {
|
|
29
29
|
let key;
|
|
30
30
|
logger = logger || noopLogger;
|
|
31
31
|
|
|
@@ -38,6 +38,7 @@ async function addFileToCache(client, logger, path,
|
|
|
38
38
|
engine,
|
|
39
39
|
model,
|
|
40
40
|
text,
|
|
41
|
+
instructions
|
|
41
42
|
});
|
|
42
43
|
const [extension, sampleRate] = getExtensionAndSampleRate(path);
|
|
43
44
|
const audioBuffer = await fs.readFile(path);
|
package/lib/purge-tts-cache.js
CHANGED
|
@@ -12,7 +12,7 @@ const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
|
12
12
|
* @returns {object} result - {error, purgedCount}
|
|
13
13
|
*/
|
|
14
14
|
async function purgeTtsCache(client, logger, {all, account_sid, vendor,
|
|
15
|
-
language, voice, deploymentId, engine, model, text} = {all: true}) {
|
|
15
|
+
language, voice, deploymentId, engine, model, text, instructions} = {all: true}) {
|
|
16
16
|
logger = logger || noopLogger;
|
|
17
17
|
|
|
18
18
|
let purgedCount = 0, error;
|
|
@@ -35,6 +35,7 @@ async function purgeTtsCache(client, logger, {all, account_sid, vendor,
|
|
|
35
35
|
engine,
|
|
36
36
|
model,
|
|
37
37
|
text,
|
|
38
|
+
instructions
|
|
38
39
|
});
|
|
39
40
|
purgedCount = await client.del(key);
|
|
40
41
|
if (purgedCount === 0) error = 'Specified item not found';
|
package/lib/synth-audio.js
CHANGED
|
@@ -89,7 +89,7 @@ const trimTrailingSilence = (buffer) => {
|
|
|
89
89
|
*/
|
|
90
90
|
async function synthAudio(client, createHash, retrieveHash, logger, stats, { account_sid,
|
|
91
91
|
vendor, language, voice, gender, text, engine, salt, model, credentials, deploymentId,
|
|
92
|
-
disableTtsCache, renderForCaching = false, disableTtsStreaming, options
|
|
92
|
+
disableTtsCache, renderForCaching = false, disableTtsStreaming, options, instructions
|
|
93
93
|
}) {
|
|
94
94
|
let audioData;
|
|
95
95
|
let servedFromCache = false;
|
|
@@ -171,7 +171,8 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
171
171
|
engine,
|
|
172
172
|
// model or model_id is used to identify the tts cache.
|
|
173
173
|
model: model || credentials.model_id,
|
|
174
|
-
text
|
|
174
|
+
text,
|
|
175
|
+
instructions
|
|
175
176
|
});
|
|
176
177
|
|
|
177
178
|
debug(`synth key is ${key}`);
|
|
@@ -242,7 +243,7 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
242
243
|
break;
|
|
243
244
|
case 'whisper':
|
|
244
245
|
audioData = await synthWhisper(logger, {
|
|
245
|
-
credentials, stats, voice, text, renderForCaching, disableTtsStreaming});
|
|
246
|
+
credentials, stats, voice, text, instructions, renderForCaching, disableTtsStreaming});
|
|
246
247
|
break;
|
|
247
248
|
case 'verbio':
|
|
248
249
|
audioData = await synthVerbio(client, logger, {
|
|
@@ -854,11 +855,10 @@ const synthElevenlabs = async(logger, {
|
|
|
854
855
|
const synthPlayHT = async(client, logger, {
|
|
855
856
|
credentials, options, stats, voice, language, text, renderForCaching, disableTtsStreaming
|
|
856
857
|
}) => {
|
|
857
|
-
const {api_key, user_id, voice_engine, options: credOpts} = credentials;
|
|
858
|
+
const {api_key, user_id, voice_engine, playht_tts_uri, options: credOpts} = credentials;
|
|
858
859
|
const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
|
|
859
860
|
|
|
860
|
-
let synthesizeUrl = 'https://api.play.ht/api/v2/tts/stream';
|
|
861
|
-
|
|
861
|
+
let synthesizeUrl = playht_tts_uri ? `${playht_tts_uri}/api/v2/tts/stream` : 'https://api.play.ht/api/v2/tts/stream';
|
|
862
862
|
// If model is play3.0, the synthesizeUrl is got from authentication endpoint
|
|
863
863
|
if (voice_engine === 'Play3.0') {
|
|
864
864
|
try {
|
|
@@ -1048,7 +1048,8 @@ const synthVerbio = async(client, logger, {credentials, stats, voice, text, rend
|
|
|
1048
1048
|
}
|
|
1049
1049
|
};
|
|
1050
1050
|
|
|
1051
|
-
const synthWhisper = async(logger, {credentials, stats, voice, text,
|
|
1051
|
+
const synthWhisper = async(logger, {credentials, stats, voice, text, instructions,
|
|
1052
|
+
renderForCaching, disableTtsStreaming}) => {
|
|
1052
1053
|
const {api_key, model_id, baseURL, timeout, speed} = credentials;
|
|
1053
1054
|
/* if the env is set to stream then bag out, unless we are specifically rendering to generate a cache file */
|
|
1054
1055
|
if (!JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) {
|
|
@@ -1059,6 +1060,8 @@ const synthWhisper = async(logger, {credentials, stats, voice, text, renderForCa
|
|
|
1059
1060
|
params += `,voice=${voice}`;
|
|
1060
1061
|
params += ',write_cache_file=1';
|
|
1061
1062
|
if (speed) params += `,speed=${speed}`;
|
|
1063
|
+
// comma is used to separated parameters in freeswitch tts module
|
|
1064
|
+
if (instructions) params += `,instructions=${instructions.replace(/\n/g, ' ').replace(/,/g, ';')}`;
|
|
1062
1065
|
params += '}';
|
|
1063
1066
|
|
|
1064
1067
|
return {
|
|
@@ -1078,6 +1081,7 @@ const synthWhisper = async(logger, {credentials, stats, voice, text, renderForCa
|
|
|
1078
1081
|
model: model_id,
|
|
1079
1082
|
voice,
|
|
1080
1083
|
input: text,
|
|
1084
|
+
...(instructions && {instructions}),
|
|
1081
1085
|
response_format: 'mp3'
|
|
1082
1086
|
});
|
|
1083
1087
|
return {
|
package/lib/utils.js
CHANGED
|
@@ -23,10 +23,11 @@ function makeSynthKey({
|
|
|
23
23
|
voice,
|
|
24
24
|
engine = '',
|
|
25
25
|
model = '',
|
|
26
|
-
text
|
|
26
|
+
text,
|
|
27
|
+
instructions = '',
|
|
27
28
|
}) {
|
|
28
29
|
const hash = crypto.createHash('sha1');
|
|
29
|
-
hash.update(`${language}:${vendor}:${voice}:${engine}:${model}:${text}`);
|
|
30
|
+
hash.update(`${language}:${vendor}:${voice}:${engine}:${model}:${text}:${instructions}`);
|
|
30
31
|
const hexHashKey = hash.digest('hex');
|
|
31
32
|
const accountKey = account_sid ? `:${account_sid}` : '';
|
|
32
33
|
const key = `tts${accountKey}:${hexHashKey}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jambonz/speech-utils",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "TTS-related speech utilities for jambonz",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Dave Horton",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/jambonz/speech-utils#readme",
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"23": "^0.0.0",
|
|
29
30
|
"@aws-sdk/client-polly": "^3.496.0",
|
|
30
31
|
"@aws-sdk/client-sts": "^3.496.0",
|
|
31
32
|
"@cartesia/cartesia-js": "^2.1.0",
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
"google-protobuf": "^3.21.2",
|
|
39
40
|
"ibm-watson": "^8.0.0",
|
|
40
41
|
"microsoft-cognitiveservices-speech-sdk": "1.38.0",
|
|
41
|
-
"openai": "^4.
|
|
42
|
+
"openai": "^4.98.0",
|
|
42
43
|
"undici": "^7.5.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
package/test/synth.js
CHANGED
|
@@ -887,7 +887,8 @@ test('TTS Cache tests', async(t) => {
|
|
|
887
887
|
// save some random tts keys to cache
|
|
888
888
|
const minRecords = 8;
|
|
889
889
|
for (const i in Array(minRecords).fill(0)) {
|
|
890
|
-
await client.set(makeSynthKey({vendor: i, language: i, voice: i, engine: i, model: i, text: i
|
|
890
|
+
await client.set(makeSynthKey({vendor: i, language: i, voice: i, engine: i, model: i, text: i,
|
|
891
|
+
instructions: i}), i);
|
|
891
892
|
}
|
|
892
893
|
const count = await getTtsSize();
|
|
893
894
|
t.ok(count >= minRecords, 'getTtsSize worked.');
|
|
@@ -906,7 +907,7 @@ test('TTS Cache tests', async(t) => {
|
|
|
906
907
|
try {
|
|
907
908
|
// save some random tts keys to cache
|
|
908
909
|
for (const i in Array(10).fill(0)) {
|
|
909
|
-
await client.set(makeSynthKey({vendor: i, language: i, voice: i, engine: i, text: i}), i);
|
|
910
|
+
await client.set(makeSynthKey({vendor: i, language: i, voice: i, engine: i, text: i, instructions: i}), i);
|
|
910
911
|
}
|
|
911
912
|
// save a specific key to tts cache
|
|
912
913
|
const opts = {vendor: 'aws', language: 'en-US', voice: 'MALE', engine: 'Engine', text: 'Hello World!'};
|
|
@@ -944,10 +945,10 @@ test('TTS Cache tests', async(t) => {
|
|
|
944
945
|
const account_sid = "12412512_cabc_5aff"
|
|
945
946
|
const account_sid2 = "22412512_cabc_5aff"
|
|
946
947
|
for (const i in Array(minRecords).fill(0)) {
|
|
947
|
-
await client.set(makeSynthKey({account_sid, vendor: i, language: i, voice: i, engine: i, text: i}), i);
|
|
948
|
+
await client.set(makeSynthKey({account_sid, vendor: i, language: i, voice: i, engine: i, text: i, instructions: i}), i);
|
|
948
949
|
}
|
|
949
950
|
for (const i in Array(minRecords).fill(0)) {
|
|
950
|
-
await client.set(makeSynthKey({account_sid: account_sid2, vendor: i, language: i, voice: i, engine: i, text: i}), i);
|
|
951
|
+
await client.set(makeSynthKey({account_sid: account_sid2, vendor: i, language: i, voice: i, engine: i, text: i, instructions: i}), i);
|
|
951
952
|
}
|
|
952
953
|
const {purgedCount} = await purgeTtsCache({account_sid});
|
|
953
954
|
t.equal(purgedCount, minRecords, `successfully purged at least ${minRecords} tts records from cache for account_sid:${account_sid}`);
|