简介:这份 praat 中文学习手册面向语音学研究者、语言学与心理学专业学生及对语音科学感兴趣的初学者,帮助读者系统掌握 praat 在语音信号分析、处理与展示方面的操作。手册围绕软件基本界面、语音文件导入导出、波形与频谱分析、声调韵律研究、元音辅音测量、语音合成、脚本编程及教学演示等模块展开,通过实例与步骤降低上手门槛。资源包共 214 个文件,全部为 html 网页文档,压缩后约 281KB,内容涵盖对象类型、脚本编辑器、公式函数、TextGrid 编辑器等主题页面,便于按目录逐项查阅与离线浏览。目前已有 920 人学习下载,适合希望从零建立 praat 操作框架、并在实际语音研究中反复查阅的读者。
1. 从一次标注翻车说起:这份手册到底能帮你省下多少时间
去年帮一个做方言调查的团队处理录音,对方发来 40 条 wav,要求标注声调、提取基频、再导出 TextGrid。我心想 Praat 脚本跑一遍的事,结果卡在第一步——他们用的 Praat 版本是 6.0 的老界面,菜单路径和我记忆里的 6.4 完全对不上,光找“To Pitch”就翻了十分钟。更麻烦的是,团队里没人系统学过 Praat,全靠零散搜到的英文帖子拼凑操作,一个“基频上限设多少”的问题,三个人给出三个答案。
这就是我拿到这份《Praat 中文学习手册》时的真实心态:不是缺资料,是缺一份能把界面、参数、脚本、坑点串起来的中文材料。Praat 本身是阿姆斯特丹大学开发的语音分析软件,功能极强,但它的官方文档是英文的,而且偏重算法说明,对“我该点哪个按钮”“这个参数填多少”这类操作问题着墨不多。这份手册的价值就在于,它把 Praat 从安装到脚本批处理的全流程用中文重新组织了一遍,覆盖了录音标注、基频提取、共振峰分析、脚本自动化这几个最常用的场景。如果你正在做语音学实验、方言调查、声学分析,或者只是需要批量处理一批录音,这份手册能让你少走很多我当年走过的弯路。
2. 手册内容拆解:从界面汉化到脚本批处理的四个层次
2.1 界面与基础操作:先搞清楚 Praat 的“对象窗口”逻辑
Praat 最让人不适应的地方,是它没有传统意义上的“打开文件—编辑—保存”流程。它的核心是对象窗口(Objects):你先把声音文件读进来,变成一个“Sound 对象”,然后对这个对象执行各种操作,操作结果又变成新的对象(比如 Pitch 对象、TextGrid 对象)。很多人第一次用 Praat 会懵,就是因为习惯了 Word 那种“所见即所得”的编辑模式。
手册里对这块讲得比较清楚,我按自己的理解重新梳理一下关键路径:
- 启动 Praat 后,你会看到两个窗口:Praat Objects(对象列表)和Praat Picture(绘图窗口)。日常操作 90% 在 Objects 窗口完成。
- 读入声音:
Read from file...选择 wav 或 mp3。注意 Praat 对 mp3 的支持需要额外解码器,建议统一转成 wav 再处理。 - 查看波形和频谱:选中 Sound 对象,点
View & Edit,会打开编辑窗口。这里可以手动标注、看基频曲线、看频谱图。 - 标注完成后,从编辑窗口或对象窗口生成 TextGrid:
Annotate > To TextGrid...。
手册里配了界面截图,标注了每个菜单的中文含义。我建议新手先把“对象窗口”和“编辑窗口”的关系搞清楚,不然后面学脚本会非常痛苦——因为脚本里每一步都是在操作对象,而不是操作“文件”。
2.2 标注系统:TextGrid 的层级设计与边界对齐
TextGrid 是 Praat 的标注核心,但它的设计逻辑和很多人想的不一样。一个 TextGrid 可以包含多个Tier(层),每个 Tier 可以是IntervalTier(区间层)或PointTier(点层)。区间层用来标音素、音节、词这类有持续时间的单位;点层用来标声门塞音、爆破点这类瞬时事件。
手册里给了一个方言调查的典型配置:
| Tier 名称 | 类型 | 用途 | 边界对齐方式 |
|---|---|---|---|
| Phone | IntervalTier | 音素标注 | 与相邻音素边界严格对齐 |
| Syllable | IntervalTier | 音节标注 | 边界必须与 Phone 层边界重合 |
| Tone | PointTier | 声调起点 | 标在韵母起始位置 |
| Word | IntervalTier | 词汇标注 | 边界与 Syllable 层对齐 |
这里有个血泪经验:Tier 之间的边界必须严格对齐。比如 Syllable 层的边界如果和 Phone 层差了几毫秒,后续用脚本提取“每个音节的基频均值”时就会出错——脚本会按 Syllable 边界去切 Pitch 对象,边界不对齐就会切到相邻音节的段。手册里专门用一节讲“边界吸附”操作:在编辑窗口里拖动边界时按住 Shift 键,边界会自动吸附到最近的零交叉点或相邻 Tier 的边界上。
另一个容易翻车的地方是PointTier 的标注位置。点层标注的是“时间点”,不是“时间段”。如果你在点层上标了一个声调起点,但实际基频曲线在这一点还没开始,提取出来的值就是错的。手册建议:点层标注前先看一遍基频曲线,确认起点位置再标。
2.3 声学参数提取:基频、共振峰、强度的参数怎么设
这是手册里最“硬”的部分,也是最能体现中文手册价值的地方——英文文档里这些参数往往只给一个默认值,不解释为什么。手册里对每个参数都给了适用场景和调整建议。
基频(Pitch)提取:
# 对选中的 Sound 对象提取基频 To Pitch: 0.0, 75, 600 # 参数含义:时间步长 0.0(自动),基频下限 75 Hz,上限 600 Hz- 时间步长:设为 0 表示自动,Praat 会根据信号长度自动计算。手动设置时一般取 0.01 秒或 0.005 秒,步长越小曲线越平滑但计算越慢。
- 基频下限:男声建议 60–80 Hz,女声建议 100–150 Hz。设太低会把噪声当成基频,设太高会漏掉低音。
- 基频上限:成年男声一般不超过 300 Hz,女声不超过 500 Hz。儿童语音可以设到 600 Hz。
手册里特别提醒:基频提取前一定要先做“去趋势”或“预加重”,否则低频噪声会干扰基频检测。Praat 的To Pitch内部已经做了滤波,但如果录音质量差,建议先手动切除静音段。
共振峰(Formant)提取:
# 提取共振峰 To Formant (burg): 0.0, 5, 5500, 0.025, 50 # 参数:时间步长 0.0,最大共振峰数 5,上限频率 5500 Hz,窗长 0.025 秒,预加重 50 Hz- 最大共振峰数:成年男性一般 4–5 个,女性和儿童可能需要 5–6 个。
- 上限频率:男性 5000 Hz,女性 5500 Hz,儿童 8000 Hz。设低了会丢掉高共振峰,设高了会引入高频噪声。
- 窗长:0.025 秒是默认值,适合大多数语音。如果分析的是快速辅音,可以缩短到 0.005 秒。
手册里给了一个对照表,我把它简化成下面这样,方便快速查:
| 参数 | 男声 | 女声 | 儿童 |
|---|---|---|---|
| Pitch 下限 | 60–80 Hz | 100–150 Hz | 150–200 Hz |
| Pitch 上限 | 300 Hz | 500 Hz | 600 Hz |
| Formant 上限 | 5000 Hz | 5500 Hz | 8000 Hz |
| 最大共振峰数 | 5 | 5 | 6 |
2.4 脚本自动化:批量处理 100 个文件的正确姿势
手动操作只能应付几个文件,真正干活必须靠脚本。Praat 的脚本语言叫Praat Script,语法类似 Python 但更简单,专门为语音处理设计。手册里给了一个批量提取基频并导出 CSV 的完整脚本,我把它拆解一下关键部分:
# 批量提取基频并导出 form 批量处理 sentence 输入目录 ./ sentence 输出文件 result.csv endform # 创建输出文件并写入表头 writeFileLine: outputFile$, "文件名,时长,基频均值,基频标准差" # 遍历目录下所有 wav 文件 fileList = Create Strings as file list: "list", inputDir$ + "*.wav" n = Get number of strings for i from 1 to n selectObject: fileList fileName$ = Get string: i sound = Read from file: inputDir$ + fileName$ # 提取基频 selectObject: sound pitch = To Pitch: 0.0, 75, 600 # 获取统计值 selectObject: pitch meanPitch = Get mean: 0, 0, "Hertz" stdevPitch = Get standard deviation: 0, 0, "Hertz" # 获取时长 selectObject: sound duration = Get total duration # 写入结果 appendFileLine: outputFile$, fileName$, ",", duration, ",", meanPitch, ",", stdevPitch # 清理对象,避免内存溢出 removeObject: sound, pitch endfor # 清理文件列表对象 removeObject: fileList逻辑说明:
form ... endform定义了一个简单的输入界面,运行脚本时会弹出对话框让你填目录和输出文件名。Create Strings as file list生成一个文件列表对象,Get number of strings拿到文件数量。- 循环里每次读取一个 wav,提取基频,取均值和标准差,然后追加写入 CSV。
removeObject是关键:Praat 不会自动回收对象,循环 100 次不清理会爆内存。
参数说明:
To Pitch: 0.0, 75, 600里的 75 和 600 要根据录音对象调整,不能照抄。Get mean: 0, 0, "Hertz"里的两个 0 表示时间范围从 0 到 0,即整个文件。如果要只分析某个时间段,改成具体秒数。appendFileLine每次追加一行,适合大批量处理。如果文件不多,也可以用writeFileLine一次性写入。
手册里还提醒:脚本文件保存为 .praat 后缀,在 Praat 里通过Run > Run script...执行。如果脚本报错,先检查文件路径里有没有中文或空格——Praat 对中文路径的支持不稳定,建议全用英文路径。
3. 避坑与排查:五个让我熬夜的 Praat 常见问题
3.1 基频曲线断断续续,像被狗啃过
现象:提取出来的基频曲线中间缺了好几段,或者跳变到几百 Hz 的异常值。
原因:最常见的是基频上下限设错了。比如分析女声时下限还留着默认的 75 Hz,结果把清音段的噪声当成了基频;或者上限设了 500 Hz,但录音里有 600 Hz 的共振峰干扰。另一个原因是录音本身有削波或低频噪声。
解决:先看波形,确认没有削波。然后调整基频范围:女声下限提到 100–150 Hz,上限提到 500–600 Hz。如果还有断点,在编辑窗口里手动检查断点位置的波形,必要时先做Filter (stop Hann band)去掉低频噪声。
3.2 TextGrid 和音频对不上,标注整体偏移
现象:标注的时候明明对齐了,导出后再打开发现标注整体前移或后移了几十毫秒。
原因:Praat 的时间基准是音频文件的采样点,如果音频文件被外部工具重新编码过(比如用某音频软件降噪后导出),采样点可能发生了变化,但 TextGrid 里的时间戳还是旧的。
解决:标注前先把音频转成标准 wav(16 bit PCM,采样率统一),标注后不要再对音频做任何处理。如果必须处理,处理完重新标注。手册里建议:原始录音、处理后的音频、TextGrid 三者分开存放,用文件名关联,不要覆盖。
3.3 脚本跑一半报错“Object not found”
现象:批量脚本跑到第 30 个文件时突然报错,提示找不到对象。
原因:Praat 脚本里selectObject是按对象 ID 选的,如果循环里创建了对象但没清理,对象 ID 会越来越乱,最终选错对象。另一个常见原因是文件列表里混入了非 wav 文件(比如 .DS_Store 或 .txt),读取时失败。
解决:每次循环结束前用removeObject清理创建的对象。文件列表生成后先检查一遍,过滤掉非 wav 文件。手册里给了一个过滤写法:
if right$(fileName$, 4) = ".wav" # 处理逻辑 endif3.4 共振峰提取结果全是 NaN
现象:提取出来的共振峰数据全是 NaN 或 0。
原因:上限频率设得太低,把共振峰截掉了;或者窗长设得太短,频谱分辨率不够。另一个可能是音频本身是静音段。
解决:把上限频率调到 5500 Hz 以上,窗长保持 0.025 秒。如果还是 NaN,检查音频段是否有实际语音。手册里建议:共振峰分析前先做一遍基频提取,确认有语音段再分析。
3.5 中文路径导致脚本无法读取文件
现象:脚本在英文路径下正常,换成中文路径就报错“File not found”。
原因:Praat 的底层文件系统接口对非 ASCII 路径支持不完善,尤其是 Windows 系统下。
解决:所有工作目录用英文命名,文件名也用英文或拼音。如果必须用中文,先在 Praat 外部把文件重命名,处理完再改回来。手册里把这个坑放在第一章就讲了,但很多人不看,直到翻车才回来找。
4. 进阶技巧:用 Praat 做声调自动分类的验证方法
手册最后一章讲了一个比较实用的进阶场景:用基频曲线做声调自动分类。这个在方言调查和汉语教学里很常用,但很多人卡在“提取了基频之后怎么用”这一步。手册给了一个基于基频均值和斜率的简单分类方法,我把它整理成可复现的步骤。
4.1 声调特征提取:均值和斜率就够了
汉语普通话四个声调的核心区别在基频曲线的走向:阴平高平、阳平上升、上声低降升、去声高降。用两个特征就能大致区分:基频均值和基频斜率(用线性回归拟合基频曲线)。
# 提取基频均值和斜率 selectObject: pitch meanPitch = Get mean: 0, 0, "Hertz" # 获取基频点序列 nPoints = Get number of frames sumX = 0 sumY = 0 sumXY = 0 sumX2 = 0 for j from 1 to nPoints time = Get time from frame: j freq = Get value at time: time, "Hertz", "linear" if freq <> undefined sumX = sumX + time sumY = sumY + freq sumXY = sumXY + time * freq sumX2 = sumX2 + time * time endif endfor slope = (nPoints * sumXY - sumX * sumY) / (nPoints * sumX2 - sumX * sumX)逻辑说明:
Get number of frames拿到基频帧数。- 循环里逐帧读取时间和频率,累加求和。
- 最后用最小二乘法算斜率。斜率正值为上升调,负值为下降调,接近零为平调。
参数说明:
Get value at time里的"linear"表示线性插值,如果基频曲线有断点,插值会跳过未定义段。- 斜率计算前要确保
nPoints足够大(至少 10 帧),否则斜率不稳定。
4.2 分类阈值怎么定:用已知样本反推
有了均值和斜率,下一步是定阈值。手册建议:不要拍脑袋定,用一批已知声调的样本反推。比如你手头有 20 个已标注的阴平样本,算出它们的均值和斜率分布,取均值加减两倍标准差作为阈值范围。
| 声调 | 基频均值范围(女声) | 斜率范围 |
|---|---|---|
| 阴平 | 220–280 Hz | -0.5–0.5 |
| 阳平 | 180–240 Hz | 1.0–3.0 |
| 上声 | 150–220 Hz | -2.0–0.5 |
| 去声 | 200–280 Hz | -3.0–-1.0 |
这个表只是示例,实际阈值要根据录音人和录音设备调整。手册里强调:声调分类没有万能阈值,必须用你自己的数据校准。
4.3 验证方法:混淆矩阵和人工抽检
分类做完后怎么知道准不准?手册给了两个方法:
方法一:混淆矩阵。把分类结果和人工标注结果做交叉表,看每个声调的召回率和精确率。如果某个声调召回率低于 80%,说明阈值需要调整。
方法二:人工抽检。从每个声调类别里随机抽 10 个样本,在 Praat 里打开波形和基频曲线,肉眼判断分类是否正确。这个方法虽然慢,但能发现混淆矩阵看不出来的问题——比如某个样本的基频曲线本身就有断点,导致斜率计算错误。
我自己的习惯是:每次做完自动分类,先跑一遍混淆矩阵,再抽检 5% 的样本。如果抽检发现错误率超过 10%,就回去检查基频提取参数,而不是急着调分类阈值。因为大部分分类错误,根源都在基频提取那一步。
从那以后我每次处理新录音,都强制走一遍“先看波形→再调基频参数→最后跑分类”的流程,不再直接套用上一次的参数。希望这份手册和上面的拆解,能帮你在 Praat 里少熬几个夜。
本文还有配套的精品资源,点击获取