8
votes

I am receiving an interleaved 16 bit PCM samples over the wire. Each sample is signed

I read it as Int16bit array, lets call this ALL_DATA. So each of the array entries is a a 16 bit sample.

Because it is interleaved I extract it into 2 channels R-L-R-L I end up with 2 (16 bit) arrays half the size of ALL_DATA array.

After that I go over each sample and normalize it to Float32Array because that is what web audio API uses.

var normalizedSample= (sample > 0) ? sample / 32768 : sample / -32768;

Is this the right way to do it.

I am getting distorted sounds. You can tell what is going on. So literally if you are listening to classic guitar it sounds like it is electric with distortion.

For Arguments sake I am putting down the example code but This code handles

MONO SOUND to make the example simpler, so we don't have to interleave it as well

var startTime = 0;
     var fileReader = new FileReader();
     fileReader.onload = function (e) {
                        var data = new DataView(e.target.result);

                    var audio = new Int16Array(data.byteLength / Int16Array.BYTES_PER_ELEMENT);
                    var len = audio.length;
                    for (var jj = 0; jj < len; ++jj) {
                        audio[jj] = data.getInt16(jj * Int16Array.BYTES_PER_ELEMENT, true);
                    }

                    var right = new Float32Array(audio.length);

                    var channleCounter = 0;
                    for (var i = 0; i < audio.length; ) {
                        var normalizedRight = (audio[i] > 0) ? audio[i] / 32768 : audio[i] / -32768;

                        i = i + 1;
                        right[channleCounter] = normalizedRight;

                        channleCounter++;
                    }






                    var source = audioContext.createBufferSource();


                    var audioBuffer = audioContext.createBuffer(1, right.length, 44100);
                    audioBuffer.getChannelData(0).set(right);


                    source.buffer = audioBuffer;


                    source.connect(audioContext.destination);

                    source.noteOn(startTime);
                    startTime += audioBuffer.duration;

                };

Any suggestions that might be causing the distorted sound will help. I have written the pcm data before I send it on the server side to a file is good and sound is perfect.

1
Your post FINALLY made me get Audio working... Thanks a ton for posting your efforts, it made my audio near crystal clear now :)olealgo
Here you mentioned that you have used MONO sound to make it simple. I am trying to do it with Stereo sound. Do you know how to do it?vishal patel

1 Answers

16
votes

Instead of saying

var normalizedSample= (sample > 0) ? sample / 32768 : sample / -32768;

try

var normalizedSample= sample / 32768;

Your calculation, as currently written, will invert the negative portions of your waveform, in a manner similar to a full-wave rectifier (your samples will always be positive numbers).

enter image description here