音频变调(不变速)
升降调 ±12 半音 · 保持原始时长 · 适合 K 歌伴奏调整 / 男女声转换
不变速变调
升降调 ±12 半音 · 保持原始时长 · 适合 K 歌伴奏调整 / 男女声转换
半音(Semitone):相邻两个音高的最小单位,12 个半音 = 1 个八度。如 C → C# 是 1 个半音,C → G 是 7 个半音(纯五度),C → 高 C 是 12 个半音(八度)。
男女声转换:男声 → 女声约 +3 ~ +5 半音;女声 → 男声约 -3 ~ -5 半音。超过 ±5 容易产生 "卡通声" / "鬼畜" 效果。
K 歌伴奏:嫌伴奏太高试 -2 / -3 ;太低试 +2 / +3 。卡拉 OK 默认 ±0 到 ±2 的调整最常见。
算法原理:本工具用 "时间拉伸 + 重采样" 实现变调不变速:先用 WSOLA 拉伸 N 倍,再用低于原 sampleRate 的方式重采样回原长度,等效改变音高。
了解工具定位 · 使用场景 · 对比优势
调整音频音调,同时保持原始时长与节奏不变。音乐制作人快速试听不同调式、播客主播修正录音跑调、配音演员匹配角色音高,无需重录。音频文件上传后由服务端 FFmpeg 处理,处理完毕自动删除,不留存。
配音演员或内容创作者需要为角色匹配不同性别的声音,但不想改变语速节奏。本工具仅调整音高(升/降调),保持原始语速和时长不变,让男声变女声或女声变男声时,情感表达和台词节奏完全保留,无需重新录制。
业余歌手遇到原调太高唱不上去的歌曲,常规变速降调会破坏伴奏节奏。本工具只降音高不降速,让副歌部分降低 2-3 个半音后,仍能踩着原曲节拍跟唱,K 歌练习或翻唱录制时不再因破音而中断。
声优或模仿爱好者想复刻某位明星的独特音色,但原声调太高或太低难以模仿。本工具将目标音频调整到与自身音域匹配的音高,保留原声的语调起伏和咬字细节,逐句对照练习时,能更精准地捕捉发音位置和共鸣方式。
视频创作者录制旁白时,因设备或情绪波动导致前后段音调不一致。本工具对多段音频统一升高或降低相同半音数,使所有旁白音色一致,且不改变语速和停顿节奏,避免后期因音调差异需要补录或剪辑对齐的麻烦。
独立游戏开发者需要为不同角色生成差异化的语音反馈,但只有一位配音演员。本工具通过调整音高(+4 半音或 -5 半音),从同一段干声中生成多个角色的声音版本,保持原始语速和情绪强度,快速填充游戏内的 NPC 对话资源。
| 维度 | 本工具 | 竞品 A (Audacity) | 传统方法 (DAW + 插件) |
|---|---|---|---|
| 数据隐私 | 纯浏览器处理,音频不上传服务器 | 本地软件处理,不联网 | 音频文件需导入工作站,依赖本地存储 |
| 处理速度 | 秒级完成,实时预览 | 需等待插件渲染,数秒至数十秒 | 需手动调整参数并渲染,耗时数分钟 |
| 离线可用 | 完全离线,加载后无需网络 | 完全离线 | 完全离线 |
| 操作门槛 | 打开网页即用,无需安装 | 需下载安装,学习曲线较陡 | 需购买/安装专业DAW及插件,操作复杂 |
| 平台兼容 | 跨平台(任何现代浏览器) | 仅支持 Windows / macOS / Linux | 依赖特定 DAW 软件平台 |
| 收费 | 免费 | 免费开源 | DAW 和插件通常需付费购买 |
| 文件大小限制 | 受浏览器内存限制,通常支持数百 MB | 受本地内存限制,支持大文件 | 受 DAW 内存限制,支持大文件 |
| 功能范围 | 专注不变速变调,功能单一 | 功能全面,包含变调、变速、降噪等 | 功能全面,可进行精细音频编辑 |
| 批处理能力 | 单次处理单个文件 | 支持批处理(需脚本或宏) | 支持批处理(需脚本或模板) |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| 输入音频文件(如 test.wav),目标调性:+2 半音 | 输出音频文件(test_+2.wav),音调升高 2 个半音,播放速度不变 | 典型场景:将歌曲升调以适应人声范围 |
| 输入音频文件(如 speech.mp3),目标调性:-3 半音 | 输出音频文件(speech_-3.mp3),音调降低 3 个半音,播放速度不变 | 典型场景:将语音降调以匹配低沉音色 |
| 输入音频文件(如 guitar.wav),目标调性:0 半音 | 输出音频文件(guitar_0.wav),音调无变化,原样输出 | 边界 case:输入 0 半音时工具应返回原文件 |
| 输入音频文件(如 long_track.wav),目标调性:+12 半音 | 输出音频文件(long_track_+12.wav),音调升高 1 个八度,播放速度不变 | 边界 case:最大合法调性值(12 半音 = 1 八度) |
| 输入音频文件(如 silent.wav),目标调性:+5 半音 | 输出音频文件(silent_+5.wav),音调升高 5 半音,但音频内容为静音 | 边界 case:静音文件变调后仍为静音 |
| 输入音频文件(如 noisy.mp3),目标调性:-1 半音 | 输出音频文件(noisy_-1.mp3),音调降低 1 半音,背景噪声同步变调 | 易错 case:用户误以为变调会滤除噪声 |
| 输入视频文件(如 video.mp4),目标调性:+4 半音 | 输出音频文件(video_+4.mp3),仅提取音频并变调,视频部分丢弃 | 易错 case:用户误以为工具会处理视频画面 |
导入一段 5 分钟的人声,把音调调高 4 个半音,期望时长缩短到 4 分钟导入 5 分钟人声,调高 4 个半音,输出时长仍然是 5 分钟本工具只改变音高(频率),不改变播放速度(时长)。变速需要配合「变速不变调」或「拉伸」算法,两者是独立参数。
上传一个 .wma 或 .ra 文件上传 .mp3、.wav、.flac、.aac、.ogg、.m4a 等主流格式底层 FFmpeg 虽支持数百种格式,但浏览器端(WASM)或服务端解码器只预编译了常用解码器。罕见格式会导致解码失败或静音输出。
设置变调值为 +24 个半音(两个八度),期望听到清晰的男声变女声设置变调值为 +4 到 +7 个半音,或 -3 到 -5 个半音超过 ±12 半音(一个八度)后,声音会严重失真、出现大量伪影,听起来像「机器人」或「卡通音」,不再是自然的男女声转换。
想把一段歌声从 C 大调转到 D 大调,直接输入 +2 半音输入 +2.00 半音(或精确到小数点后两位)十二平均律中 C→D 是 +2 半音,但实际人声或乐器录音可能存在音准偏差。使用整数半音可能造成「跑调感」,建议用小数微调。
上传一个 200MB 的 48kHz/24bit WAV 文件,立即点击「开始变调」先确认浏览器标签页是否显示「等待中」或「处理中」超过 30 秒,或改用后端模式处理浏览器端 WASM 处理受限于单线程内存,大文件(>50MB)会导致页面卡死或崩溃。服务端处理无此限制但需要网络上传时间。
用 8kHz 采样率的电话录音做变调,期望得到高质量音乐效果使用 44.1kHz 或 48kHz 采样率的音频文件低采样率音频的高频信息已丢失,变调算法会放大这些缺失频段的量化噪声,导致输出有「沙沙声」或「金属声」。
上传一个 5.1 声道的 AC3 文件,变调后只听到左前和右前声道有声音先将多声道音频混缩为立体声或单声道再上传变调算法通常只处理前两个声道(L/R),环绕声道(C/LFE/SL/SR)会被丢弃或静音。混缩后处理可保证所有声道信息被保留。
导入一段跑调的人声,设置变调值为 -0.5 半音,期望自动修正所有走音使用专门的音高修正软件(如 Melodyne、Auto-Tune)逐音符调整本工具对整段音频做全局音高偏移,无法识别并单独修正某个走音的音符。修音准需要时间域的音符分割和音高映射,属于不同技术路线。
公式推导 · 流程图解 · 依据出处
f' = f × 2^{(n/12)}
f' — 变调后的频率(Hz)f — 原始音频频率(Hz)n — 变调半音数(正为升调,负为降调)原始音频频率 f = 440 Hz(A4 音),升调 3 个半音(n = 3)。则 f' = 440 × 2^{(3/12)} = 440 × 2^{0.25} ≈ 440 × 1.1892 ≈ 523.25 Hz(C5 音)。
基于十二平均律的等程半音公式,适用于音乐音频变调(如人声、乐器)。不适用于非乐音(如噪声、语音中的非谐波成分),此时音高感知可能与公式计算结果有偏差。
3 种主流语言 · 复制即用
import subprocess
import os
# 使用 FFmpeg 实现不变速变调(提高 4 个半音)
input_file = "input.wav"
output_file = "output_pitch.wav"
semitones = 4 # 半音数,正数升调,负数降调
# 通过 atempo 保持原速,rubberband 变调
cmd = [
"ffmpeg",
"-i", input_file,
"-af", f"rubberband=pitch={2**(semitones/12):.6f}:tempo=1",
output_file
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"FFmpeg error: {result.stderr}")
else:
print(f"Pitch shifted by {semitones} semitones -> {output_file}")package main
import (
"fmt"
"os/exec"
"strconv"
)
func main() {
input := "input.wav"
output := "output_pitch.wav"
semitones := 4.0
// 计算变调系数:2^(semitones/12)
ratio := 1.0
if semitones >= 0 {
ratio = 1.0
for i := 0; i < int(semitones); i++ {
ratio *= 1.0594630943592953 // 2^(1/12)
}
} else {
ratio = 1.0
for i := 0; i < int(-semitones); i++ {
ratio /= 1.0594630943592953
}
}
cmd := exec.Command("ffmpeg",
"-i", input,
"-af", fmt.Sprintf("rubberband=pitch=%.6f:tempo=1", ratio),
output,
)
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Printf("FFmpeg error: %v\n%s", err, string(out))
return
}
fmt.Printf("Pitch shifted by " + strconv.FormatFloat(semitones, 'f', 0, 64) + " semitones -> " + output)
}const { execSync } = require('child_process');
const path = require('path');
// 使用 FFmpeg 在 Node.js 中实现不变速变调
const inputFile = 'input.wav';
const outputFile = 'output_pitch.wav';
const semitones = 4; // 升 4 个半音
// 计算变调系数
const ratio = Math.pow(2, semitones / 12);
const cmd = `ffmpeg -i "${inputFile}" -af "rubberband=pitch=${ratio.toFixed(6)}:tempo=1" "${outputFile}"`;
try {
execSync(cmd, { stdio: 'pipe' });
console.log(`Pitch shifted by ${semitones} semitones -> ${outputFile}`);
} catch (err) {
console.error(`FFmpeg error: ${err.stderr.toString()}`);
}7 个高频疑问