Audacityでラベル毎にファイル分割・変換するで、時分秒(h:mm:ss)を秒(s)に変換して加算して書き換える必要があったので、Vim Sriptでそんな変換ファンクションを実装してみた。
最初は、開始時刻、長さを表示しているのを、それぞれ秒に変換させるファンクションを作った。
0:00:00.000 0:02:03.081
0:02:03.081 0:04:45.451
0:06:48.533 0:04:15.588
0:11:04.121 0:05:50.975
0:16:55.097 0:06:37.438
function! s:MakeAudacityImportLabelTxtFile() range abort
for i in range(1, line("$"))
let strline = getline(i)
let timeIn = matchlist(strline, '\(\d\):\(\d\{2\}\):\(\d\{2\}\)\.\(\d\{3\}\)', 0, 1)
let length = matchlist(strline, '\(\d\):\(\d\{2\}\):\(\d\{2\}\)\.\(\d\{3\}\)', 0, 2)
if len(timeIn) > 0 && len(length)
let timeInMili = (timeIn[1]*3600 + timeIn[2]*60 + timeIn[3])*1000 + timeIn[4]
let lengthMili = (length[1]*3600 + length[2]*60 + length[3])*1000 + length[4]
let strLast = printf("%06s", timeInMili)
let strNext = printf("%06s", timeInMili + lengthMili)
let lastTrackTime = strpart(strLast, 0, len(strLast)-3) . '.' . strpart(strLast, len(strLast)-3) . '000'
let nextTrackTime = strpart(strNext, 0, len(strNext)-3) . '.' . strpart(strNext, len(strNext)-3) . '000'
call setline(i, lastTrackTime . "\t" . nextTrackTime . "\t". i)
endif
endfor
endfunction
これが↓になる
取り込みラベル編集ファイル1
000.000000 123.081000 1
123.081000 408.532000 2
408.533000 664.121000 3
664.121000 1015.096000 4
1015.097000 1412.535000 5
matchlist
というメソッドを初めて使ったのだが、中々便利だ
echo matchlist('0:02:03.081', '\(\d\):\(\d\{2\}\):\(\d\{2\}\)\.\(\d\{3\}\)', 0, 1)
['0:02:03.081', '0', '02', '03', '081', '', '', '', '', '']
とリストとして取得できる。第4引数のcount指定で何番目に合致する文字列を取得するか指定できるのもありがたい。
echo matchlist('0:02:03.081 0:04:45.451', '\(\d\):\(\d\{2\}\):\(\d\{2\}\)\.\(\d\{3\}\)', 0, 2)
とパターンに一致する文字列が二つあっても、引数のcountを2に指定すれば
['0:04:45.451', '0', '04', '45', '451', '', '', '', '', '']
となる。
Vim scriptでは小数は、浮動小数点での扱いになるようなので、整数に変換してから、加算して、後で小数点を付けるという強引な方法にした。
Vim scriptでの数値から文字列はprintf
を使うと便利なので、それを使った。今回は使わなかったが、文字列から数値に変換するときはstr2nr
を使うようだ。
そして、表示する文字列が準備できたら、それを現在の表示行と入れ替えるにはsetline
を使う。
それから、タブなどを文字列結合するときは"
ダブルコーテーションで囲って、メタ文字を入力する。なので、この場合は. "\t" .
とする。'
だとそのままの文字として結合される。
と結構頑張ったのだけど、結局、 前回の記事で書いたように開始時刻、長さでマイクロ秒が丸めれているせいで、1ミリ秒ズレが生じる。
開始時刻から次の開始時刻までを長さとする方が良いと分かったので、そもそもの準備する文字列を開始時刻だけ1とすることにした。
0:02:03.081
0:06:48.533
0:11:04.121
0:16:55.097
0:23:32.536
function! s:MakeAudacityImportLabelTxtFile() range abort
let lastTrackTime = '0.000000'
for i in range(1, line("$"))
let strline = getline(i)
let timeIn = matchlist(strline, '\(\d\):\(\d\{2\}\):\(\d\{2\}\)\.\(\d\{3\}\)', 0, 1)
if len(timeIn) > 0
let nextTrackTime = printf("%s", timeIn[1]*3600 + timeIn[2]*60 + timeIn[3]) . '.' . timeIn[4] . '000'
call setline(i, lastTrackTime . "\t" . nextTrackTime . "\t" . i)
let lastTrackTime = nextTrackTime
endif
endfor
endfunction
とシンプルな形となった。この場合、↓のようになる。
取り込みラベル編集ファイル2
0.000000 123.081000 1
123.081000 408.533000 2
408.533000 664.121000 3
664.121000 1015.097000 4
1015.097000 1412.536000 5
こんな変換処理すらエディター内だけで完結できる Vim はやはり偉大だと改めて思った。
-
一番下の開始時刻は、ファイルの終了時刻を指定することとなる。 ↩︎