2015-01-30 3 views
7

Я пытаюсь понизить частоту дискретизации, которую я получаю от audioContext. Я считаю, что он приходит в 44100, и я хочу, чтобы это было 11025. Я думал, что могу просто усреднить каждые 3 образца, и он воспроизводит правильную скорость, но высота слишком высока, как если бы мы все были на гелии ,Уменьшение дискретизации звукового буфера PCM в javascript

Каков правильный способ сглаживания float32Array от 44100 до int16Array с образцами 11025.

var context = new Flash.audioContext(); 
var audioInput = context.createMediaStreamSource(stream); 
var recorder = context.createScriptProcessor(null, 1, 1); 
recorder.onaudioprocess = onAudio; 
audioInput.connect(recorder); 
recorder.connect(context.destination); 

var onAudio = function (e) { 
    var left = e.inputBuffer.getChannelData(0); 
    bStream.write(Flash.convertFloat32ToInt16(left)); 
} 

var convertFloat32ToInt16 = function(buffer) { 
    var l = buffer.length; 
    var point = Math.floor(l/3); 
    var buf = new Int16Array(point); 
    for (var x = l; x > 0;) { 
     var average = (buffer[x] + buffer[x-1] + buffer[x-2])/3; 
     buf[point] = average*0x7FFF; 
     point -= 1; 
     x -= 3; 
    } 
    return buf.buffer; 
} 

ответ

10

Для всех, кому нужен ответ.

var downsampleBuffer = function (buffer, sampleRate, outSampleRate) { 
    if (outSampleRate == sampleRate) { 
     return buffer; 
    } 
    if (outSampleRate > sampleRate) { 
     throw "downsampling rate show be smaller than original sample rate"; 
    } 
    var sampleRateRatio = sampleRate/outSampleRate; 
    var newLength = Math.round(buffer.length/sampleRateRatio); 
    var result = new Int16Array(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] = Math.min(1, accum/count)*0x7FFF; 
     offsetResult++; 
     offsetBuffer = nextOffsetBuffer; 
    } 
    return result.buffer; 
} 

это будет возвращать частота дискретизации меньше одного переданного ему, а также преобразования его в int16Array вместо float32.

+0

Слава богу за это сообщение. Помог мне так сильно, что ты понятия не имел. –

+0

Im рад, что он смог помочь кому-то :), который был беспорядок, чтобы решить. – Neablis

+0

Вы экономите мой день: 'D – diewland

Смежные вопросы