如何在 nodejs 中使用 nvidia jarvis tts

问题描述

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

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

音频是未压缩的 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 实现中听起来不错,但从 node 中它有太多的噪音。

传递给 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));
            });