You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中获取麦克风输入频率?基于p5.js开发网页吉他调音器

获取麦克风输入频率实现吉他调音器(p5.js及替代方案)

嘿,作为一个用p5.js折腾过不少音频项目的开发者,我刚好能给你一些实用的建议!要做吉他调音器,核心就是实时获取麦克风输入的频率,下面分两种方案给你拆解:

方案一:用p5.sound官方库实现(最省心)

p5.sound本身就封装了Web Audio API的功能,完全能满足你的需求,步骤很清晰:

  1. 请求麦克风权限并初始化音频输入
    首先得让用户授权麦克风访问,然后创建AudioIn实例来捕获实时音频,再连接到FFT(快速傅里叶变换)模块——它能把音频波形转换成频谱数据,帮我们找到对应频率。

  2. 解析频谱获取峰值频率
    在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:06:00