Decrease bitrate in WAV file created with recorderjs

I try to use recorderjs on the application engine website, where users upload short sound recordings (say, from 1 to tens of seconds). I noticed that the WAV files that I upload are much larger than I expected. For example, I just created a record that lasts about 9 seconds, and the downloaded block is 1736769 bytes, which is> 1.5 megabytes.

Question:

How can I change the recorderjs code (or my own code - maybe I'm using recorderjs incorrectly) so that my audio cables have a lower bitrate? I would like a 10 second recording to be safely below 1 MB.

I assume that I will need to change the encodeWAV function to here or maybe exportWAV, but I'm not sure how to do this. Does it make sense to simply discard every other element of the interleaved buffer in exportWAV? Is there a smarter way to do this? How does the bitrate of the exported WAV depend on the properties of my computer (for example, the sampling rate of my sound card)?

I can add some details of my own code if this can be useful.

Edit: if you want to see a live example, install the google chrome beta and try this page . On my computer, a recording lasting 5-10 seconds is more than 1 MB.

Many thanks,

Adrian

+8
html5 audio wav audio-recording
source share
3 answers

You can try a couple of things. Firstly, I think you want to say something about "deleting every other element of the interleaved buffer" (converting sound to mono).

To do this, you can save the left or right channel. You can change the rotation function:

function interleave(inputL, inputR){ return inputL; // or inputR } 

If you want to keep both channels, but β€œpan” them both centers (on a single mono channel), you can do something like:

 function interleave(inputL, inputR){ var result = new Float32Array(inputL.length); for (var i = 0; i < inputL.length; ++i) result[i] = 0.5 * (inputL[i] + inputR[i]); return result; } 

However, there are potentially many others hosted; you will have to change the encoded sound, denoting stereo for mono. However, I assume that (and I did not use recorder.js, so I do not know its internal actions), line 113/114 in recorderWorker would probably change to 1.

My assumption is that you could just change the two places mentioned here (the interlace function and the place where the channel counter is installed [line 114]), because: interleave and encodeWAV are only called through the exportWAV function, so without touching as the original worker was a recording sound (and he recorded stereo), we hope we will not break it. In this case, we would only make changes to the stored sound.

+4
source share

In my case, Chrome records audio at 96 kHz and Firefox at 44.1 kHz, which makes huge WAV files. I implemented the downsampling function inside recorderWorker.js, where you can select the desired sampling rate, for example 16000.

 function downsampleBuffer(buffer, rate) { if (rate == sampleRate) { return buffer; } if (rate > sampleRate) { throw "downsampling rate show be smaller than original sample rate"; } var sampleRateRatio = sampleRate / rate; var newLength = Math.round(buffer.length / sampleRateRatio); var result = new Float32Array(newLength); var offsetResult = 0; var offsetBuffer = 0; while (offsetResult < result.length) { var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio); var accum = 0, count = 0; for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) { accum += buffer[i]; count++; } result[offsetResult] = accum / count; offsetResult++; offsetBuffer = nextOffsetBuffer; } return result; } 

and I call it when exporting a wav file:

 function exportWAV(rate, type) { var bufferL = mergeBuffers(recBuffersL, recLength); var bufferR = mergeBuffers(recBuffersR, recLength); var interleaved = interleave(bufferL, bufferR); var downsampledBuffer = downsampleBuffer(interleaved, rate); var dataview = encodeWAV(rate, downsampledBuffer, false); var audioBlob = new Blob([ dataview ], { type : type }); this.postMessage(audioBlob); } 
+18
source share

I use the same recorder code and I need to lower the transfer speed. My solution creates a mono file of 11025 Hz. it is not very elegant, so I will be glad if someone has corrections for me.

First, I change the sampling rate in the init function to 11025 instead of the bit rate of the audio content (this is not an elegant part, since the context may not be 44100 Hz).

I replace the contents of the interleave function with this

 var length = inputL.length / 4; var result = new Float32Array(length); var index = 0, inputIndex = 0; while (index < length) { result[index++] = 0.25 * (inputL[inputIndex++] + inputL[inputIndex++] + inputL[inputIndex++] + inputL[inputIndex++]); } return result; 

This only takes the left channel and turns every 4 buffer samples into 1 as a result, so it takes up less memory. if the bit rate changes by the same factor (divided by 4, for example, 11025), the file will sound the same, but it will be much smaller.

I also changed the number of channels in encodeWAV to one

 /* channel count */ view.setUint16(22, 1, true); 

The record will be 1/8 compared to the originally created file.

+3
source share

All Articles