Praat脚本提取时长及基频并示例如何绘制声调图

本文详细介绍了使用Praat脚本批量提取语音文件中的时长、基频等参数,并以绘制汉字声调图为例,展示了如何应用此脚本进行简单操作。此外,还提供了提取结果文件在Excel中绘制声调图的方法,以及时长归一化与声调归一化的解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[更新日期:2020年04月20日  本站所有Praat脚本都不再提供更新,请大家移步https://github.com/feelins/Praat_Scripts下载最新的代码,可以采用git clone到本地的方法(具体操作要熟悉github相关操作),也可以点击页面的Clone or download,然后选择Download Zip下载整个Praat脚本目录到本地直接打开使用。]

Praat脚本具有强大的功能,对语音文件标注完成后,下面的任务就是把成百上千的语音文件中的参数提取出来,最基本的就是时长,和基频,其它还有元音可能要提取共振峰,如果对这些文件全部手工提取,工作量可想而知,而使用Praat脚本即可以批量提取,便于统一整理。这里先介绍如何提取时长和基频的脚本,随后以如何绘制汉字声调图为例,说明一个小的应用。

1. 基本的读文件以及文件名操作(略)

2. 基频处理

 

if fileReadable(pitchtierFileName$)
  Read from file: pitchtierFileName$
else
  To Pitch: 0, 75, 600
  Interpolate
  Smooth: 10
  Down to PitchTier
  selectObject: "Pitch " + simpleName$
  Remove
  selectObject: "Pitch " + simpleName$
  Remove
  selectObject: "Pitch " + simpleName$
  Remove
endif

解释:这部分是针对基频的提取处理,如果有修正好的基频文件,这里是需要使用Praat保存的格式*.PitchTier格式。所谓的修基频是需要通过Praat生成一个Pitch文件,然后对里面的清、浊出错比较明显的位置给予修正。如果不修基频,最后的结果难免有很多数值点影响整体效果。如果没有提供修正的基频文件,脚本会自动创建一个基频文件。如上面代码里的To Pitch这一部分。

3. 提取音素所在的单词

   intervalWordTier = Get interval at time: word_tier, sTime
   sTimeWord = Get start point: word_tier, intervalWordTier
   eTimeWord = Get end point: word_tier, intervalWordTier
   durationWord = eTimeWord - sTimeWord
   labelOfIntervalWord$ = Get label of interval: word_tier, intervalWordTier


解释:这一段是为了提取该音素所在的单词,因为整个脚本是以音素层为参考,然后提取每个音素所在的单词,所以这里的代码是为了提取这个音素所在的单词。

5. 测试的文件如下图。

语音文件使用的是http://www.phonetics.ucla.edu/course/contents.html页面上的声音。标注文件是随手标的,请忽略不准确,或者错误。

6. 生成的文件

在result.txt,如下面的格式:

7. 举例:

下面以一个小的例子,即如何绘制汉字普通话的声调图,说明如何应用这个脚本进行一些简单的操作。同样的应用可以用到如何提取汉语普通话的连读变调图,以及未知方言的声调提取,以及句子单位的语调提取都是同样的道理。

该示例请在如下地址下载,包括两个汉字的标注示例,提取脚本,提取出来的结果文件,以及在Excel绘制的声调图。积分会在评论后返还,欢迎下载后评论,谢谢:

 示例说明:

1. 标注的时候如图,只给了简单的两层,注意韵母a的标注,我刻意没有保留结尾的那段,因为为了描述大概的声调走向,只保留了比较稳定的一段,其它使用者在实际标注时可根据自己的需要确定如何标注。

2. 标注好之后,使用上述的脚本,即可提取出结果result.txt,脚本运行的时候,音段层为2,单词层是1,文件所在的目录是data,然后输入一个结果文件的正确路径和名称。

3.将结果文件都拷贝到excel里,只保留跟要绘制声调相关的韵母那些行,这样只保留了a相关的数据行,这里只是为了演示,只有两个字的数据,实际操作时,每一个韵母的每一类声调都可能有N多的数据,这样就可以放到一块,进行一下平均,平均的时候是对基频10个点分别平均,这样保证得到的是10个点的基频。这样的操作也称为对时长的归一化。如下图所示,当提取两个韵母的基频时,因为每一个情况下的发音时长是肯定不同的,即使是同一个人,在发同一个韵母的时候,也不能保证时长是相同的,在这样的情况下,只能做一个时长归一化,保证都是10个点的时长,大概的描述这个发音的时长,而归一化的方式,就是把整体时长比如平均分9份,每隔一份的间隔提取一个值,这样无论在什么情况下,每一个样本都提取10个值,这就是时长归一化。当然同样的道理,你也可以选择提取15个值,5个值。。。但是其实就稳定的发音段来说,无论多少值,都区别不大。建议在标注的时候尽量保留稳定段,而且要尽量多的数据平均,这样绘制出来的图像是更有普遍意义的。

4.最终当前这两个字的声调图如下:

5.目前学术研究上流行五度值描述汉语的声调,这样相当于又是一个归一化的过程,相当于把不同的人,不同的性别的人,不同地区的人,任何的差异都抹掉,全部都归一化到1-5的范围内来描述声调,这样适合于进行一个汉语方言区的调查,而条件是必须有足够多的数据,优点是更直观,描述起来大家都容易接受,缺点就是看不到个体的差异。现在比较公认是采用以下的公式进行归一化:

Value =5* (log(x)-log(min))/(log(max)-log(min))

5是归一化到1-5的范围内,而对每一个基频取log值,则是因为有学术研究表现在log域上更接受于人的听感,而max,min代表是样本整体的最大值,最小值,x是指当前原始值。

还是上述数据,经过归一化计算之后,得到如下的声调图。那么我们可以描述,阴平调为55,阳平调为15(其它地方可能描述为25,35,原因是这里只有一个字,很难代表整体,有兴趣的朋友可以多找一些样例平均)

# 关注
关于对本站脚本的使用咨询,以及功能修改,增加等,都可以扫QQ咨询群,私信群主。

![在这里插入图片描述](https://img-blog.csdnimg.cn/35877f190a774dc6a7d17cb720382d9c.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoYW9wZW5nZmVp,size_16,color_FFFFFF,t_70#pic_center)
# 版权说明
1、版权归本公众号“极地语音工作室”,原名“语音处理小站”所有;

2、未经本站或者作者允许, 不得任意转载本文内容,否则将视为侵权;

3、转载或者引用本文内容请注明来源及原作者;

4、对于不遵守此声明或者其他违法使用本站内容者,本人依法保留追究权等。
 



### 生成平均基频的方法与工具 生成平均基频通常涉及对多个音频文件进行基频提取计算这些基频的平均趋势。以下是详细方法和相关工具介绍: #### 方法一:使用 Praat 工具生成平均基频 Praat 是一种广泛应用于语音分析的工具,能够高效地提取基频生成基频。为了生成平均基频,可以采用以下步骤[^1]: - 使用 Praat 脚本批量提取多个音频文件的基频。 - 将所有基频数据导入到数据分析软件(如 MATLAB 或 Python)中。 - 对齐各个音频文件的时间轴,计算每个时间点上的基频平均。 以下是一个 Praat 脚本示例,用于批量提取基频保存为文本文件: ```praat # 定义函数以批量提取基频 form BatchExtractPitch sentence directoryPath "C:/AudioFiles/" real timeStep 0.01 integer pitchFloor 75 integer pitchCeiling 500 endform Create DirList: directoryPath, "*.wav" nFiles = Get number of texts for i to nFiles fileName$ = Get text... i Read from file: directoryPath$ + fileName$ To Pitch: timeStep, pitchFloor, pitchCeiling Extract Pitch Tier Write to text file: "pitch_" + fileName$ + ".txt" endfor ``` 此脚本将从指定目录中的所有 `.wav` 文件中提取基频保存为单独的文本文件。 #### 方法二:使用 Python 和 Parselmouth 库生成平均基频 Parselmouth 是一个基于 Praat 的 Python 包装库,支持高效的语音信号处理。以下是使用 Parselmouth 提取基频生成平均基频的代码示例: ```python import parselmouth import numpy as np import matplotlib.pyplot as plt # 加载音频文件 audio_files = ["file1.wav", "file2.wav", "file3.wav"] f0_list = [] for file in audio_files: sound = parselmouth.Sound(file) pitch = sound.to_pitch() f0_values = pitch.selected_array['frequency'] f0_list.append(f0_values) # 计算平均基频 min_length = min(len(f0) for f0 in f0_list) average_f0 = np.mean([f0[:min_length] for f0 in f0_list], axis=0) # 绘制平均基频 time = np.linspace(0, min_length / 100, min_length) plt.plot(time, average_f0) plt.xlabel("时间 (秒)") plt.ylabel("基频 (Hz)") plt.title("平均基频") plt.grid(True) plt.show() ``` 此代码加载多个音频文件,提取基频计算每个时间点上的平均基频,最后绘制出平均基频。 #### 方法三:使用 MATLAB 生成平均基频 MATLAB 提供了强大的信号处理功能,可用于生成平均基频。以下是 MATLAB 示例代码: ```matlab % 加载多个音频文件 audio_files = {'file1.wav', 'file2.wav', 'file3.wav'}; f0_list = {}; for i = 1:length(audio_files) [audio, Fs] = audioread(audio_files{i}); f0 = pitch(audio, Fs, 'Method', 'cepstral', 'VoicedThreshold', 0.3, 'Range', [75, 500]); f0_list{end+1} = f0; end % 计算平均基频 min_length = min(cellfun('length', f0_list)); average_f0 = mean(cellfun(@(x) x(1:min_length), f0_list, 'UniformOutput', false)); % 绘制平均基频 t = (0:min_length-1) / Fs; plot(t, average_f0); xlabel('时间 (秒)'); ylabel('基频 (Hz)'); title('平均基频'); grid on; ``` 此代码加载多个音频文件,提取基频计算每个时间点上的平均基频,最后绘制出平均基频。 #### 工具推荐 - **Praat**:适合语音信号的基频提取和初步分析,尤其适用于需要手动调整参数的情况[^1]。 - **Parselmouth**:Python 包装的 Praat 库,适合批量处理和自动化分析。 - **MATLAB**:提供丰富的信号处理工具箱,适合复杂的基频分析和可视化。 #### 注意事项 - 在生成平均基频时,需确保所有音频文件的时间长度一致或对齐时间轴。 - 如果音频包含非语音部分或噪声,可能需要预处理以提高基频估计的准确性。 - 平均基频可以用于描述声调语言的声调趋势或语调走势,具体应用取决于研究目标。
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极地语音工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值