Praat 脚本 | 基于TextGrid标注内容截取声音及标注片段

作者:熊子瑜
脚本ID:Praat.XZY20210907.014
上传时间:2021年9月7日 更新时间:2022年8月25日
简介:根据用户指定的声音文件夹,针对其中的全部声音文件(*.wav),基于各个声音文件所对应的标注文件(*.TextGrid)中的标注内容和时间信息,将其截取成相应的声音片段,并另外保存起来,会同步截取保存标注片段的内容文件。使用时,每个声音文件需有相应的标注文件,并成对存放在相同的文件夹之中,另外用户需指定标注内容所在的层级序号。用户可设定不用截取保存的标注内容,多个标签之间用“,”分隔。另外,标注层级中的空白部分(即无标注内容的片段)也会被脚本程序自动忽略,不做截取保存。此脚本程序适用于较多字词条目的长录音文件的截取保存操作。

点此下载该脚本程序


#By XIONG Ziyu
#时间:2021-09-07  更新时间:2022-08-25
#版本号:Praat 6.1.05
#功能:根据用户指定的声音文件夹,针对其中的全部声音文件(*.wav),
#      基于各声音文件所对应的标注文件中的标注内容和时间信息将其截取成相应的声音片段,
#      并另外保存起来,同步截取保存标注片段内容文件。使用时用户需指定标注内容所在的层级序号。
#      用户还可根据实际需要选择Adjust_Duration参数,在边界时间信息的基础上调整截取的时间点位置。
#      用户可设定不用截取保存的标注内容,多个标签之间用“,”分隔。
#      另外,标注层级中的空白部分(即无标注内容)也会被脚本程序自动忽略,不做截取保存。


form 截取保存声音片段
	sentence wavFile_Open_Path D:\sound\
	sentence wavFile_Save_Path D:\sound_new\
	positive Tier_Index 1
	optionmenu Adjust_Duration: 7
		option 边界位置外扩300毫秒
		option 边界位置外扩200毫秒
		option 边界位置外扩100毫秒
		option 边界位置外扩50毫秒
		option 边界位置外扩20毫秒
		option 边界位置外扩10毫秒
		option 按边界位置截取
		option 边界位置内缩10毫秒
		option 边界位置内缩20毫秒
		option 边界位置内缩50毫秒
		option 边界位置内缩100毫秒
		option 边界位置内缩200毫秒
		option 边界位置内缩300毫秒
		option 按边界位置加减半个停顿
	optionmenu New_FileName: 2
		option 自动编号
		option 以内容命名,重名时加编号
	sentence Do_not_save ,#,&,sil,XXX,
endform

