当前位置: 代码迷 >> JavaScript >> 如何使用Web Audio API测量两种声音之间的差异?
  详细解决方案

如何使用Web Audio API测量两种声音之间的差异?

热度:102   发布时间:2023-06-06 09:36:39.0

我正在尝试使用分析器节点和getByteFrequencyData()来测量两个声音之间的差异。 我认为通过总结每个频率箱的差异,我可以得出一个数字来表示两个声音的差异。 然后,我将能够更改声音并再次测量数字,以查看新声音是否比之前更多或更少。

getByteFrequencyData()是否完全包含声音的表示,还是我需要包含其他数据来限定声音?

这是我正在使用的代码:

var Spectrogram = (function(){
    function Spectrogram(ctx) {
        this.analyser = ctx.createAnalyser();
        this.analyser.fftSize = 2048;
        this.sampleRate = 512;

        this.scriptNode = ctx.createScriptProcessor(this.sampleRate, 1, 1);
        this.scriptNode.onaudioprocess = this.process.bind(this);

        this.analyser.connect(this.scriptNode);

        this.startNode = this.analyser;
        this.endNode = this.scriptNode;

        this.data = [];
    }

    Spectrogram.prototype.process = function(e) {
        var d = new Uint8Array(this.analyser.frequencyBinCount);
        this.analyser.getByteFrequencyData(d);
        this.data.push(d);

        var inputBuffer = e.inputBuffer;
        var outputBuffer = e.outputBuffer;
        for(var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
            var inputData = inputBuffer.getChannelData(channel);
            var outputData = outputBuffer.getChannelData(channel);
            for(var sample = 0; sample < inputBuffer.length; sample++) {
                outputData[sample] = inputData[sample];
            }
        }
    };

    Spectrogram.prototype.compare = function(other) {
        var fitness = 0;
        for(var i=0; i<this.data.length; i++) {
            if(other.data[i]) {
                for(var k=0; k<this.data[i].length; k++) {
                    fitness += Math.abs(this.data[i][k] - other.data[i][k]);
                }
            }
        }
        return fitness;
    }

    return Spectrogram;
})();

您可以使用Meyda包提供的spectralFlux功能来比较两个信号。 根据维基百科,光谱通量“通常计算为两个归一化光谱之间的2范数(也称为欧几里德距离)。”

在运行npm install --save meyda ,你会做类似的事情:

const spectralFlux = require('meyda/src/extractors/spectralFlux');

const difference = spectralFlux({
  signal: [your first signal],
  previousSignal: [your second signal]
});

您可以随意复制的代码,以便您不必处理依赖项,代码库已获得适当许可。

它将返回两个信号发声“不同”的系数。 您可以在时域或频域中执行此操作。 你会得到不同的数字,但两者都会与声音彼此“不同”的方式联系起来。

但“差异”可能无法准确描述您的用例差异。 例如,您可能非常关心音量差异,而不是太多关于音质差异,但频谱通量指标并未考虑到这一点。 您可能希望首先通过特征提取器运行每个信号,找到有关其属性的其他统计信息,例如它们的感知音量,亮度等,然后在这些数据之间采用加权的欧氏距离,这将提供更加量身定制的“差异”度量标准为了你的目的你需要什么。

很高兴进一步详细说明,但这已经很长时间了。

  相关解决方案