在线吉他调音器
实时麦克风音高检测 · 标准 EADGBE / Drop D / 半音降 等调弦预设
实时音高检测/标准调弦
实时麦克风音高检测 · 标准 EADGBE / Drop D / 半音降 等调弦预设
需要麦克风权限 · 弹任意一根弦
标准 EADGBE:吉他最常用调弦,从低音到高音为 6-1 弦。E2 (82.4Hz) / A2 / D3 / G3 / B3 / E4 (329.6Hz)。
Drop D (DADGBE):把 6 弦降到 D2 (73.4Hz),金属 / 摇滚常用。可弹低音 power chord。
半音降 (Eb Ab Db Gb Bb Eb):所有弦下降半音,听感更厚重,Jimi Hendrix / Stevie Ray Vaughan 著名调弦。
技巧:① 安静环境 ② 弹单弦不要同时拨多弦 ③ 拨弦后等 1-2 秒 ④ 偏差 < 5 音分(cents)视为准
了解工具定位 · 使用场景 · 对比优势
通过麦克风实时检测吉他各弦音高,显示当前音名与标准音高(E2/A2/D3/G3/B3/E4)的偏差值,辅助将每根弦校准到标准音。适合吉他初学者快速上手调弦、排练前快速检查音准,或录音前确保乐器音高准确。纯浏览器端运行,麦克风音频数据不上传服务器。
刚买吉他的初学者常因听不出音高差而调不准弦,反复用手机 App 也常受环境噪音干扰。本工具通过实时音高检测,在嘈杂房间也能稳定捕捉每根弦的基频,并将偏离值以音分(cent)显示——看到指针居中、偏差归零,新手也能在 2 分钟内完成标准调弦,避免因长期跑调练坏耳朵。
乐队演出前 5 分钟,舞台环境嘈杂、时间紧迫,传统电子调音器需插线或夹琴头,操作笨拙。本工具在浏览器中打开即用,无需安装,对着手机麦克风拨弦即可实时反馈——吉他手、贝斯手甚至尤克里里手轮流使用同一页面,30 秒完成一把琴的六根弦校准,确保开场第一个和弦不翻车。
每天练琴 1 小时,但手指按弦力度不均或琴颈轻微弯曲会导致个别弦音准漂移,长期在跑调状态下练习会形成错误的听觉记忆。本工具支持持续监测模式,练琴过程中随时拨一根空弦就能看到实时音高——发现 3 弦偏低 8 音分,立刻微调旋钮,让每次练习都在标准音高基准上建立正确的指板音感。
吉他老师布置的爬格子练习,学生往往只顾指法速度而忽略按弦音准——同一品格在不同琴弦上的实际音高可能因琴颈曲度而偏移。本工具可配合练习:学生按指定品格拨弦,页面显示实际音高与理论音高的偏差值(如 5 弦 3 品应为 C4,实际显示 C4 +12 音分),老师据此判断是琴的问题还是按弦位置偏差,针对性纠正。
弹奏 Drop D、Open G 等特殊调弦时,需要将某根弦调到非标准音高,传统调音器只显示标准音名,容易调错。本工具允许设定目标音高(如 6 弦从 E2 改为 D2),实时显示当前音高与目标值的音分差——调弦过程中指针从 -200 逐渐归零,视觉反馈比单纯听音更直观,尤其适合在录音前快速切换多首曲目的调弦方案。
| 维度 | 本工具 | 竞品 A(GuitarTuna) | 传统方法(独立硬件调音器) |
|---|---|---|---|
| 数据隐私 | 纯浏览器处理,音频数据不上传任何服务器 | 需注册账号,音频数据经服务器处理 | 无数据上传,完全物理隔离 |
| 离线可用 | 首次加载后完全离线运行 | 需要网络连接才能使用 | 无需网络,电池供电即可 |
| 使用成本 | 免费,无内购 | 免费版含广告,专业功能需订阅 | 一次性硬件购买成本(50-500元不等) |
| 设备依赖 | 需浏览器和麦克风(电脑/手机均可) | 需安装 App(iOS/Android) | 独立硬件,无需手机或电脑 |
| 调音精度 | ±1 音分(标准 A4=440Hz 基准) | ±1 音分(官方标注) | ±3-5 音分(入门级)至 ±1 音分(专业级) |
| 环境噪音适应性 | 依赖浏览器降噪能力,嘈杂环境精度下降 | 内置降噪算法,嘈杂环境表现较好 | 物理接触式拾音,基本不受环境噪音影响 |
| 多乐器支持 | 仅支持吉他标准调弦(EADGBE) | 支持吉他、贝斯、尤克里里、小提琴等数十种乐器 | 通常仅支持吉他/贝斯,部分型号支持多种乐器 |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| 弹奏空弦(6弦E) | E2 (82.41 Hz) ✓ 准 | 典型场景:标准调弦起点,6弦空弦E |
| 弹奏空弦(1弦E) | E4 (329.63 Hz) ✓ 准 | 典型场景:1弦高音E,与6弦差两个八度 |
| 弹奏空弦(5弦A) | A2 (110.00 Hz) ✓ 准 | 典型场景:5弦空弦A,常用参考音 |
| 弹奏空弦(3弦G) | G3 (196.00 Hz) ✓ 准 | 典型场景:3弦空弦G,标准调弦中间音 |
| 弹奏空弦(2弦B) | B3 (246.94 Hz) ✓ 准 | 典型场景:2弦空弦B,与1弦E相邻 |
| 弹奏空弦(4弦D) | D3 (146.83 Hz) ✓ 准 | 典型场景:4弦空弦D,与3弦G相邻 |
| 弹奏泛音(12品) | 音高不准确(泛音频率偏移) | 易错 case:泛音非基频,检测会出错 |
| 弹奏和弦(同时多弦) | 仅显示最强音(如E2) | 边界 case:多音同时输入,只检测主音 |
把手机麦克风贴在琴箱背面或琴颈上弹奏麦克风对准音孔前方 10-20cm 处,或使用拾音器直连吉他音孔是主要声辐射区域,琴体背面和琴颈振幅小,拾音灵敏度低会导致基频检测不稳定
调准空弦 E 后,直接按住 5 品弹 A 弦来校准 A 弦每根弦单独弹奏空弦进行调音,不依赖按弦音高按弦会改变琴弦张力导致音高偏移,且品丝磨损或按压力度不均会引入误差;空弦音高是唯一基准
同时扫过 6 根弦让调音器识别每次只弹一根弦,等音高稳定后再弹下一根实时音高检测基于单音基频提取,多音同时发声会产生频谱混叠,导致检测器锁定错误的泛音
默认 A4=440Hz 但乐队使用 A4=442Hz 时未调整确认调音器 A4 参考频率与合奏标准一致(常见 440Hz/442Hz/443Hz)标准调弦以 A4=440Hz 为基准,但管弦乐团常用 442Hz,巴洛克音乐用 415Hz;参考频率偏差 1Hz 约等于 4 音分
拨弦后 0.1 秒内读取调音器显示并调整拨弦后等待 0.5-1 秒,等音高显示稳定后再拧旋钮吉他拨弦瞬间会激发大量泛音,基频检测需要时间窗口(通常 50-200ms)来锁定稳定基频;过早读取的是瞬态噪声
弹 12 品泛音(轻触 12 品品丝上方)来调空弦直接弹空弦进行调音12 品泛音是基频的 2 倍频,调音器若锁定泛音会显示高八度音名,导致实际空弦偏低一个八度
在空调噪音 / 电视声 / 人声背景下弹奏调音使用有线拾音器夹在琴头,或选择安静房间关闭门窗实时音高检测算法无法区分吉他基频和环境噪音;背景噪音中的低频成分(如空调 50Hz 嗡嗡声)会直接干扰基频提取
公式推导 · 流程图解 · 依据出处
f = 1 / T
f — 音高频率(Hz)T — 振动周期(秒)调音器检测到吉他第 1 弦(高音 E)的振动周期 T = 0.002267 秒,则 f = 1 / 0.002267 ≈ 441.0 Hz,接近标准 440 Hz,判定为音准。
适用于所有弦乐器(吉他、尤克里里、小提琴等)的实时音高检测。不适用于非周期性噪声(如拨弦杂音、拍打箱体声),此时周期检测会失效,需结合自相关算法过滤。
3 种主流语言 · 复制即用
import numpy as np
import pyaudio
import struct
# 实时音高检测(自相关法)
CHUNK = 1024
RATE = 44100
def autocorrelation(signal):
"""自相关函数,检测基频"""
n = len(signal)
result = np.correlate(signal, signal, mode='full')
result = result[n-1:] # 取后半段
# 忽略第一个峰值(自身相关),找第二个峰值
diffs = np.diff(result)
peaks = np.where((diffs[:-1] > 0) & (diffs[1:] < 0))[0] + 1
if len(peaks) < 2:
return 0
# 第二个峰值的索引对应周期
period = peaks[1] - peaks[0]
return RATE / period if period > 0 else 0
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=RATE,
input=True, frames_per_buffer=CHUNK)
print("检测中... 弹奏吉他弦")
try:
for _ in range(10): # 采样10次
data = stream.read(CHUNK)
signal = np.frombuffer(data, dtype=np.int16).astype(np.float32)
freq = autocorrelation(signal)
if freq > 80: # 吉他最低音约82Hz
print(f"检测频率: {freq:.1f} Hz")
finally:
stream.stop_stream()
stream.close()
p.terminate()package main
import (
"fmt"
"math"
"github.com/gordonklaus/portaudio"
)
func autocorrelation(signal []float64) float64 {
n := len(signal)
var maxCorr, secondMaxIdx float64
// 简化自相关:找第二个峰值
for lag := 1; lag < n/2; lag++ {
var sum float64
for i := 0; i < n-lag; i++ {
sum += signal[i] * signal[i+lag]
}
if sum > maxCorr {
secondMaxIdx = float64(lag)
maxCorr = sum
}
}
if secondMaxIdx == 0 {
return 0
}
return 44100.0 / secondMaxIdx
}
func main() {
portaudio.Initialize()
defer portaudio.Terminate()
stream, _ := portaudio.OpenDefaultStream(1, 0, 44100, 1024)
defer stream.Close()
stream.Start()
defer stream.Stop()
buffer := make([]float64, 1024)
fmt.Println("检测中...")
for i := 0; i < 5; i++ {
stream.Read()
// 假设 buffer 已填充音频数据
freq := autocorrelation(buffer)
if freq > 80 {
fmt.Printf("频率: %.1f Hz\n", freq)
}
}
}
// 浏览器中实时音高检测(Web Audio API)
async function startPitchDetection() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const audioCtx = new AudioContext();
const source = audioCtx.createMediaStreamSource(stream);
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048;
source.connect(analyser);
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Float32Array(bufferLength);
function detectPitch() {
analyser.getFloatTimeDomainData(dataArray);
// 自相关法找基频
let maxCorr = 0;
let period = 0;
for (let lag = 1; lag < dataArray.length / 2; lag++) {
let sum = 0;
for (let i = 0; i < dataArray.length - lag; i++) {
sum += dataArray[i] * dataArray[i + lag];
}
if (sum > maxCorr) {
maxCorr = sum;
period = lag;
}
}
if (period > 0) {
const freq = audioCtx.sampleRate / period;
if (freq > 80) {
console.log(`检测频率: ${freq.toFixed(1)} Hz`);
}
}
requestAnimationFrame(detectPitch);
}
detectPitch();
}
startPitchDetection();8 个高频疑问