@jambonz/speech-utils 0.2.1 → 0.2.3

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.
@@ -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, text}) {
28
+ {account_sid, vendor, language, voice, deploymentId, engine, model, text}) {
29
29
  let key;
30
30
  logger = logger || noopLogger;
31
31
 
@@ -36,6 +36,7 @@ async function addFileToCache(client, logger, path,
36
36
  language: language || '',
37
37
  voice: voice || deploymentId,
38
38
  engine,
39
+ model,
39
40
  text,
40
41
  });
41
42
  const [extension, sampleRate] = getExtensionAndSampleRate(path);
@@ -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, text} = {all: true}) {
15
+ language, voice, deploymentId, engine, model, text} = {all: true}) {
16
16
  logger = logger || noopLogger;
17
17
 
18
18
  let purgedCount = 0, error;
@@ -33,6 +33,7 @@ async function purgeTtsCache(client, logger, {all, account_sid, vendor,
33
33
  language: language || '',
34
34
  voice: voice || deploymentId,
35
35
  engine,
36
+ model,
36
37
  text,
37
38
  });
38
39
  purgedCount = await client.del(key);
@@ -169,6 +169,8 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
169
169
  language: language || '',
170
170
  voice: voice || deploymentId,
171
171
  engine,
172
+ // model or model_id is used to identify the tts cache.
173
+ model: model || credentials.model_id,
172
174
  text
173
175
  });
174
176
 
