見出し画像

Praat Script書き初め

データ整理がなってない状態だった(今もなお)のですが,必要があり過去のデータを使った研究を始めています。

今回やりたい範囲のデータはPraat上でアノテーションを付けることができたので,次はそこにある時間情報を全て書き出します。Praatは操作を全て記憶しスクリプトとして書き出す機能があり,これを加工すれば簡単にマクロを作ることができます。もちろん一から書くこともできます。今だとガイドがかなり充実していますね。

言語が大幅改変してからあまりスクリプトを書く機会はなかったのですが,今回久しぶりに書きました。せっかくなので新しい言語(といっても古い言語もそのまま使える)の勉強も兼ねてGUIで操作してスクリプトに書き出し加工するという手順で進めました。

まず,今回の作業では音声ファイルに対して5つの層 (tier)を作り,上からtext,note,segment,tone,topicと名付けました。

それぞれの層の役割は次のとおりです。これは下地理則さんの講座を参照しました。表記の厳密さに欠けていますが,今月と来月の発表に向けたものなので,ちゃんとしたのは改めて。

  • text層:ターゲットとなる表現

  • note層:メモ。例えば言いよどみや後で修正があったとかも

  • segment層:子音,母音。本来は/k/や/a/などの具体的な音を入れるべきだけど,今回は子音,母音,二重母音,長音,撥音,促音と何番目のモーラかという情報があればいいのでC,Vなどで簡略化。具体的な音を入れても後から順番を自動で付けられるので,これはこれで二度手間なのだけど。

  • tone層:アクセント,イントネーションの情報,HやLをターゲットとなる位置に付ければいいのだけど,今回は(いわゆる)アクセントのHに相当する情報だけ欲しいのでHだけ付けている。

  • topic層:IDと表現の情報

音声ファイルとアノテーションをするファイル(textgridと呼ぶ)を開いてひとつひとつ名前を付けるのは非常に面倒なので,ある程度自動で区切り,層に名前を付けた状態にします。音量や時間長をもとに自動で区切る命令を使い,さらに必要な層の情報を足してファイルを開くスクリプトを書きました。

# 選択した音声ファイルの名前を fnames$ に入れる
fname$ = selected$("Sound")

# 音声ファイルを元にtextgridを作る
To TextGrid (silences): 100, 0, -40, 0.3, 0.1, "", "sound"
Insert interval tier: 2, "note"
Insert interval tier: 3, "segment"
Insert point tier: 4, "tone"
Insert interval tier: 5, "topic"

# 音声ファイルを一緒に選択し,開く
plusObject: "Sound "+fname$
View & Edit

これを実行すると下の画面が出ます。

あとは誤分析されたところは修正しつつ,音声を聞いて必要な情報を入力していきます。アクセント調査でよくある読み上げ式の調査のものであればある程度(text層とtopic層ぐらい?)はアルバイトに頼んで付けてもらうこともできそうです。

これがだいたい200語分できたので,次はこのアノテーションから自動で次の情報を出すようにします。

  • text:表現

  • segment:各音のラベル(C1とかV3とか),開始時間,終了時間

  • tone:時間

textgridから情報を引き出すにはpraat上でQueryと書かれたボタンを押して必要な情報(例えば何番目のtierの何番目のintervalか)を入力します。一度praat上で実際に操作してからpraatのscript windowを開いて履歴を張り付ければスクリプトでの書き方がだいたい分かるので,必要な情報を変数に書き換えればいいです。

この場合,手順としては次のようにしました。

  1. text層の1番左の空間(intervalと呼ぶ)から順番に文字の入力されているintervalを探し,開始時間と終了時間を記憶する

  2. text層の開始時間から最も近いtoneを探す。

  3. 1と2の情報を書き出す

  4. 文字のあるintervalが見つかったらその範囲のsegmentに含まれる文字の入力されている全てのintervalの音,開始時間,終了時間の情報を書き出すというのを繰り返す

具体的なスクリプトは以下のとおりです。

# text層のintervalの数を数える
num_Interval = Get number of intervals: 1

# intervalの数だけ繰り返す
for int to num_Interval

	# 手順1
	lab_1$ = Get label of interval: 1, int

	if lab_1$ <> ""

	start_time_1 = Get start time of interval: 1, int
	start_label_3 = Get interval at time: 3, start_time_1

	end_time_1 = Get end time of interval: 1, int
	end_label_3 = Get interval at time: 3, end_time_1

	# 手順2
	hindex = Get nearest index from time: 4, start_time_1
	htime = Get time of point: 4, hindex

	# 手順3
	appendInfo: int, tab$, lab_1$, tab$, htime

	# 手順4
	for la from start_label_3 to end_label_3
		int3_label$ = Get label of interval: 3, la
		if int3_label$ <> ""
			cvstart = Get start time of interval: 3, la
			cvend = Get end time of interval: 3, la
			appendInfo: tab$, int3_label$, tab$, cvstart, tab$, cvend
		endif
	endfor

	appendInfo: newline$

	endif
endfor

そして実行。

気持ちいい

できたウィンドウを保存しエクセルで開くと次のようになります。

ちなみに指定したフォルダにあるtextgrid全て開き保存までするというのもできますが,新しい言語でのやり方はよく分かってないので解説は控えます。

作業の見通しが立ち,どうにか冬休みの宿題を終えた気分です。さてここからあらためて考察していきますが,間に合うか…

この記事が気に入ったらサポートをしてみませんか?