Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clicking sounds in Stream played with Web Audio Api

I have a strange Problem. I'm using Web Audio to play a stream from the server. I do that the following way:

 var d2 = new DataView(evt.data);

var data = new Float32Array(d2.byteLength / Float32Array.BYTES_PER_ELEMENT);
for (var jj = 0; jj < data.length; ++jj) {
    data[jj] = d2.getFloat32(jj * Float32Array.BYTES_PER_ELEMENT, true);
}

var buffer = context.createBuffer(1, data.length, 44100);
buffer.getChannelData(0).set(data);

source = context.createBufferSource();
source.buffer = buffer;
source.start(startTime);
source.connect(context.destination);

startTime += buffer.duration;

This works fine. If i play the stream on my Computer i don't have any problems.

If i play the same stream on my Windows 8 tablet (same Chrome version) i have a lot of clicking sounds in the audio. There are multiple of them within one second. It kinda seams that on the end of each buffer i hear a click.

I don't understand the difference... The only difference i could find was that the samplingrate of the soundcard on my computer is 44100 and on the tablet it's 48000.

The transmitted stream is in 44100 and i don't have any samplerate problems. just the clicking sounds.

Does anybody have an idea why this is happening?

Thank you, metabolic

like image 613
metabolic Avatar asked Nov 01 '22 09:11

metabolic


2 Answers

AudioBufferSourceNode resample their buffers to the AudioContext samplerate. As you can imagine, the API does not allow you to keep the resampler state between one AudioBufferSourceNode and the other, so there is a discontinuity between the two buffers.

I think the easiest way is to provide a stream at the sample-rate of the device, by resampling server-side. When the AudioWorkerNode will be ready and implemented, you'll be able to fix this yourself as well client side, but it's not.

Alternatively also you can just stream using an element, and pipe that to Web Audio API using AudioContext.createMediaElementSource().

like image 83
padenot Avatar answered Nov 09 '22 05:11

padenot


I had the same issue, thanks to Padenot's answer I checked the sample rates. AudioContext.sampleRate defaulted to 44100, but the PCM data and AudioBuffer was 48000. Initialising the AudioContext with a matching sampleRate solved the problem:

var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioCtx = new AudioContext({
  latencyHint: 'interactive',
  sampleRate: 48000,
});

With this, I can schedule the playback of 20ms 48khz PCM16 AudioBuffers back-to-back without any clicks or distortion.

like image 37
bain Avatar answered Nov 09 '22 06:11

bain