今天的文章跟Praat脚本
无关,作为这个所谓的“人工智能”时代最流行的编程语言,如何使用Python
处理TextGrid
并提取一些数据自然是很有必要的,因为从处理复杂关系的数据来说,Praat
脚本的能力还是比较有限的,即使可以完成,也会花费很多精力而使工作效率低下。但是不可否认,Praat脚本
对于处理有层级结构的标注文件是有很大优势的。
本文作为一个开始,先简单了解用Python
读取TextGrid
文件,有人可能会说,TextGrid
文件也是文本文件,就是相当于使用Python
读写文本文件,这不是很简单的事情吗?可是事实上TextGrid
通过记事本打开,确实是一个文本文件,但是它包括不同层级的关系,如果你打算就是通过循环语句,一句一句的查找,再去建立关系。。。啊,这也是个办法。我们现在要做的是如何“优雅”的读取?以下是用记事本打开一个TextGrid
文件的一部分。
File type = "ooTextFile"
Object class = "TextGrid"
xmin = 0
xmax = 2.66
tiers? <exists>
size = 2
item []:
item [1]:
class = "IntervalTier"
name = "Phon"
xmin = 0
xmax = 2.66
intervals: size = 17
intervals [1]:
xmin = 0
xmax = 0.27958612055419324
text = "sil"
intervals [2]:
xmin = 0.27958612055419324
xmax = 0.406291189066745
text = "k"
通过记事本可以看到熟悉的时长,标注信息等,如果在一个文件里标了很多层,这里是item[1]
这样的表示,interval[1]
是表示标注的interval
信息,这里包括了开始时间
,结束时间
,和标注内容
。
为了避免象前面提到的用无穷无尽的循环语句去查找某个目标,最基础的是使用函数,稍高级一点的是使用类,在Python
中有很多开源的包(package)也可以实现textgrid
读写,笔者基本上都去了解过,笔者本人也写过一个类,但是自从遇到本文要推荐的这个之后,瞬间感觉这个更简洁,也更好理解。
这个文件的源作者不是特别清楚,是在研究另外一个项目的时候发现的,以下是这个文件的版权说明。
##############################################################################
# The MIT License (MIT)
#
# Copyright (c) 2016 Kyler Brown
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
这个读取文件利用了Python的namedtuple,namedtuple类位于collections模块,有了namedtuple后通过属性访问数据能够让我们的代码更加的直观更好维护。namedtuple能够用来创建类似于元祖的数据类型,除了能够用索引来访问数据,能够迭代,还能够方便的通过属性名来访问数据。
在python中,传统的tuple类似于数组,只能通过下表来访问各个元素,我们还需要注释每个下表代表什么数据。通过使用namedtuple,每个元素有了自己的名字。类似于C语言中的struct,这样数据的意义就可以一目了然。
在经过这样的方式读取之后,上述TextGrid
在变量中以下面的列表形式存在:
Entry(start=0.0, stop=0.27958612055419324, name='sil', tier='Phon')
Entry(start=0.27958612055419324, stop=0.406291189066745, name='k', tier='Phon')
Entry(start=0.406291189066745, stop=0.5165142974475827, name='a2', tier='Phon')
Entry(start=0.5165142974475827, stop=0.6143759357296349, name='er2', tier='Phon')
上面这个列表,每个元素都有4个属性,这样可以通过很多方式定位到一个元素(所有应用于Python列表
的操作),得到它的开始时间,结束时间,和标注内容,如果你的标注有几层,那么会有几个这样的列表,通过时间点,得到不同层之间的关系也是很方便的。
该文件和之前的Praat
都放在了同一个项目目录里,大家可以通过文本后面提供的地址下载使用,下面举例说明如何使用。
代码段:
将这个文件放在你的其它Python
文件同一级目录中。
首先建立一个常规的Python
文件,笔者在Python3.6
环境和Python3.7
环境都使用过。比如示例中使用的a01_basic_read.py
,将这个文件读进来。
import textgrid as tg
现在找一个TextGrid文件试一下,通过下面这句话读进来 。
tgrid = tg.read_textgrid(r'E:\Biaobei_Demo\000001.TextGrid', 'Phon')
请注意原作者的textgrid.py
里的,read_textgrid
这个函数没有第二个参数,它是写死的使用phones
名称,这个是不方便的,毕竟我们每个人标注的时候,层级名称并不是都是统一的,所以这里要用到这个名称,根据你自己的情况进行修改。我这里用的是Phon
,注意大小写。这样一句话就把第一层所有的信息都读进了tgrid
这个变量里,是不是比较简洁?我们想知道这一层里有多少个interval
?使用下面这句:
print(len(tgrid))
# 输出:17
如果想遍历输出这一层的信息,使用下面的代码:
for entry in tgrid:
print(entry.name)
# 输出:
sil
k
a2
er2
p
u3
p
ei2
...
是不是觉得非常容易呢?后面我们会陆续介绍一些在这个基础上进行的一些复杂一些的层级统计等操作。有兴趣的可以在上面的代码继续扩展,比如输出每一层的开始时间?结束时间?
提议只把标了p
的内容输出?这应该不难吧?欢迎练习或者咨询。
如何获取脚本 https://github.com/feelins/Praat_Scripts
本站所有Praat脚本
都可以在上述github的项目目录
里找到,如果日常对代码、脚本操作比较熟练的可通过下载、安装、配置github for windows
在自己的电脑上通过git clone
将代码下载到本机,这样的好处是可以跟主站及时更新代码。
不想费如此脑筋,可以通过点击如下图1位置所示,下载整站的代码,也可直接使用。
本文的代码是00-Python
,同学可练习使用。脚本里有我的邮箱,有任何问题都可以来信咨询。
关注
关于对本站脚本的使用咨询,以及功能修改,增加等,都可以扫QQ咨询群,私信群主。
版权说明
1、版权归本公众号“极地语音工作室”,原名“语音处理小站”所有;
2、未经本站或者作者允许, 不得任意转载本文内容,否则将视为侵权;
3、转载或者引用本文内容请注明来源及原作者;
4、对于不遵守此声明或者其他违法使用本站内容者,本人依法保留追究权等。