Запись аудио в Интернете, предустановка: 16000 Гц 16 бит

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.********(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.*********(4, 36 + samples.length * 2, true);
 /* RIFF type */
 writeString(view, 8, 'WAVE');
 /* format chunk identifier */
 writeString(view, 12, 'fmt ');
 /* format chunk length */
 view.*********(16, 16, true);
 /* sample format (raw) */
 view.setUint16(20, 1, true);
 /* channel count */
 view.setUint16(22, 2, true);
 /* sample rate */
 view.*********(24, sampleRate, true);
 /* byte rate (sample rate * block align) */
 view.*********(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.*********(40, samples.length * 2, true);
 floatTo16BitPCM(view, 44, samples);
 return view;
}

Привет, я использую этот исходный код для записи звука для моего школьного экзамена. Он записывает аудио в 44100 Гц и 16 бит. Я хочу изменить настройки записи для записи звука на 16000 Гц и 16 бит. Я попробовал изменить 44 в функции encodeWAV до 16, но это не сработало.

function encodeWAV(samples){
 var buffer = new ArrayBuffer(44 + samples.length * 2);
 var view = new DataView(buffer)

Также я попытался изменить floadRToBitPCM. Я пытался изменить с 44 до 16, но это тоже не сработало.

floatTo16BitPCM(view, 44, samples);

Можете ли вы помочь мне с этой проблемой? Я не знаю, как изменить этот исходный код.

4 ответа

Я не верю, что вы можете контролировать частоту дискретизации с помощью API веб-аудио... он выбирает частоту дискретизации по умолчанию, которая определяется за пределами браузера... конечно, после записи, вы можете программным образом изменить свой звук для повторной выборки к любой частоте дискретизации... Большинство аудиоплееров могут воспроизводить только носители стандартных частот дискретизации... возможность визуализации частоты дискретизации 16 кГц может быть более сложной, чем повторная выборка с 44,1 до 16 кГц


Изменить:

Еще один вариант (намного лучший IMO) - это просто пойти на HTML MediaRecorder и записать в формате .ogg, demo, и это git repo

Я предполагаю, что вы используете this в качестве источника, и, как сказал jaket, строка floatTo16BitPCM(view, 44, samples); не имеет ничего общего с выборкой ставка...

если вы хотите выполнить повторную выборку данных, вы можете изменить это:

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);
}

в это:

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);
}

для повторной выборки данных,

// 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;
};

Изменить:, если вы не собираетесь слишком сильно его менять, вы можете просто записать его как

function exportWAV(type){
 var buffers = [], desiredSamplingRate = 16000;


Вы изменяете неправильное поле. Волновой файл представляет собой заголовок, за которым следуют данные. Заголовок волны обычно составляет 44 байта. Значение 44, которое вы видите в примере кода, связано с этим, а не с 44100.

Где-то в коде, который вы еще не отправили, sampleRate определяется как 44100. Вам нужно отследить это определение и изменить его на 16000. В зависимости от остальной части вашего кода и источника образцов это может не быть довольно просто. Например, если сэмплы записываются с устройства, и устройство настроено на запись на этапе 44100, то простое сохранение сохраненной формы сигнала как 16000 не будет иметь желаемого эффекта. Это просто сделает воспроизведение 2.75x слишком медленным, как эффект Барри Уайта.


Вы можете изменить функцию init таким образом, здесь вы можете преодолеть частоту выборки браузера по умолчанию до 16000, а также каналы, обозначающие моно/стерео, которые мы можем изменить,  если это моно, это будет 1, другие мудрые два.

function init(config) {
 //sampleRate = config.sampleRate;
 sampleRate = 16000;
 debugger;
 //numChannels = config.numChannels;
 numChannels = 1;
 initBuffers();
 }

licensed under cc by-sa 3.0 with attribution.