Compare commits

..
6 Commits
Author SHA1 Message Date
Dave Horton 98f679f43a 0.0.16 2023-07-19 10:04:17 -04:00
Dave Horton 7e7841b5ff Merge pull request #23 from jambonz/feature/trim-silence
trim trailing silence from azure tts when JAMBONES_TTS_TRIM_SILENCE i…
2023-07-19 10:03:42 -04:00
Dave Horton 75ce537db1 linting 2023-07-19 10:02:10 -04:00
Dave Horton 830be783b8 trim trailing silence from azure tts when JAMBONES_TTS_TRIM_SILENCE is set 2023-07-19 10:00:31 -04:00
Dave Horton 38c3219425 Merge pull request #21 from jambonz/snyk-fix-255777535fcb48b70c964213f7dd9fe8
[Snyk] Security upgrade @aws-sdk/client-polly from 3.303.0 to 3.347.1
2023-06-07 13:09:27 -04:00
snyk-bot e37b96a9c2 fix: package.json & package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-FASTXMLPARSER-5668858
2023-06-07 15:35:04 +00:00
3 changed files with 1011 additions and 873 deletions
+31 -3
View File
@@ -33,6 +33,24 @@ const debug = require('debug')('jambonz:realtimedb-helpers');
const EXPIRES = (process.env.JAMBONES_TTS_CACHE_DURATION_MINS || 4 * 60) * 60; // cache tts for 4 hours const EXPIRES = (process.env.JAMBONES_TTS_CACHE_DURATION_MINS || 4 * 60) * 60; // cache tts for 4 hours
const TMP_FOLDER = '/tmp'; const TMP_FOLDER = '/tmp';
const trimTrailingSilence = (buffer) => {
assert.ok(buffer instanceof Buffer, 'trimTrailingSilence - argument is not a Buffer');
let offset = buffer.length;
while (offset > 0) {
// Get 16-bit value from the buffer (read in reverse)
const value = buffer.readUInt16BE(offset - 2);
if (value !== 0) {
break;
}
offset -= 2;
}
// Trim the silence from the end
return offset === buffer.length ? buffer : buffer.subarray(0, offset);
};
/** /**
* Synthesize speech to an mp3 file, and also cache the generated speech * Synthesize speech to an mp3 file, and also cache the generated speech
* in redis (base64 format) for 24 hours so as to avoid unnecessarily paying * in redis (base64 format) for 24 hours so as to avoid unnecessarily paying
@@ -104,7 +122,12 @@ async function synthAudio(client, logger, stats, { account_sid,
text text
}); });
let filePath; let filePath;
if (['nuance', 'nvidia'].includes(vendor)) { if (['nuance', 'nvidia'].includes(vendor) ||
(
process.env.JAMBONES_TTS_TRIM_SILENCE &&
['microsoft', 'azure'].includes(vendor)
)
) {
filePath = `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt || ''}`)}.r8`; filePath = `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt || ''}`)}.r8`;
} }
else filePath = `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt || ''}`)}.mp3`; else filePath = `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt || ''}`)}.mp3`;
@@ -284,6 +307,7 @@ const synthMicrosoft = async(logger, {
}) => { }) => {
try { try {
const {api_key: apiKey, region, use_custom_tts, custom_tts_endpoint} = credentials; const {api_key: apiKey, region, use_custom_tts, custom_tts_endpoint} = credentials;
const trimSilence = filePath.endsWith('.r8');
let content = text; let content = text;
const speechConfig = SpeechConfig.fromSubscription(apiKey, region); const speechConfig = SpeechConfig.fromSubscription(apiKey, region);
speechConfig.speechSynthesisLanguage = language; speechConfig.speechSynthesisLanguage = language;
@@ -297,7 +321,9 @@ const synthMicrosoft = async(logger, {
*/ */
if (!content.startsWith('<speak')) content = `<speak>${text}</speak>`; if (!content.startsWith('<speak')) content = `<speak>${text}</speak>`;
} }
speechConfig.speechSynthesisOutputFormat = SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3; speechConfig.speechSynthesisOutputFormat = trimSilence ?
SpeechSynthesisOutputFormat.Raw8Khz16BitMonoPcm :
SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
const synthesizer = new SpeechSynthesizer(speechConfig); const synthesizer = new SpeechSynthesizer(speechConfig);
if (content.startsWith('<speak>')) { if (content.startsWith('<speak>')) {
@@ -323,7 +349,9 @@ const synthMicrosoft = async(logger, {
reject(cancellation.errorDetails); reject(cancellation.errorDetails);
break; break;
case ResultReason.SynthesizingAudioCompleted: case ResultReason.SynthesizingAudioCompleted:
resolve(Buffer.from(result.audioData)); let buffer = Buffer.from(result.audioData);
if (trimSilence) buffer = trimTrailingSilence(buffer);
resolve(buffer);
synthesizer.close(); synthesizer.close();
stats.increment('tts.count', ['vendor:microsoft', 'accepted:yes']); stats.increment('tts.count', ['vendor:microsoft', 'accepted:yes']);
break; break;
+978 -868
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@jambonz/speech-utils", "name": "@jambonz/speech-utils",
"version": "0.0.15", "version": "0.0.16",
"description": "TTS-related speech utilities for jambonz", "description": "TTS-related speech utilities for jambonz",
"main": "index.js", "main": "index.js",
"author": "Dave Horton", "author": "Dave Horton",
@@ -24,7 +24,7 @@
}, },
"homepage": "https://github.com/jambonz/speech-utils#readme", "homepage": "https://github.com/jambonz/speech-utils#readme",
"dependencies": { "dependencies": {
"@aws-sdk/client-polly": "^3.303.0", "@aws-sdk/client-polly": "^3.347.1",
"@google-cloud/text-to-speech": "^4.2.1", "@google-cloud/text-to-speech": "^4.2.1",
"@grpc/grpc-js": "^1.8.13", "@grpc/grpc-js": "^1.8.13",
"bent": "^7.3.12", "bent": "^7.3.12",