wavFile_Open_Path$=replace$(wavFile_Open_Path$,"/","\",0)
wavFile_Save_Path$=replace$(wavFile_Save_Path$,"/","\",0)
if right$(wavFile_Open_Path$,1)!="\"
	wavFile_Open_Path$=wavFile_Open_Path$+"\"
endif
if right$(wavFile_Save_Path$,1)!="\"
	wavFile_Save_Path$=wavFile_Save_Path$+"\"
endif
if wavFile_Save_Path$=wavFile_Open_Path$
	exitScript: "保存路径与读取路径不能完全相同,请修改保存路径!'newline$'"
endif

cpos=index(wavFile_Save_Path$,":\")
for i from cpos+2 to length(wavFile_Save_Path$)
	tt$=mid$(wavFile_Save_Path$,i,1)
	if tt$="\" or i=length(wavFile_Save_Path$)
		tmp$=left$(wavFile_Save_Path$,i)
		createDirectory: "'tmp$'"
	endif
endfor
txtfn$=wavFile_Save_Path$+"发音文本.txt"
filedelete 'txtfn$'

if adjust_Duration=1
	adjust_Duration=0.3
endif
if adjust_Duration=2
	adjust_Duration=0.2
endif
if adjust_Duration=3
	adjust_Duration=0.1
endif
if adjust_Duration=4
	adjust_Duration=0.05
endif
if adjust_Duration=5
	adjust_Duration=0.02
endif
if adjust_Duration=6
	adjust_Duration=0.01
endif
if adjust_Duration=7
	adjust_Duration=0
endif
if adjust_Duration=8
	adjust_Duration=-0.01
endif
if adjust_Duration=9
	adjust_Duration=-0.02
endif
if adjust_Duration=10
	adjust_Duration=-0.05
endif
if adjust_Duration=11
	adjust_Duration=-0.1
endif
if adjust_Duration=12
	adjust_Duration=-0.2
endif
if adjust_Duration=13
	adjust_Duration=-0.3
endif
if adjust_Duration=14
	adjust_Duration=14
endif

Create Strings as file list: "fileList", "'wavFile_Open_Path$'*.wav"
fNum = Get number of strings
for f from 1 to fNum
	select Strings fileList
	fname$ = Get string: 'f'
	wfname$= wavFile_Open_Path$ + fname$
	tfname$= wfname$-".wav"+".TextGrid"
	if fileReadable(wfname$) and fileReadable(tfname$)
		Read from file: "'wfname$'"
		aTime=Get total duration
		Read from file: "'tfname$'"
		fname$=selected$("TextGrid")
		iNum = Get number of intervals: tier_Index
		if iNum > 0
			selectObject: "TextGrid 'fname$'"
			for i from 1 to iNum
				selectObject: "TextGrid 'fname$'"
				st = Get start time of interval: tier_Index, i
				et = Get end time of interval: tier_Index, i
				name$ = Get label of interval: tier_Index, i
				ost=st
				oet=et
				while left$(name$,1)=" " or left$(name$,1)=" " or left$(name$,1)=newline$
					name$=right$(name$,length(name$)-1)
				endwhile
				while right$(name$,1)=" " or right$(name$,1)=" " or right$(name$,1)=newline$
					name$=left$(name$,length(name$)-1)
				endwhile
				if name$!="" and index(",'do_not_save$',", ",'name$',")=0
					if new_FileName=1
						tt$="'i'"
						while length(tt$)<4
							tt$="0"+tt$
						endwhile
						sfn$=wavFile_Save_Path$+fname$+"-"+tt$+".wav"
					endif
					if new_FileName=2
						idx=0
						sfn$=wavFile_Save_Path$+fname$+"-"+name$+".wav"
						while fileReadable(sfn$)
							idx=idx+1
							tt$="'idx'"
							while length(tt$)<3
								tt$="0"+tt$
							endwhile
							sfn$=wavFile_Save_Path$+fname$+"-"+name$+"_'tt$'.wav"
						endwhile
					endif
					if adjust_Duration=14
						pre=i-1
						if pre>0
							pst = Get start time of interval: tier_Index, 'pre'
							pet = Get end time of interval: tier_Index, 'pre'
							pname$ = Get label of interval: tier_Index, 'pre'
							if pname$="" or index(",'do_not_save$',", ",'name$',")>0
								st=st-(pet-pst)/2
							endif
							if pst=0
								st=0
							endif
						endif
						nex=i+1
						if nex<=iNum
							nst = Get start time of interval: tier_Index, 'nex'
							net = Get end time of interval: tier_Index, 'nex'
							nname$ = Get label of interval: tier_Index, 'nex'
							if nname$="" or index(",'do_not_save$',", ",'name$',")>0
								et=et+(net-nst)/2
							endif
							if net=aTime
								et=aTime
							endif
						endif						
					else
						st=st-adjust_Duration
						et=et+adjust_Duration
					endif

					if st<0
						st=0
					endif
					if et>aTime
						et=aTime
					endif
					selectObject: "Sound 'fname$'"
					Extract part: st, et, "rectangular", 1, 1
					Save as WAV file:  "'sfn$'"
					Remove
					selectObject: "TextGrid 'fname$'"
					Extract part: st, et, "no"
					sfn$=sfn$-".wav"+".TextGrid"
					Save as text file:  "'sfn$'"
					Remove
					fileappend "'txtfn$'" 'fname$''tab$''ost:3''tab$''oet:3''tab$''st:3''tab$''et:3''tab$''sfn$''tab$''name$''newline$'
					sfn$=sfn$-".TextGrid"+".txt"
					filedelete 'sfn$'
					fileappend "'sfn$'" 'name$''newline$'
				endif
			endfor
		endif
		select all
		minus Strings fileList
		Remove
	endif
endfor

exitScript: "操作结束,结果文件已保存至:'newline$''wavFile_Save_Path$''newline$'"