Why some .wav files cannot be decoded in Firefox

I have a web page that for some reason decodes wave files. Chrome and Safari seem to be working fine. Firefox sometimes cannot decode the file and gives an error: "The buffer passed to decodeAudioData contains invalid content that cannot be decoded successfully." I created jsfiddle which illustrates the problem:

var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); var source; function getData() { source = audioCtx.createBufferSource(); request = new XMLHttpRequest(); request.open('GET', 'https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav', true); request.responseType = 'arraybuffer'; request.onload = function() { var audioData = request.response; audioCtx.decodeAudioData(audioData, function(buffer) { source.buffer = buffer; source.connect(audioCtx.destination); }, function(e){"Error with decoding audio data" + e.err}); } request.send(); } getData(); source.start(0); 

Can someone tell me what the problem is, and is there any way around it? Thank you very much.

EDIT Thanks to the significant contribution of Michael Cheney, I was able to implement some javascript that processes the wave so that it can be played in Firefox. The code truncates any part of the "fmt" fragment to 16 bytes. Code located at jfiddle

 var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); var source; function getData() { source = audioCtx.createBufferSource(); request = new XMLHttpRequest(); request.open('GET', 'https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav', true); request.responseType = 'arraybuffer'; request.onload = function() { var audioData = request.response; var dv = new DataView(audioData); var junk = 0; var position = 12; do { var header = String.fromCharCode.apply(null, Uint8Array(audioData, position, 4)); var length = dv.getUint32(position + 4, true); if (header.trim() === 'fmt') { junk = junk + length - 16; } position = position + 8 + length; }while(position < audioData.byteLength); var productArray = new Uint8Array(audioData.byteLength - junk); productArray.set(new Uint8Array(audioData, 0, 12)); var newPosition = 12; position = 12; var fmt_length_spot; do { var header = String.fromCharCode.apply(null, Uint8Array(audioData, position, 4)); var length = dv.getUint32(position + 4, true); if (header.trim() === 'fmt') { productArray.set(new Uint8Array(audioData, position, 24), newPosition); fmt_length_spot = newPosition + 4; newPosition = newPosition + 24; } else { productArray.set(new Uint8Array(audioData, position, length + 8), newPosition); newPosition = newPosition + 8 + length; } position = position + 8 + length; }while(position < audioData.byteLength); audioData = productArray.buffer; dv = new DataView(audioData); dv.setUint32(4, audioData.byteLength - 8, true); dv.setUint32(fmt_length_spot, 16, true); audioCtx.decodeAudioData(audioData, function(buffer) { source.buffer = buffer; source.connect(audioCtx.destination); }, function(e){"Error with decoding audio data" + e.err}); } request.send(); } getData(); source.start(0); 

Thanks Michael.

+3
source share
3 answers

This may be a JUNK fragment at the beginning of the file. You can run it through sox to clear foreign pieces as follows:

 sox Malice_Bass.wav Malice_Bass_simple.wav 

Here is what my personal parser says about the file:

 RIFF - WAVE (36467192 bytes) JUNK (92) bext (602) Description: Originator: Pro Tools Originator Ref: jicj!dad1ofaaaGk Origination Date: 2014-09-09 Origination Time: 20:46:43 Time Ref Low: 0 Time Ref High: 0 BWF Version: 0 SMPTE UMID Bytes: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Coding History: fmt (40) Format Tag: 1 Channels: 2 Samples per sec: 48000 Avg bytes per sec: 192000 Block align: 4 Bits per sample: 16 minf (16) elm1 (214) data (36466048) regn (92) umid (24) 

When I clean it with sox, Firefox closes, complaining about it, but still doesn't play. I confirmed that it downloads the file but does not seem to play it.

+2
source

This wav file is disabled for the first 20 seconds. I just downloaded:

 wget https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav 

I tried to use chrome, and the violin was silent, initially I thought because of the fact I just use speakers for laptops. FFT, using courage, speaks of its very low frequencies, starting with 20 seconds of silence.

The Web Audio API uses a standard computer sampling rate, which is usually 44.1 kHz. Since the file uses 48 kHz, is this your machine configured with a 48 kHz interrupt frequency? If you reformat this file from 48 kHz to 44.1 kHz, which is a typical computer sampling rate, it will probably work.

+1
source

I recently had this problem with the fact that Firefox did not read wav files using the api browser audio browser and found out that the problem lies in the bit depth of the audio file, which must not exceed 16 bits in order to be recognized by Firefox. I also found out that this is an 8 year old Firefox bug that is pretty amazing ( https://bugzilla.mozilla.org/show_bug.cgi?id=524109 )

My soul was to downgrade any wav files with 32-bit depth to 16 bits through the sox command line, for example: sox input.wav -b 16 output.wav. Obviously, you can use ffmpeg or any other application that can do this under Linux. Hope this helps.

0
source

All Articles