为什么这会降低音频质量?
Why does this decrease the audio quality?
我在 Flask 应用程序中将音频从客户端流式传输到服务器,但接收到的音频质量很差。
在客户端,我对音频缓冲区进行了如下预处理:
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)
但生成的音频听起来金属味、断断续续且嘈杂。生成的波形如下所示:
我的代码中哪里的音频质量丢失了?如何在不损失质量的情况下流式传输音频?
我对您处理音频的方式的第一印象是实时处理太慢了。
在客户端,您遍历每个样本,应用边界检查(您真的需要这样做吗?)然后从 float32 格式转换为 int16 格式,对每个样本应用条件和乘法。
然后在服务器端对每个样本进行另一个循环,只是为了将样本放入列表中(数据不是已经以列表的形式出现了吗?)。然后才将该列表打包成二进制数组,然后写入磁盘。
仅仅写一个缓冲区就需要大量工作,您可能正在丢失数据。
以下是我建议您尝试的方法:删除所有转换并查看是否可以让数据以本机 float32 格式流经系统。使用 socket.io 您可以直接从客户端发送打包的 float32 数据。尚未对此进行测试,但我相信 socket.emit('audio event',{data: buf.buffer})
将直接发送二进制有效负载,而无需客户端转换。然后在服务器上,message['data']
将是一个二进制负载,您可以直接将其写入磁盘。要检查数据是否看起来不错,您可以使用 audacity,使用 Import Raw 对话框中的 32 位浮点数选项。
一旦您获得原始的 float32 数据,如果您需要另一种格式的数据,您可以查看添加转换(希望只在一个地方)是否仍然允许您维持实时。我怀疑您可能需要在 C/C++ 中编写此转换代码,因为 Python 对于此类事情来说太慢了。如果您正沿着这条路走下去,研究 Cython 可能是个好主意。
我在 Flask 应用程序中将音频从客户端流式传输到服务器,但接收到的音频质量很差。
在客户端,我对音频缓冲区进行了如下预处理:
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)
但生成的音频听起来金属味、断断续续且嘈杂。生成的波形如下所示:
我的代码中哪里的音频质量丢失了?如何在不损失质量的情况下流式传输音频?
我对您处理音频的方式的第一印象是实时处理太慢了。
在客户端,您遍历每个样本,应用边界检查(您真的需要这样做吗?)然后从 float32 格式转换为 int16 格式,对每个样本应用条件和乘法。
然后在服务器端对每个样本进行另一个循环,只是为了将样本放入列表中(数据不是已经以列表的形式出现了吗?)。然后才将该列表打包成二进制数组,然后写入磁盘。
仅仅写一个缓冲区就需要大量工作,您可能正在丢失数据。
以下是我建议您尝试的方法:删除所有转换并查看是否可以让数据以本机 float32 格式流经系统。使用 socket.io 您可以直接从客户端发送打包的 float32 数据。尚未对此进行测试,但我相信 socket.emit('audio event',{data: buf.buffer})
将直接发送二进制有效负载,而无需客户端转换。然后在服务器上,message['data']
将是一个二进制负载,您可以直接将其写入磁盘。要检查数据是否看起来不错,您可以使用 audacity,使用 Import Raw 对话框中的 32 位浮点数选项。
一旦您获得原始的 float32 数据,如果您需要另一种格式的数据,您可以查看添加转换(希望只在一个地方)是否仍然允许您维持实时。我怀疑您可能需要在 C/C++ 中编写此转换代码,因为 Python 对于此类事情来说太慢了。如果您正沿着这条路走下去,研究 Cython 可能是个好主意。