HTML 5音频库-如何获得音乐表的平均值

HTML 5 Audio lib - How to get the average value of the music table

本文关键字:音乐 平均值 何获得 音频 HTML      更新时间:2023-09-26

我发现有一个很好的、工作非常好的教程,可以用网络库播放音乐。

一切都很好,但我希望我演奏的音乐具有"平均值"。让我来解释一下。当前:音乐已加载,

function loadSound(url) {
        var request = new XMLHttpRequest();
        request.open('GET', url, true);
        request.responseType = 'arraybuffer';
        // When loaded decode the data
        request.onload = function() {
            // decode the data
            context.decodeAudioData(request.response, function(buffer) {
                // when the audio is decoded play the sound
                playSound(buffer);
            }, onError);
        }
        request.send();
    }

并播放缓冲区。我可以很容易地找到缓冲区的平均值:

var getAverage = function(dataArray){
        var total = 0,                               // initialize to 0
            i = 0, length = dataArray.length;
        while(i < length) total += dataArray[i++];   // add all
        return length ? total / length : 0;          // divide (when length !== 0)
    }

在那里使用

javascriptNode.onaudioprocess = function() {
        // get the average for the first channel
        var array =  new Uint8Array(analyser.frequencyBinCount);
        analyser.getByteFrequencyData(array);
        // clear the current state
        ctx.clearRect(0, 0, 1000, 325);
        // set the fill style
        ctx.fillStyle=gradient;
        drawSpectrum(array);
        var averageVal = getAverage(array);

但是,"全局"值,而不仅仅是放在缓冲区中的值呢?

总之:如何从加载的mp3中恢复全局Uint8Array对象,而不仅仅是解析的缓冲区?

非常感谢你的帮助!

回顾一下:您有一个程序可以流式传输MP3文件。周期性地,您会被调用流的连续块,并且您能够计算每个单独块的平均值。您想要计算整个流的平均值。

计算平均值的唯一方法是在整个流中保持一个运行的和,并计算除以它的元素数量。我不知道javascript,但你需要将这两个值存储在函数范围之外的变量中。

var getSum = function(dataArray){
    var sum = 0,                               // initialize to 0
    i = 0, length = dataArray.length;
    while(i < length) sum += dataArray[i++];   // add all
    return sum;
}
var sum = 0;
var N = 0;
javascriptNode.onaudioprocess = function() {
    ...
    sum += getSum(array);
    N += array.length;
}

稍后,当流结束时,您需要计算average=sum/N

您可能会遇到的一个问题是,sum可能会溢出,这取决于sum变量的总体容量、样本的大小和流的长度。所以,首先做必要的事情,使和成为double。如果这还不够,你可能不得不接受一个近似值,比如取平均值的平均值。只要每个区块的大小接近相同,它就会非常接近。

var getSum = function(dataArray){
    var sum = 0,                               // initialize to 0
    i = 0, length = dataArray.length;
    while(i < length) sum += dataArray[i++];   // add all
    return sum;
}
var sumOfAverages = 0;
var N = 0;
javascriptNode.onaudioprocess = function() {
    ...
    sum = getSum(array);
    sumOfAverages = sum / array.length;
    N += 1;
}