如何在JavaScript中获取麦克风输入频率?基于p5.js开发网页吉他调音器
获取麦克风输入频率实现吉他调音器(p5.js及替代方案)
嘿,作为一个用p5.js折腾过不少音频项目的开发者,我刚好能给你一些实用的建议!要做吉他调音器,核心就是实时获取麦克风输入的频率,下面分两种方案给你拆解:
方案一:用p5.sound官方库实现(最省心)
p5.sound本身就封装了Web Audio API的功能,完全能满足你的需求,步骤很清晰:
请求麦克风权限并初始化音频输入
首先得让用户授权麦克风访问,然后创建AudioIn实例来捕获实时音频,再连接到FFT(快速傅里叶变换)模块——它能把音频波形转换成频谱数据,帮我们找到对应频率。解析频谱获取峰值频率
在draw()循环里,我们可以分析频谱数据,找到振幅最高的那个点,再把它转换成对应的频率值。
给你一段可直接测试的代码示例:
let mic; let fft; function setup() { createCanvas(400, 400); // 初始化麦克风 mic = new p5.AudioIn(); mic.start(); // 初始化FFT,参数是频谱精度,越高越准但性能消耗大 fft = new p5.FFT(0.8, 1024); fft.setInput(mic); } function draw() { background(200); // 获取频谱数据(0-255范围的振幅值) let spectrum = fft.analyze(); // 找到振幅最大的索引 let maxAmp = 0; let peakIndex = 0; for (let i = 0; i < spectrum.length; i++) { if (spectrum[i] > maxAmp) { maxAmp = spectrum[i]; peakIndex = i; } } // 把索引转换成对应的频率 let detectedFreq = fft.freq(peakIndex); // 显示频率值 fill(0); textSize(24); text(`当前频率: ${Math.round(detectedFreq)} Hz`, 20, 50); // 可选:绘制频谱可视化 noStroke(); fill(0, 255, 0); for (let i = 0; i < spectrum.length; i++) { let h = map(spectrum[i], 0, 255, 0, height); rect(i * (width / spectrum.length), height - h, width / spectrum.length, h); } }
注意:浏览器会要求麦克风权限,测试时要用HTTPS或者localhost,不然会被浏览器阻止访问麦克风。
方案二:用自相关算法提升低频精度(适合吉他低音弦)
FFT对于高频信号很准,但吉他的低音弦(比如E弦82Hz)频率低,FFT的精度可能不够。这时候可以用自相关算法来更准确地检测基频,你可以结合p5.sound的AudioIn获取原始音频数据,自己实现自相关:
这里给你一个简化的自相关实现片段,放在draw()里配合p5.sound使用:
function draw() { background(200); // 获取原始音频波形数据 let wave = fft.waveform(); let freq = getFundamentalFrequency(wave, sampleRate()); fill(0); textSize(24); text(`当前基频: ${Math.round(freq)} Hz`, 20, 50); } function getFundamentalFrequency(wave, sampleRate) { let autocorr = []; let maxLag = wave.length / 2; // 计算自相关值 for (let lag = 0; lag < maxLag; lag++) { let sum = 0; for (let i = 0; i < wave.length - lag; i++) { sum += wave[i] * wave[i + lag]; } autocorr.push(sum); } // 找到第一个峰值(排除初始的0点) let peakIndex = 1; while (autocorr[peakIndex] > autocorr[peakIndex + 1]) { peakIndex++; } while (autocorr[peakIndex] < autocorr[peakIndex + 1]) { peakIndex++; } // 转换为频率 return sampleRate / peakIndex; }
这个方法对低频的检测精度会比FFT高很多,适合吉他调音的场景。
其他可选库
如果想尝试其他工具,比如Tone.js也能轻松实现实时频率检测,它的Analyser模块和p5.sound思路类似,但API设计更偏向专业音频开发,不过你完全可以和p5.js配合使用,只需要把麦克风输入连接到Tone.js的分析器就行。
内容的提问来源于stack exchange,提问作者Strimply
相关产品推荐
相关产品推荐

