0

I am receiving a raw data wave file from server, and I need to play this array of bytes on the client side.

I tried to use decodeAudioData like in this link but i got the error :

DOMException : Unable to decode Audio data.

It is logical because my raw data is not a regular mp3 file, it is a wave that needs to be played with 8000Hz rate and 1 channel and 16bits per sample.

Is there a function to play a byte array received from server with a certain rate and a number of channels

Community
  • 1
  • 1
Mehdi Souregi
  • 3,153
  • 5
  • 36
  • 53
  • doesn't the function in that sample do it for you? From my limited understanding admittedly, but it looks like `audioContext.createBuffer(1, numberOfSamples, sampleRate);` can be called with whatever rate and samples you like? I don't see that it not being MP3 is relevant, because the example you linked to is about WAV already? – ADyson May 19 '17 at 15:18
  • i've read that the exception Unable to decode Audio data happens when decodeAudioData does not know the format of the file, it only works properly with mp3 format. And for createBuffer method i've already read about it , i did not find where i can put my array to play it, do you have an example ? – Mehdi Souregi May 19 '17 at 15:27
  • Hmm, in the accepted solution to that question (admittedly not using the createBuffer function I mentioned), http://stackoverflow.com/a/24194252/5947043, it states "I call playByteArray and pass it a byte array containing pcm wav data." So clearly it can be possible to do this. That answer is 5 years old though. Firstly we should be using AudioContext instead of webkitAudioContext. See https://developer.mozilla.org/en/docs/Web/API/AudioContext - there might be some info in there about the exact supported formats, rates etc, but at a basic level WAV _is_ supported. – ADyson May 19 '17 at 15:40

1 Answers1

2

I managed to play the bytes on browser using this method :

function playWave(byteArray) {
    var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    var myAudioBuffer = audioCtx.createBuffer(1, byteArray.length, 8000);
    var nowBuffering = myAudioBuffer.getChannelData(0);
    for (var i = 0; i < byteArray.length; i++) {
        nowBuffering[i] = byteArray[i];
    }

    var source = audioCtx.createBufferSource();
    source.buffer = myAudioBuffer;
    source.connect(audioCtx.destination);
    source.start();
}
Mehdi Souregi
  • 3,153
  • 5
  • 36
  • 53
  • Hi Mehdi. Are you sending the wave file as is from the server or are you omitting the header info and just sending the audio part? – Farhan Ahmed Wasim Feb 12 '19 at 19:55
  • 1
    I don't use the header info at all, but lately I changed the method myAudioBuffer.getChannelData() to using audioCtx.decodeAudioData(data, function() {}) and this method needs data with header info, so I had to construct the header info (on client side) before using the decodeAudioData() – Mehdi Souregi Feb 14 '19 at 12:21