网络音频API - 实时流在块之间点击。
我正在尝试通过一个node.js(express)服务器上的websocket将音频流式传输到Web浏览器。音频来自iOS设备,是以4k采样的16位单声道wav文件(每秒4000个采样点)。网络音频API - 实时流在块之间点击。
这里是我的代码:
服务器代码:
webSocketServer.on('connection', function connection(client) {
client.on('message', function(message) {
webSocketServer.clients.forEach(function each(connection) {
connection.send(message, { binary: true }
);
});
});
客户端代码:
webSocket = new WebSocket('ws://' + window.location.hostname + ':8080/');
webSocket.binaryType = 'arraybuffer'
webSocket.onmessage = function(message) {
var arrayBuffer = message.data // wav from server, as arraybuffer
var source = audioContext.createBufferSource();
audioContext.decodeAudioData(arrayBuffer, function(buffer){
source.buffer = buffer
source.connect(audioContext.destination)
source.start(time);
time += source.buffer.duration
}, function(){
console.log('error')
})
};
decodeAudioData()
似乎是工作,但它返回的音频缓冲器半我是长期待。 (例如,4000个样本只会给我0.5秒的音频,我原本以为这是因为wav是16位而不是32,但切换到32导致decodeAudioData()
触发它的错误回调。添加到成功回调:
source.playbackRate.value = 0.5 // play at half speed
time += source.buffer.duration * 2 // double duration
这得到定时工作完美,但我留下了一个问题:有一个听得见的“咔嗒”或音频数据块之间的“流行”间隔出后。大约一秒(time += (source.buffer.duration * 2) + 1
),我能够发现点击发生在每个块的最开始处。
所以我的主要两个头部划痕是:
1)为什么解码音频播放速度是我所期望的两倍?对于Web Audio API,我的采样率是否过低?为什么我无法解码32位wav?
2)我对数字音频工作站(ableton,逻辑)有一些经验,我知道如果一个波从样本回落到零或反之亦然(即:开始/结束一个正弦波在一个阶段中)。这是怎么回事?有没有办法解决这个问题?将每个单独的样本交叉淡化似乎很愚蠢。为什么每个组块拾取的最后一个都没有停止?
1)我收到的音频实际上是在2k的错误,但wav头仍然说4k,因此双倍速度的错误。
2)见Chris Wilsons answer here最后一段:
最后 - 这是行不通的好,如果声音流不匹配默认音频设备的采样率;总会有点击,因为decodeAudioData将重新采样到设备速率,这将不会有一个完美的持续时间。它会起作用,但是可能会有大块的边界处的点击等工件。您需要一个尚未指定或实现的功能 - 可选的AudioContext采样率 - 以解决此问题。
Brion Vibbers AudioFeeder.js很好的工作,没有任何点击,但需要原始的32位pcm数据。也要警惕upsampling artifacts!