首页 > 解决方案 > 如何在nodejs中使用nvidia jarvis tts

问题描述

我正在尝试将 python jarvis tts 示例转换为 nodejs。我可以从 jarvis 取回音频,但是播放时噪音很大

在 python 示例中,他们使用 16bit 作为位深度,但同样的 im 在节点上得到非常拉伸的音频。

音频是未压缩的 16 位签名 little-endian 样本(线性 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));
            });

标签: node.jsaudiotext-to-speechpcmtyped-arrays

解决方案


我能够通过使用 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));
            });

推荐阅读