我从傅里叶变换得到了频谱。它看起来像这样:![sound spektrogram created by passing police](https://istack.dev59.com/BVNo5.webp)
警察刚好经过 颜色代表强度。
X轴表示时间,
Y轴表示频率,其中0位于顶部。
当吹哨或警笛只留下一条痕迹时,许多其他声音似乎包含大量谐波频率。
电吉他直接插入麦克风(标准调弦)
真正糟糕的是,如您所见,没有主要强度-有2-3个几乎相等的频率。
我编写了一个峰值检测算法来突出最显著的峰值:
这个算法的思路是,我遍历数据并记住大于阈值![Guitar strings now with highlighted strongest frequency](https://istack.dev59.com/2wLnz.webp)
红色圆点标出了最强的峰值。你可以点击这里查看它的运行情况(或者说不太运行)。
![sound spektrogram created by passing police](https://istack.dev59.com/BVNo5.webp)
警察刚好经过 颜色代表强度。
X轴表示时间,
Y轴表示频率,其中0位于顶部。
当吹哨或警笛只留下一条痕迹时,许多其他声音似乎包含大量谐波频率。
![sound spektrogram of EHGDAE tuned guitar](https://istack.dev59.com/EeTSw.webp)
我编写了一个峰值检测算法来突出最显著的峰值:
function findPeaks(data, look_range, minimal_val) {
if(look_range==null)
look_range = 10;
if(minimal_val == null)
minimal_val = 20;
//Array of peaks
var peaks = [];
//Currently the max value (that might or might not end up in peaks array)
var max_value = 0;
var max_value_pos = 0;
//How many values did we check without changing the max value
var smaller_values = 0;
//Tmp variable for performance
var val;
var lastval=Math.round(data.averageValues(0,4));
//console.log(lastval);
for(var i=0, l=data.length; i<l; i++) {
//Remember the value for performance and readibility
val = data[i];
//If last max value is larger then the current one, proceed and remember
if(max_value>val) {
//iterate the ammount of values that are smaller than our champion
smaller_values++;
//If there has been enough smaller values we take this one for confirmed peak
if(smaller_values > look_range) {
//Remember peak
peaks.push(max_value_pos);
//Reset other variables
max_value = 0;
max_value_pos = 0;
smaller_values = 0;
}
}
//Only take values when the difference is positive (next value is larger)
//Also aonly take values that are larger than minimum thresold
else if(val>lastval && val>minimal_val) {
//Remeber this as our new champion
max_value = val;
max_value_pos = i;
smaller_values = 0;
//console.log("Max value: ", max_value);
}
//Remember this value for next iteration
lastval = val;
}
//Sort peaks so that the largest one is first
peaks.sort(function(a, b) {return -data[a]+data[b];});
//if(peaks.length>0)
// console.log(peaks);
//Return array
return peaks;
}
这个算法的思路是,我遍历数据并记住大于阈值
minimal_val
的一个值。如果接下来的look_range
个值都比这个选择的值小,则被认为是峰值。这个算法并不是很智能,但实现起来非常容易。然而,它不能确定字符串的主要频率,就像我之前预料的那样。 ![Guitar strings now with highlighted strongest frequency](https://istack.dev59.com/2wLnz.webp)
红色圆点标出了最强的峰值。你可以点击这里查看它的运行情况(或者说不太运行)。