gpt4 book ai didi

javascript - 从音频中获取对数字节频率数据

转载 作者:数据小太阳 更新时间:2023-10-29 05:18:16 25 4
gpt4 key购买 nike

我之前问过类似的问题,但是没有解决我的问题,而且解释的很差。这次我做了插图,希望能更好地解释。

我的音频播放器有一个简单的频谱分析仪。频率存储在一个数组中,该数组在每个 requestAnimationFrame 上更新,该数组如下所示:

fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);

Read more about getByteFrequencyData here.

所以这很好用,但我希望频率在整个频谱中均匀分布。现在它显示线性频率:

enter image description here

如您所见,这里的主要频率范围是高音(高端),最主要的频率范围是低音范围(低端)。我希望我的分析仪呈现这样均匀分布的频率范围:

enter image description here

在这里您可以看到分析仪上均匀分布的频率。这可能吗?

我用来生成分析器的代码如下所示:

// These variables are dynamically changed, ignore them.
var canbars = 737
var canmultiplier = 8
var canspace = 1

// The analyser
var canvas, ctx, source, context, analyser, fbc_array, bars, bar_x,
bar_width, bar_height;

function audioAnalyserFrame() {
'use strict';
var i;
canvas.width = $('analyser-').width();
canvas.height = $('analyser-').height();
ctx.imageSmoothingEnabled = false;
fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
ctx.fillStyle = "white"; // Color of the bars
bars = canbars;
for (i = 0; i < bars; i += canmultiplier) {
bar_x = i * canspace;
bar_width = 2;
bar_height = -3 - (fbc_array[i] / 2);
ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
}
window.requestAnimationFrame(audioAnalyserFrame);
}

function audioAnalyserInitialize() {
'use strict';
var analyserElement = document.getElementById('analyzer');

if (analyserElement !== null && audioViewIsCurrent() === true) {
if (analyserInitialized === false) {
context = new AudioContext();
source = context.createMediaElementSource(audioSource);
} else {
analyser.disconnect();
}
analyser = context.createAnalyser();
canvas = analyserElement;
ctx = canvas.getContext('2d');
source.connect(analyser);
analyser.connect(context.destination);
if (analyserInitialized === false) {
audioAnalyserFrame();
}
analyserInitialized = true;
analyser.smoothingTimeConstant = 0.7;
}
}

请注意,我在 for 循环中跳过了 8 个小节(请参阅顶部的 canmultiplier)(如果我不这样做,分析器的另一半会在 Canvas 外呈现,因为它太大。)我不知道这是否也是导致频率范围不一致的原因。

最佳答案

如果我对您的理解正确,我认为这对您有用,尽管远非完美。

您在 for 循环中所做的是对数组进行采样,每 8 个元素采样一次。我要做的是以对数方式进行采样。

一个例子:

//Given a range, transforms a value from linear scale to log scale.
var toLog = function(value, min, max){
var exp = (value-min) / (max-min);
return min * Math.pow(max/min, exp);
}

//This would be the frequency array in a linear scale
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];

//In this case i'm using a range from 1 to 20, you would use the size of your array. I'm incrementing 'i' by one each time, but you could also change that
for (var i = 1; i < 20; i += 1) {
//I'm starting at 1 because 0 and logarithms dont get along
var logindex = toLog(i,1,19); //the index we want to sample

//As the logindex will probably be decimal, we need to interpolate (in this case linear interpolation)
var low = Math.floor(logindex);
var high = Math.ceil(logindex);
var lv = arr[low];
var hv = arr[high];
var w = (logindex-low)/(high-low);
var v = lv + (hv-lv)*w; //the interpolated value of the original array in the logindex index.
document.write(v + "<br/>"); //In your case you should draw the bar here or save it in an array for later.
}

我希望我解释得很好。这里有一个 working demo它有一些边界错误,但它可以按我认为你需要的方式工作。

关于javascript - 从音频中获取对数字节频率数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35799286/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com