为什么这会降低音频质量?

时间:2016-09-02 19:05:11

标签: javascript audio flask pack flask-socketio

我正在将烧录应用程序中的音频从客户端传输到服务器,但收到的音频质量非常低。

在客户端上,我按如下方式预处理音频缓冲区:

this.node.onaudioprocess = function(e){
      var buf = e.inputBuffer.getChannelData(0);
      var out = new Int16Array(buf.length);
      for (var i = 0; i < buf.length; i++){
        var s = Math.max(-1, Math.min(1, buf[i]));
        out[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
      }
      socket.emit('audio event',{data: out})
      return;
}

在服务器端,我收到如下音频:

audio_file = open('tempfile.raw', 'w')

@socketio.on('audio event')
def audio_message(message):
    dat = [v[1] for v in sorted(message['data'].iteritems())]
    n = len(dat)
    byteval = struct.pack('<'+str(n)+'h',*dat)
    audio_file.write(byteval)

但由此产生的音频听起来很金属,中断且嘈杂。以下是结果波形的外观:

received wave sample

在我的代码中,音频质量丢失了吗?如何在没有质量损失的情况下传输音频?

1 个答案:

答案 0 :(得分:2)

我对你如何处理音频的第一印象是它实时工作太慢了。

在客户端上,你遍历每一个样本,应用边界检查(你真的需要这样做吗?)然后从float32转换为int16格式,对每个单独的样本应用条件和乘法。

然后在服务器端,你会在每个样本中进行另一个循环,只是为了将样本放入一个列表中(不是数据已经作为列表出现给你了吗?)。然后才将该列表打包成一个写入磁盘的二进制数组。

编写缓冲区需要做很多工作,你可能会丢失数据。

我建议您尝试以下操作:删除所有转换,看看是否可以使用本机float32格式获取流经系统的数据。使用socket.io,您可以发送直接从客户端打包的float32数据。 Haven没有对此进行过测试,但我相信socket.emit('audio event',{data: buf.buffer})将直接发送二进制有效负载而不进行客户端转换。然后在服务器上,message['data']将是一个二进制有效负载,您可以直接写入磁盘。要检查数据是否正常,可以使用“导入原始”对话框中的32位浮点选项来使用audacity。

一旦你的原始float32数据工作,如果你需要另一种格式的数据,你可以看到添加转换(希望只在一个地方)仍然允许你维持实时。我怀疑你可能需要在C / C ++中对这种转换进行编码,因为Python对于这种类型的东西来说太慢了。如果你走这条路,看看Cython可能是个好主意。