2016-03-09 3 views
0

Я пытаюсь передать аудио через websocket на node.js (express) сервере в веб-браузер. Звук поступает с устройства iOS в виде 16-битных, монофонических wav-файлов, отснятых с частотой 4 тыс. (4000 выборок в секунду).Web Audio API - Live Stream 'клики' между кусками.

Вот мой код: Код

Сервер:

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) Почему декодированный звук воспроизводится в два раза быстрее, чем я ожидаю? Является ли частота дискретизации 4k слишком низкой для API веб-аудио? Почему я не могу декодировать 32-битные wav?

2) У меня есть опыт работы с цифровыми звуковыми рабочими станциями (способный, логический), и я знаю, что звуки щелчка могут возникать, если волна «перескакивает» из образца обратно вниз на ноль или наоборот (то есть: начало/конец синусоидальной волны в разгар фазы). Это то, что здесь происходит? Есть ли способ обойти это? Кроссфейдинг каждого отдельного образца кажется глупым. Почему не каждый кусок, где последний остановился?

ответ

1

1) Звук, который я получал, был на самом деле в 2k по ошибке, но заголовок wav все еще сказал 4k, таким образом, ошибка двойной скорости.

2) См последний абзац Chris Wilsons answer here:

Наконец - это не будет хорошо работать, если звук поток не соответствует частота дискретизации аудио по умолчанию устройства в; всегда будут клики, потому что decodeAudioData будет пересчитывать скорость устройства, которая не будет иметь идеальной продолжительности. Он будет работать, но, скорее всего, будут артефакты, такие как клики на границах кусков. Вам нужна функция, которая еще не реализована или реализована - выбираемые частоты выборки AudioContext - чтобы исправить это.

Brion Vibbers AudioFeeder.js отлично работает без каких-либо щелчков, Также будьте настороже: upsampling artifacts!

-1

Другой вариант: Вы можете использовать MediaSource API преодолеть эти затруднения между звуком.

Если вам нужны полные исследования по этому вопросу, используйте это: MSE for Audio