-
Notifications
You must be signed in to change notification settings - Fork 309
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
[project-s] 歌ボ形式で歌声合成する機能を追加 #1255
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ほぼLGTMです!!!
いろいろコメントしていますが、必ず直すべきみたいな部分はなかったと思います!
将来的な設計の話ですが、「合成し終わってから再生」したいユーザーも居るかもとかちょっと思いました!
その場合今の設計だと「合成し終わっているか」を取得しにくいかも?と思いました。
これはただの感想ですが、Phrase作成即合成で再生までの時間を縮めようとすると、合成のキャンセル機能が欲しくなりますね・・・ 😇
constructor(audioPlayer: AudioPlayer, audioEvents: AudioEvent[]) { | ||
this.audioPlayer = audioPlayer; | ||
this.audioEvents = audioEvents; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
なるほどです、設計がなんとなく見えてきた気がします!
AudioSequenceがAudioPlayerを持つ設計ではなく、AudioSequenceを持つ誰かがAudioPlayerを1つだけ持つ設計にすると、Playerが散らばらずに1箇所に集まるので管理しやすい・・・かも・・・・・?
いやでも一様に扱えるので今の設計もありかも・・・?
まあ設計をガチャガチャ変えながら実装するよりも、一旦とりあえず全部実装してみてあとで整理して再設計するのが良いのかなと思いました。
なのでとりあえず問題なく動いているなら今は一旦良し・・・!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Transportで全てのイベントのスケジューリングを行うためにこの形になっていますが、私も「AudioSequenceを持つ誰かがAudioPlayerを1つだけ持つ」形のほうが自然な気がするので、後でまた設計を検討・試行したいと思います!
おそらく「AudioSequenceを持つ誰か」がそれぞれスケジューリングを行うことになり、そのスケジューリングの実行をTransportが管理することになると思います。
(一応今の設計でもループやマルチトラックの実装は可能です)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!!
データ構造が入り組んできたなというのが正直な感想です!
ぶっちゃけどういう構造が良いのかわからないので、とりあえず動くものを完成させてからいろいろ議論するのが良いのかなと思いました!
「ストレスフリーに動くようにする」というラスボスタスクが現れるまでは、まあだましだまし進めていくのが良いのかな~と。
(そういう意味で、Phraseも3段階キャッシュ構造をなくしても良いかもとちょっと思いました。このあたりはかなり理解できてる気がするので、どちらでも・・・!)
@Hiroshiba
ひとまずaudioQueryCacheを削除して、allPhrasesとaudioBufferCacheのみにしてみました。
再生時のUIの更新などで、どこかでポーリングすることになるので、そこで「合成し終わっているか」を判定しても良いかもと思っています。 |
なるほどです! |
直前で作っている形で、コードが読みやすくなって一旦良いのかなと思いました!! これはただの所感なのですが、データ構造は「全体scoreからたくさんのphraseが作られる」というのが今の形だと思うのですが、「たくさんのphraseがあって全体scoreが作られる」形にしていくのが良いのかなとちょっと感じています。 ユーザーが操作するのは全体scoreではなくphraseである、みたいな。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sigprogramming
大変遅くなり失礼いたしました、LGTMです!!
また、おてすきで以下でもし大きく動作把握誤りがあればおしらせください…!
(しっかり読めていないやもしれず…)
Transport: 各Sequence(Note/Audioの両方)のスケジューリング・イベント管理
AudioSequence: ボイス用Sequence/イベントの集合
Phrase: エンジン側に渡すクエリ・再生タイミング・オーディオバッファ
RENDERの動作:
- (プリプロセス/重複ノートの削除や長いノートの修正など)
- Phrase群の更新
- Phraseのクエリ(ハッシュ)が追加・変更されていたらクエリを(再)作成し合成
- RENDERのdispatch時にすでにレンダリングが行われていた場合、中止し新しいリクエストからレンダリング
上記から、以下のタイミングで再合成される(Noteの場合はPhrase単位で該当部のみ変更)
- Singer変更
- Score作成・変更
- Note追加・変更・削除
- Tempo変更
再生やシーク時はTransportのスケジューリングに沿ってAudioSequenceのイベント実行
@romot-co
ここは、以下の流れになっています…!
また、拍子は音声の合成に関係しませんが、ひとまず拍子が変更された場合もレンダリング(再合成)が行われるようになっています…! |
@Hiroshiba フレーズに分割するのは、分割してレンダリングするため(必要な部分だけレンダリングするため)で、
この2つは意味的に異なるので、まとめて「フレーズ」として扱わない方が良いかも…?と思いました…! |
あーーーー なるほどです、ユーザーやプログラムにとって都合の良い区間単位と、エンジンにとって都合の良い単位(今はPhrase)が異なる場合があるということですよね。たしかにです!! |
approveが揃っていそうなのでマージさせて頂きます!! |
内容
歌ボ形式で歌声合成(レンダリング)する機能を追加します。
長いノートは、長音で伸ばすなど色々試したのですが上手く合成できなかったので、
とりあえずノート自体を短くするようにしています。
また、高い音(C5くらいから)も上手く合成できませんが、
とりあえずノートナンバーから算出した値をそのままピッチに設定しています。
関連 Issue
ref #1254