问题
function floatTo16BitPCM(output, offset, input){
for (var i = 0; i < input.length; i++, offset+=2){
var s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
}
function writeString(view, offset, string){
for (var i = 0; i < string.length; i++){
view.setUint8(offset + i, string.charCodeAt(i));
}
}
function encodeWAV(samples){
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
/* RIFF identifier */
writeString(view, 0, 'RIFF');
/* RIFF chunk length */
view.setUint32(4, 36 + samples.length * 2, true);
/* RIFF type */
writeString(view, 8, 'WAVE');
/* format chunk identifier */
writeString(view, 12, 'fmt ');
/* format chunk length */
view.setUint32(16, 16, true);
/* sample format (raw) */
view.setUint16(20, 1, true);
/* channel count */
view.setUint16(22, 2, true);
/* sample rate */
view.setUint32(24, sampleRate, true);
/* byte rate (sample rate * block align) */
view.setUint32(28, sampleRate * 4, true);
/* block align (channel count * bytes per sample) */
view.setUint16(32, 4, true);
/* bits per sample */
view.setUint16(34, 16, true);
/* data chunk identifier */
writeString(view, 36, 'data');
/* data chunk length */
view.setUint32(40, samples.length * 2, true);
floatTo16BitPCM(view, 44, samples);
return view;
}
Hi, I am using this source code to record audio for my school exam. It records audio in 44100Hz and 16bit. I want to change recording settings to record audio in 16000Hz and 16bit. I tried modify 44 in function encodeWAV to 16 but it didn't work.
function encodeWAV(samples){
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer)
Also I have tried to change floadRToBitPCM. I tried to change 44 to 16 but it also didn't work.
floatTo16BitPCM(view, 44, samples);
Can you help me with this issue?? I don't know how to modify this source code.
回答1:
I do not believe you can control sample rate using Web Audio API ... it picks up the system default sample rate which is defined outside the browser ... of course subsequent to recording, you can programmatically alter your audio to resample to any sample rate ... Most audio players can only play media of standard sample rates ... being able to render an off sample rate of 16 kHz might be more challenging than resampling from 44.1 to 16 kHz
回答2:
Edit:
Another option(much better one IMO) is just to go for the HTML's MediaRecorder and record in .ogg
format, demo, and it's git repo
I am assuming that you are using this as the source, and like jaket said, the line floatTo16BitPCM(view, 44, samples);
has nothing to do with sampling rate...
if you want to resample the data, you have modify this:
function exportWAV(type){
var buffers = [];
for (var channel = 0; channel < numChannels; channel++){
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
if (numChannels === 2){
var interleaved = interleave(buffers[0], buffers[1]);
} else {
var interleaved = buffers[0];
}
var dataview = encodeWAV(interleaved);
var audioBlob = new Blob([dataview], { type: type });
this.postMessage(audioBlob);
}
into this:
function exportWAV(type, desiredSamplingRate){
var buffers = [];
for (var channel = 0; channel < numChannels; channel++){
var buffer = mergeBuffers(recBuffers[channel], recLength);
buffer = interpolateArray(buffer, desiredSamplingRate, sampleRate);
buffers.push(buffer);
}
sampleRate = desiredSamplingRate;
if (numChannels === 2){
var interleaved = interleave(buffers[0], buffers[1]);
} else {
var interleaved = buffers[0];
}
var dataview = encodeWAV(interleaved);
var audioBlob = new Blob([dataview], { type: type });
this.postMessage(audioBlob);
}
code for re-sampling data,
// for changing the sampling rate, data,
function interpolateArray(data, newSampleRate, oldSampleRate) {
var fitCount = Math.round(data.length*(newSampleRate/oldSampleRate));
var newData = new Array();
var springFactor = new Number((data.length - 1) / (fitCount - 1));
newData[0] = data[0]; // for new allocation
for ( var i = 1; i < fitCount - 1; i++) {
var tmp = i * springFactor;
var before = new Number(Math.floor(tmp)).toFixed();
var after = new Number(Math.ceil(tmp)).toFixed();
var atPoint = tmp - before;
newData[i] = this.linearInterpolate(data[before], data[after], atPoint);
}
newData[fitCount - 1] = data[data.length - 1]; // for new allocation
return newData;
};
function linearInterpolate(before, after, atPoint) {
return before + (after - before) * atPoint;
};
Edit: if you not going to change it too much, you can just hard code it as
function exportWAV(type){
var buffers = [], desiredSamplingRate = 16000;
回答3:
You are modifying the wrong field. A wave file is a header followed by the data. The wave header is typically 44 bytes long. The value of 44
you are seeing in the sample code is related to that and not to 44100
.
Somewhere in code you have not posted, sampleRate
is defined to be 44100. You need to track down that definition and change it to 16000. Depending on the rest of your code and the source of the samples it may not be quite that simple though. For example, if samples are being recorded from a device and the device has been configured to record at 44100 then simply marking the saved waveform as 16000 is not going to have the desired effect. It's just going to make playback 2.75x too slow aka the Barry White effect.
回答4:
You can change the init function like this, here you can overcome the default browser sample rate to 16000 and also the channels indicating the mono/stereo we can change that one also , if it is mono it will be 1 , other wise two .
function init(config) {
//sampleRate = config.sampleRate;
sampleRate = 16000;
debugger;
//numChannels = config.numChannels;
numChannels = 1;
initBuffers();
}
来源:https://stackoverflow.com/questions/28969304/record-audio-on-web-preset-16000hz-16bit