-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ストリーミング処理の対応 #853
Comments
決めなきゃいけないこと
|
名前については、ユーザー向けレベルなら またintermediateが
audio: Audio = synth.seekable_synthesis(aq, amaama_zundamon)
wav_part: bytes = audio.render(slice(t1, t2 + 1))
wav_whole: bytes = audio.render(slice(None))
# よい感じに分割したイテレータを作る
for wav_part in audio.render_segments():
... |
#854 で組んでみましたがpyo3がまだできていません.. |
Audioの中にsynthesizerの参照を持たせるためにはlifetimeを導入する必要があるが、pythonにはこのままでは渡せない |
とりあえずrender関数をSynthesizerの中に入れました |
とりあえず複雑性を避けた方が議論が円滑になりそうですし、今はそれでよいと思います。 もしやるとしたら、 #[pyclass]
+ #[derive(Clone)]
pub(crate) struct Synthesizer {
- synthesizer: Closable<
- voicevox_core::blocking::Synthesizer<voicevox_core::blocking::OpenJtalk>,
- Self,
- SingleTasked,
+ synthesizer: Arc<
+ Closable<
+ voicevox_core::blocking::Synthesizer<voicevox_core::blocking::OpenJtalk>,
+ Self,
+ SingleTasked,
+ >,
>,
} ouroborosでライフタイムパラメータを消す、という形になるかと思います。 use ouroboros::self_referencing;
#[pyclass]
#[self_referencing]
struct Audio {
synthesizer: Synthesizer, // `#[pyclass]`の方
#[borrows(synthesizer)]
#[not_covariant]
inner: voicevox_core::blocking::Audio<'this>, // Open JTalkは要らないので、`&voicevox_core::blocking::Synthesizer`自体ではなく`&Status`を持つようにすれば型引数の`O`は消えるはず
} (ただ #832 の考えかたからすると"pyclass"丸ごとじゃなくて [追記] 文脈として、 |
今のところヒホさん抜きで話が進んでいますが、COREのRust API & Python APIを実装しながら議論する、という今の流れはいいんじゃないかなと思っていることを表明しておきます。 余程複雑なAPIにしない限りはC APIも(ENGINEの)Web APIも後から考えられるはず。 |
フレーム数が良いと思います!
パッと正解が思いつかないですね。。試行錯誤して作っていく感じになるかも。 パディング、つまり音声を出力するために前後何フレーム余分に中間表現を入力する必要があるかですが、これはAPIには露出させない形を目指せると嬉しそうです。
返り値をクラスインスタンスにするの良いですね!!
良いと思います!! |
フレーム数単位にするならSynthesisIntermediateに実際のフレームレートを持たせた方がいいと思います、というのも記憶が正しければtts経由だとサンプリングレート取れないはずなので。(あとラッパー作るのも楽になる) |
これちょっと弱点があって、関数を実行するまでフレームレートがわからないんですよね。 個人的には別のとこに置くのが良いんじゃないかな~~~と思ってます。 |
24kHzから変える予定が無いのなら、グローバルな値として提示してもいいんじゃないかと思います。C APIなら 名前については、 |
たしかに、サンプリングレートもフレームレートも一旦固定で良いと思います! |
@Yosshi999 さんのおかげで、コア側でストリーミング生成(render)が可能になってきています!! ちょっと今後 compatible engineにどう実装するか
↑のために実装をどう変えるか
|
もう1点、これは @Yosshi999 さんがもしという感じなのですが、VOICEVOX ENGINEへの導入に向けた実装にご興味あったりしませんか!! ちなみにVOICEVOX ENGINEへの導入は3つステップがあって、必要な能力がちょっとずつ変わってくる感じです。 1つが↑でもあげていた、 2つ目がVOICEVOX ENGINEからコアの 3つ目がおそらく一番難しくて、VOICEVOX ENGINEから もしご興味あれば・・・!!! |
この本文は @qryxip が記述している。 #851 で生まれた`generate_full_intermediate`と`render_audio_segment`を用 いて次の公開APIを作る。`precompute_render`で`AudioFeature`を生成し、 `AudioFeature`と区間指定を引数とした`render`で指定区間のPCMを生成する 形。 - `voicevox_core::blocking::Synthesizer::precompute_render` - `voicevox_core::blocking::Synthesizer::render` - `voicevox_core::blocking::AudioFeature` また`render`で生成したPCMをWAVとして組み立てるため、次の公開APIも作る。 - `voicevox_core::wav_from_s16le` ただしこのPRで実装するのはRust APIとPython APIのみ。非同期API、C API、 Java APIについては今後実装する。Python APIのtype stubも今後用意する。ま たテストも今後書く。 Refs: #853 Co-authored-by: Ryo Yamashita <qryxip@gmail.com> Co-authored-by: Hiroshiba <hihokaruta@gmail.com> Co-authored-by: Nanashi. <sevenc7c@sevenc7c.com>
やってみます。実装順は上の通りで確定でいいですかね?とりあえずはdecode関数を |
うおーありがとうございます!!!
はい、この流れが良いかなと・・・!
ですね!! |
内容
音声を逐次的に生成する機能を提供し、長い文章の音声を生成する際のレイテンシの短縮をめざす。
関連
Pros 良くなる点
Cons 悪くなる点
実現方法
現在の音声合成処理(synthesis)はaudio queryを入力としてスペクトログラム生成 -> 音声波形生成の順に処理されており、前半と後半の処理時間の比は大体1:10くらいである。また、スペクトログラム生成は内部のモデルの仕様上audio query全体を入力する必要があるが、後半の音声波形生成は十分にマージンを取っていれば任意の位置から任意の長さの音声を生成することができる。
参考:
https://github.com/Yosshi999/streaming_hifigan
そこで、現在
decode
として処理されている関数を二つに分け、generate_full_intermediate
関数によってえられる中間表現(現状ではスペクトログラム)をいったんユーザーに返し、その中間表現と指定区間を入力として音声を生成するrender_audio_segment
関数によって最終的な音声を生成する。実装が必要なもの
struct Intermediate
: ユーザーにいったん返す中間表現。実態(スペクトログラム)には触れてほしくないが、lengthは後段の生成区間指定などのために参照可能にする必要がある。blocking::Synthesizer::synthesis_intermediate(&self, &AudioQuery, StyleId, &SynthesisOptions) -> Result<Intermediate>
: 現在のsynthesis()
の途中(decodeの前半部)までを実行する。現在音声が途切れる問題のworkaroundとして前後にパディングがついており、これを音声生成時に取り除くためパディング長をどこかで共有する必要がある。blocking::Synthesizer::render_audio_segment(&self, Intermediate, usize, usize) -> Result<Vec<u8>>
: 中間表現から指定した区間の音声を生成する。nonblocking::*
も必要?あるとうれしいもの
The text was updated successfully, but these errors were encountered: