mmorise / World

A high-quality speech analysis, manipulation and synthesis system
http://www.kisc.meiji.ac.jp/~mmorise/world/english
Other
1.17k stars 251 forks source link

synthesisrealtime_cppについて #86

Closed huskofcrayfish closed 5 years ago

huskofcrayfish commented 5 years ago

初めまして。 標記の件について、気になる点があったためプルリクエストを送らせていただきました。 synthesisrealtime_cpp内、SearchPointer() でsynth->current_pointer2が使用されていますが、current_pointer2 はリングバッファ内において ClearRingBuffer()によってデータが破棄された位置を指す変数であり、synth->current_pointer を使用するべきなのではないかと思い書き換えてみました。 書き換えた状態でも私が試した限りでは問題なく動作しました。 ご確認をお願いします。

mmorise commented 5 years ago

ご連絡ありがとうございます. こちら,当時の私の記憶が確かであれば,current_pointerにするとsynthesis.cppと微妙に値が変わる他,極稀に不正処理が起こったと思います(元々DCオフセットなど一部の処理を実時間用に変えているので完全には一致しません).current_pointer2の役割は,リングバッファのデータが破棄された位置であっているはずですが,破棄された位置と現在の位置の差は常に一定ではなく稀にずれることがあります.現在の実装は,current_pointer2を使い,そのズレを補正するような演算になっていたはずです.

記憶が曖昧なのでこれ以上はコードを真面目に見直してからになりますが,恐らくサンプリング周波数が22.05 kHzでframe_shiftが5 msのように,frame_shiftの切り替わる時刻にサンプル点が存在しないケースが存在する際にこの問題は顕在化しやすいはずです.

huskofcrayfish commented 5 years ago

早速のご回答ありがとうございます。 改めてコードのほうを確認してみましたが、frame_shiftの切り替わる点にサンプル点がなかった場合にfrontには直前のサンプル点(この表現が正しいかわかりませんが)を参照させ、その点を表現するためにpointerからindex分進んだ場所という形で表しているということでしょうか。 その場合、 frameはf0_origin[pointer] から f0_origin[pointer] + f0_length[pointer] の間に収まる必要があるように見えます。current_pointer とcurrent_pointer2 に2以上の差があるとそれを超えてしまうような気がしますが、確認した範囲では2以上の差がつくことはありませんでした。通常の使用方法では2以上の差がつかないということでしょうか。

mmorise commented 5 years ago

すみません,しばらく詳細なコードの検証をやれる時間が確保できないので,予想でのお話になります(今更ながら,真面目なドキュメントを書いていないことを反省).

結論から言いますと,やはりcurrent_pointer2で正解だと思います. 1つ前の私のネタは,不正処理が出ること以外,多分今回の件とは関係ない(私の勘違い)です.ClearRingBufferを見ると,113行目でtmp_pointerを2番目の引数に指定し,114行目でcurrent_pointer2にtmp_pointerを代入しています.ClearRingBuffer内82行目の終了条件は「i < end」なので,最初にご指摘のあった「current_pointer2は破棄された位置」は微妙に異なっており,「破棄された位置の次」,つまりデータが存在する位置を示すことになるはずです.ゆえに,SearchPointerでcurrent_pointer2を指定しても問題が生じないのだと思います.

131行目と132行目を見ると,frontは常にcurrent_pointer2のフレームから情報を参照し,nextはcurrent_pointer2が終端までたどり着いていた場合,その次のcurrent_pointerの先頭の情報を参照しているようです.current_pointer2の終端の次がcurrent_pointerの先端なので,手続き的にはこれで問題無いように見えます.

huskofcrayfish commented 5 years ago

お話を聞く限りcurrent_pointer2であっていそうなのでプルリクエストは取り下げておきます。 お忙しい中ご説明ありがとうございました。