如何在nodejs中使用nvidia jarvis tts
How to use nvidia jarvis tts in nodejs
我正在尝试将 python jarvis tts 示例转换为 nodejs。
我可以从 jarvis 取回音频,但播放时噪音很大
在 python 示例中,他们使用 16 位作为位深度,但在相同的情况下,我在节点上获得非常拉伸的音频。
音频是未压缩的 16 位带符号小端样本(线性 PCM)。据我从他们的原型文件中了解到
datalen = len(resp.audio) // 4
data32 = np.ndarray(buffer=resp.audio, dtype=np.float32, shape=(datalen, 1))
data16 = np.int16(data32 * 23173.26) # / 1.414 * 32767.0)
speech = bytes(data16.data)
print(speech)
我曾尝试将类型化数组转换为 float32array,然后再转换为 int16array,但没有成功。
从 python 实现听起来不错,但从节点来看它有太多噪音。
传递给 tts grpc 的参数在两者上是相同的。
编辑:
我能够使用此代码以 16 位深度以最小噪音播放音频。但还是有一些干扰。
this.ttsClient.Synthesize(SynthesizeSpeechRequest, (err, resp) => {
console.log(err);
const b16 = new Float32Array(resp.audio.length / 4);
const v = new DataView(resp.audio.buffer);
for (let i = 0; i < resp.audio.byteLength; i += 4) {
const element = v.getFloat32(i);
b16[i / 4] = element;
}
let l = b16.length;
const buf = new Int16Array(l);
while (l--) {
const s = Math.max(-1, Math.min(1, b16[l]));
buf[l] = s < 0 ? s * 0x8000 : s * 0x7fff;
// buf[l] = s[l] * 0x7fff; //old //convert to 16 bit
}
buf.map((x) => x * 23173.26);
console.log("buf", buf);
// // // new Int16Array().BYTES_PER_ELEMENT
cb(Buffer.from(buf.buffer));
});
我能够通过使用 readFloatLE 而不是数据视图来读取来解决这个问题。
this.ttsClient.Synthesize(SynthesizeSpeechRequest, (err, resp) => {
if (err) console.log(err);
const b16 = new Float32Array(Math.floor(resp.audio.length));
for (let i = 0; i < resp.audio.byteLength; i += 4) {
const element = resp.audio.readFloatLE(i);
b16[i / 4] = element;
}
let l = b16.length;
const buf = new Uint16Array(l);
while (l--) {
const s = Math.max(-1, Math.min(1, b16[l]));
buf[l] = s < 0 ? s * 0x8000 : s * 0x7fff;
}
b16.map((x) => x * 23173.26);
cb(Buffer.from(buf.buffer));
});
我正在尝试将 python jarvis tts 示例转换为 nodejs。 我可以从 jarvis 取回音频,但播放时噪音很大
在 python 示例中,他们使用 16 位作为位深度,但在相同的情况下,我在节点上获得非常拉伸的音频。
音频是未压缩的 16 位带符号小端样本(线性 PCM)。据我从他们的原型文件中了解到
datalen = len(resp.audio) // 4
data32 = np.ndarray(buffer=resp.audio, dtype=np.float32, shape=(datalen, 1))
data16 = np.int16(data32 * 23173.26) # / 1.414 * 32767.0)
speech = bytes(data16.data)
print(speech)
我曾尝试将类型化数组转换为 float32array,然后再转换为 int16array,但没有成功。
从 python 实现听起来不错,但从节点来看它有太多噪音。
传递给 tts grpc 的参数在两者上是相同的。
编辑:
我能够使用此代码以 16 位深度以最小噪音播放音频。但还是有一些干扰。
this.ttsClient.Synthesize(SynthesizeSpeechRequest, (err, resp) => {
console.log(err);
const b16 = new Float32Array(resp.audio.length / 4);
const v = new DataView(resp.audio.buffer);
for (let i = 0; i < resp.audio.byteLength; i += 4) {
const element = v.getFloat32(i);
b16[i / 4] = element;
}
let l = b16.length;
const buf = new Int16Array(l);
while (l--) {
const s = Math.max(-1, Math.min(1, b16[l]));
buf[l] = s < 0 ? s * 0x8000 : s * 0x7fff;
// buf[l] = s[l] * 0x7fff; //old //convert to 16 bit
}
buf.map((x) => x * 23173.26);
console.log("buf", buf);
// // // new Int16Array().BYTES_PER_ELEMENT
cb(Buffer.from(buf.buffer));
});
我能够通过使用 readFloatLE 而不是数据视图来读取来解决这个问题。
this.ttsClient.Synthesize(SynthesizeSpeechRequest, (err, resp) => {
if (err) console.log(err);
const b16 = new Float32Array(Math.floor(resp.audio.length));
for (let i = 0; i < resp.audio.byteLength; i += 4) {
const element = resp.audio.readFloatLE(i);
b16[i / 4] = element;
}
let l = b16.length;
const buf = new Uint16Array(l);
while (l--) {
const s = Math.max(-1, Math.min(1, b16[l]));
buf[l] = s < 0 ? s * 0x8000 : s * 0x7fff;
}
b16.map((x) => x * 23173.26);
cb(Buffer.from(buf.buffer));
});