@@ -924,7 +926,7 @@ const synthPlayHT = async(client, logger, {
924
926
  };
925
927
 
926
928
  const synthRimelabs = async(logger, {
927
- credentials, options, stats, voice, text, renderForCaching, disableTtsStreaming
929
+ credentials, options, stats, language, voice, text, renderForCaching, disableTtsStreaming
928
930
  }) => {
929
931
  const {api_key, model_id, options: credOpts} = credentials;
930
932
  const opts = !!options && Object.keys(options).length !== 0 ? options : JSON.parse(credOpts || '{}');
@@ -935,6 +937,7 @@ const synthRimelabs = async(logger, {
935
937
  params += `{api_key=${api_key}`;
936
938
  params += `,model_id=${model_id}`;
937
939
  params += ',vendor=rimelabs';
940
+ params += `,language=${language}`;
938
941
  params += `,voice=${voice}`;
939
942
  params += ',write_cache_file=1';
940
943
  if (opts.speedAlpha) params += `,speed_alpha=${opts.speedAlpha}`;
@@ -960,6 +963,7 @@ const synthRimelabs = async(logger, {
960
963
  text,
961
964
  modelId: model_id,
962
965
  samplingRate: sampleRate,
966
+ lang: language,
963
967
  ...opts
964
968
  });
965
969
  return {
package/lib/utils.js CHANGED
@@ -17,9 +17,16 @@ const debug = require('debug')('jambonz:realtimedb-helpers');
17
17
  //const nuanceClientMap = new Map();
18
18
 
19
19
  function makeSynthKey({
20
- account_sid = '', vendor, language, voice, engine = '', text}) {
20
+ account_sid = '',
21
+ vendor,
22
+ language,
23
+ voice,
24
+ engine = '',
25
+ model = '',
26
+ text
27
+ }) {
21
28
  const hash = crypto.createHash('sha1');
22
- hash.update(`${language}:${vendor}:${voice}:${engine}:${text}`);
29
+ hash.update(`${language}:${vendor}:${voice}:${engine}:${model}:${text}`);
23
30
  const hexHashKey = hash.digest('hex');
24
31
  const accountKey = account_sid ? `:${account_sid}` : '';
25
32
  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.1",
3
+ "version": "0.2.3",
4
4
  "description": "TTS-related speech utilities for jambonz",
5
5
  "main": "index.js",
6
6
  "author": "Dave Horton",
package/test/synth.js CHANGED
@@ -5,7 +5,7 @@ const fs = require('fs');
5
5
  const {makeSynthKey} = require('../lib/utils');
6
6
  const logger = require('pino')();
7
7
  const bent = require('bent');
8
- const getJSON = bent('json')
8
+ const getJSON = bent('json');
9
9
 
10
10
  process.on('unhandledRejection', (reason, p) => {
11
11
  console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
@@ -720,7 +720,7 @@ test('Cartesia speech synth tests', async(t) => {
720
720
  client.quit();
721
721
  });
722
722
 
723
- test('rimelabs speech synth tests', async(t) => {
723
+ test('rimelabs speech synth tests mist', async(t) => {
724
724
  const fn = require('..');
725
725
  const {synthAudio, client} = fn(opts, logger);
726
726
 
@@ -730,7 +730,7 @@ test('rimelabs speech synth tests', async(t) => {
730
730
  }
731
731
  const text = 'Hi there and welcome to jambones!';
732
732
  try {
733
- let opts = await synthAudio(stats, {
733
+ const opts = await synthAudio(stats, {
734
734
  vendor: 'rimelabs',
735
735
  credentials: {
736
736
  api_key: process.env.RIMELABS_API_KEY,
@@ -740,7 +740,7 @@ test('rimelabs speech synth tests', async(t) => {
740
740
  reduceLatency: false
741
741
  })
742
742
  },
743
- language: 'en-US',
743
+ language: 'eng',
744
744
  voice: 'amber',
745
745
  text,
746
746
  renderForCaching: true
@@ -754,6 +754,40 @@ test('rimelabs speech synth tests', async(t) => {
754
754
  client.quit();
755
755
  });
756
756
 
757
+ test('rimelabs speech synth tests mistv2', async(t) => {
758
+ const fn = require('..');
759
+ const {synthAudio, client} = fn(opts, logger);
760
+
761
+ if (!process.env.RIMELABS_API_KEY) {
762
+ t.pass('skipping rimelabs speech synth tests since RIMELABS_API_KEY is not provided');
763
+ return t.end();
764
+ }
765
+ const text = 'Hi there and welcome to jambones!';
766
+ try {
767
+ const opts = await synthAudio(stats, {
768
+ vendor: 'rimelabs',
769
+ credentials: {
770
+ api_key: process.env.RIMELABS_API_KEY,
771
+ model_id: 'mistv2',
772
+ options: JSON.stringify({
773
+ speedAlpha: 1.0,
774
+ reduceLatency: false
775
+ })
776
+ },
777
+ language: 'spa',
778
+ voice: 'pablo',
779
+ text,
780
+ renderForCaching: true
781
+ });
782
+ t.ok(!opts.servedFromCache, `successfully synthesized rimelabs mistv2 audio to ${opts.filePath}`);
783
+
784
+ } catch (err) {
785
+ console.error(JSON.stringify(err));
786
+ t.end(err);
787
+ }
788
+ client.quit();
789
+ });
790
+
757
791
  test('whisper speech synth tests', async(t) => {
758
792
  const fn = require('..');
759
793
  const {synthAudio, client} = fn(opts, logger);
@@ -853,11 +887,11 @@ test('TTS Cache tests', async(t) => {
853
887
  // save some random tts keys to cache
854
888
  const minRecords = 8;
855
889
  for (const i in Array(minRecords).fill(0)) {
856
- await client.set(makeSynthKey({vendor: i, language: i, voice: i, engine: i, text: i}), i);
890
+ await client.set(makeSynthKey({vendor: i, language: i, voice: i, engine: i, model: i, text: i}), i);
857
891
  }
858
892
  const count = await getTtsSize();
859
893
  t.ok(count >= minRecords, 'getTtsSize worked.');
860
-
894
+
861
895
  const {purgedCount} = await purgeTtsCache();
862
896
  t.ok(purgedCount >= minRecords, `successfully purged at least ${minRecords} tts records from cache`);
863
897