Skip to content
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

テキスト音声合成ライブラリの作成 #1

Closed
Hiroshiba opened this issue Dec 2, 2021 · 58 comments
Closed

テキスト音声合成ライブラリの作成 #1

Hiroshiba opened this issue Dec 2, 2021 · 58 comments

Comments

@Hiroshiba
Copy link
Member

テキスト音声合成ができる薄いライブラリを作る計画です。
今エンジンとコアに機能が分離しているので、これらをうまいことまとめる必要があります。

@Hiroshiba
Copy link
Member Author

最初に要議論で、議論はこちらで行われています

@Hiroshiba Hiroshiba changed the title テキスト音声合成ライブラリの作成 多言語対応したテキスト音声合成ライブラリの作成 Dec 2, 2021
@Hiroshiba Hiroshiba changed the title 多言語対応したテキスト音声合成ライブラリの作成 いろんなプログラミング言語に対応したテキスト音声合成ライブラリの作成 Dec 2, 2021
@Hiroshiba Hiroshiba changed the title いろんなプログラミング言語に対応したテキスト音声合成ライブラリの作成 C++製のテキスト音声合成ライブラリの作成 Feb 8, 2022
@Hiroshiba
Copy link
Member Author

Hiroshiba commented Feb 8, 2022

このプロジェクトの内容を「C++ TTSライブラリ化」に軌道修正し、本格的に稼働したいです。

C++ TTSライブラリができると嬉しいことはこんな感じです。

  • 別言語に組み込みやすくなる
    • ので、例えば動画作成ツールで気軽に連携してもらえる
    • discordのbot作成などの趣味プログラミングで採用されやすくなる
    • スマホ移植やwebフロント移植などもしやすくなる

どこまでできるようにすべきかですが、まず初手は単純なTTS(文字→音声)ができるライブラリにするのが良いかなと思います。

  • 単純なTTS(文字→音声)の実装

その次が迷っているのですが、AquesTalk記法を使用可能にするか、中間表現(エンジンのQuery)を修正できるレベルを目指したいです。

  • AquesTalk記法の実装
  • 中間表現(エンジンのQuery)のやりとりを実装

モーフィング機能・辞書編集機能などは一旦保留にして上記2つを注力すれば良いのかなと思っています。

@qwerty2501
Copy link

どのように配布するつもりでいますか? DLLでしょうか?
またAPIをどうする想定でいますか?(素朴な C APIを定義しFFIされる想定か、そうではないか)

別言語に組み込みやすくなる

これは各言語ごとにラッパーライブラリができて初めて成立すると思うので、C++製ライブラリ+ラッパーライブラリの作成を行う必要がありそうです。

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Feb 10, 2022

配布は今のVOICEVOX COREと同じで、動的ライブラリの形式を考えています。
APIも今のコアと同じでexternすれば良いのかなと思っています。(こちらは単純にそれ以外の方法に関する知識がなく。。)

言語ごとにラッパーライブラリが作れると嬉しいですね!!
あとあとエンジンでも活用できると嬉しいので、特にpythonラッパーは作るモチベーションがありそうです。
とりあえずこのissueはC++ライブラリの作成を目指したいです。
1つめのマイルストーンの単純なTTS(文字→音声)の実装ができてインターフェースが定まり次第、ラッパーを作り始めても良いかもですね!

@qwerty2501
Copy link

qwerty2501 commented Feb 10, 2022

そういえば以前コメントしたこれを検討しても良いかもしれませんがどうしましょうかね。
とりあえず何も使わずにC APIでの公開にしておきますか?
C APIで動的ライブラリとして公開するならstruct情報を隠蔽して公開する必要がありそうですね。(この場合将来的にQueryの修正レベルのことをできるようにするなら、恐らくライブラリのユーザーにheapメモリ管理をさせなければならないでしょう。)

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Feb 11, 2022

SWIGも面白そうです。本格的に多言語展開する際にぜひ検討したいですね!
初手はとりあえずC APIとして公開を目指しましょう。同時並行で調査しておくと良いかも?

struct情報に関しては・・・あ、今のエンジンみたくjsonでやり取りするというのはどうでしょう。
エラーメッセージのとこみたく、ライブラリ側でjson文字列のメモリを確保してアドレスを返し、その解放はライブラリ側が担当するとか・・・
いやこうすると並列で取得したときにおかしくなりますね・・・うーん、できればメモリ確保の手間は避けられるようにしたいですが、なにか良い方法ないですかね・・・

@qwerty2501
Copy link

qwerty2501 commented Feb 11, 2022

SWIGについて少し調べましたが、Swift/Objective-Cの出力がサポートされてないようなのでスマホターゲットを考慮するとiOSをどうするかSWIGを使うにしても考えなければならなそうです。

エラーメッセージのとこみたく、ライブラリ側でjson文字列のメモリを確保してアドレスを返し、その解放はライブラリ側が担当するとか・・・
いやこうすると並列で取得したときにおかしくなりますね・・・うーん、できればメモリ確保の手間は避けられるようにしたいですが、なにか良い方法ないですかね・・・

coreのエラーメッセージのやつですよね。あれはおっしゃってるとおり並列で取得したときにおかしくなるので絶対にやめたほうが良いと思います。
structのフィールドを絶対に変えないという確信がある場合はstructを公開してもよいかもですが、その場合でも文字列用に確保したheapメモリの管理をしなければならず、どのみち手間になります。手間というよりは危険というべきかもですが。

C APIでDLLを扱う場合は、ライブラリの構造体用に確保したメモリの管理操作はユーザー側で行うのが一般的ではあるので、これを避けたければwrapperを提供し、その内部でメモリの管理を行うアプローチが良いのではないでしょうか?

SWIGだと定義したclass/structを指定するとそのコードを各言語用に出力できるようなので、そのあたりのwrapper処理コードを自動で出力してくれそうです。

@Hiroshiba
Copy link
Member Author

SWIG、面白そうなのですが、ライセンスがGPLなので厳しそうでした。。。

一旦SWIGから離れて、最適解を探せればと思いました。

いま問題なのは、「可変長のメモリサイズが必要なパラメータを返すのはどうすればいいか」だという認識です。
C APIで実装するなら、よくある方法だと

  1. メモリサイズを返す
  2. mallocしてもらう
  3. memcpyする

でしょうか。
ユーザー側もこちらの実装側もちょっと手間ですが、この方法以外思いつかないのであればこの方法しかないのかなと感じました。。

@y-chan
Copy link
Member

y-chan commented Feb 12, 2022

C APIに関して、以前AquesTalk10のNode.jsラッパーを書いたことがあり、AquesTalkがwavを生成する際はメモリアドレスとメモリサイズを返す、を行っていました。
また、AquesTalkに関して言えばメモリの解放もAquesTalk側が担っていました(AquesTalk_FreeWave関数が存在します)
なので、AquesTalk側でいったんメモリを確保してもらい、AquesTalk側で確保されたメモリのアドレスとサイズを元にmalloc/memcpyし、FreeWaveを実行していました。

https://github.com/y-chan/node-aquestalk10/blob/380581872273c341af23af230db38cbebfcdd804/aquestalk10.cc#L181-L188

他言語ラッパーを書く際に、Cの要素を他言語のものに変換する(上の例であればNapi::Buffer<uint8_t>::Copyなどの)必要が出てきそうだとも思いました。
なので、前に倣えにはなりますが、

  1. ライブラリ側で勝手にメモリを確保し、それらの情報(アドレス・サイズ)を返す
  2. それらをコピーして使ってもらう前提にする
  3. ライブラリ側にメモリ解放関数を用意しておき、コピーした(使った)後は解放してもらうようにする

が良いかなと思いました。

@qwerty2501
Copy link

qwerty2501 commented Feb 12, 2022

@Hiroshiba ライセンスGPLってSWIG自体ですよね?SWIGはライブラリではなくコード生成なので大丈夫な気がします(要調査)
ただ一旦C APIでやるという点については私も賛成です。

ちょっと上手く伝わってなかったのですが、メモリ確保/開放はライブラリ側で関数用意するイメージですね。
ただCなので、開放はその関数を明示的にユーザーが呼び出してやるイメージです。
ユーザー側がメモリサイズを指定したり、標準ライブラリのmalloc/freeを呼び出す実装だと実装ミスが多くなりそうなので避けたほうが良さそうです。

この構造体実装を隠すテクニックは Opaqueポインタ とよばれてるので参考にしていただければ

この中で特に実装を隠さなければならないモチベーションが高いのは下記ですね

Person構造体に変化があるたびに、Person.hの呼び出し側で再コンパイル・再リンクが必要。 ビルドの時間が増加します。またライブラリ側と呼び出し側で異なる定義のPerson構造体を想定している場合、リンクすると危険なことが起こるはずです。

DLLで配布した場合、動的にリンクされるので、例えばライブラリがバージョンアップして構造体の実装が変わった時にDLLのみ更新した場合危険な状態になります。

@Hiroshiba
Copy link
Member Author

では一旦C APIで・・・!
なるほどです、ライブラリ側でmalloc/freeを呼べば簡単という発想がなかったのでちょっと勘違いしてしまいました。
y-chanさんも仰ってる通り、ライブラリ側でmalloc/freeするのが良いと思います!

構造体の件ですが、そもそもデータの型がコード(header.h)に、データの内容がバイナリにある状態を避けたいかもです。
仰るとおりバージョンがずれるリスクがあります。
ので、データの形と、データの中身どちらも返す機構にしたいです。
一番手っ取り早いのはエンジンみたいにjson stringを返す方法かなと思っていますが、どうでしょう。

@qwerty2501
Copy link

qwerty2501 commented Feb 12, 2022

あまり一般的なアプローチではないのでユーザーからは違和感は持たれそうです。open jtalkのlabel formatが文字列で返されましたが、あれと似たような違和感があるかと

そもそもデータの型がコード(header.h)データの内容がバイナリにある状態を避けたいかもです

Opaqueポインタを使えばこれは達成できると思いますが、json文字列にしたいモチベーションは何でしょうか?
すみませんバイナリにある状態を避けたいということは、そもそもユーザーから見えるところ以外でも型定義をしたくないということでしょうか?隠れていれば問題ないと考えているのですが、モチベーションは何でしょうか?

データの形と、データの中身どちらも返す機構にしたいです

データの形とは何でしょう?

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Feb 12, 2022

そもそもstructは避けたいモチベーションがある感じです。

Python用にCythonでCラッパーを書いて思ったのですが、structやvectorなどのCの独自言語仕様があるとコンパイルが面倒なんですよね・・・
ラッパーを書くための専用の記法や変換規則を習得する必要がありました(ユーザーのモチベーションをくじいてしまう)。
https://qiita.com/shunsukeaihara/items/7a31a3379936611cb9ee#cdef-struct%E3%81%97%E3%81%A1%E3%82%83%E3%81%86%E5%A0%B4%E5%90%88
なので、文字列をよしなに解釈するほうが楽かもです。
もちろんユーザーにとって一番嬉しいのは言語ごとにラッパーがあることですが、とりあえずC APIを作るなら一旦文字列を返す方がユーザーにとって楽かなと思います。

あとそういえば、返したい中間パラメータはAudioQueryなのですが、これは内部で可変長の値を持つのでそもそもstructは無理かもです。
(structの中でvectorなどを使わずに可変長の値持つのってできましたっけ・・・?)

@Segu-g
Copy link
Member

Segu-g commented Feb 12, 2022

もちろんユーザーにとって一番嬉しいのは言語ごとにラッパーがあることですが、とりあえずC APIを作るなら一旦文字列を返す方がユーザーにとって楽かなと思います。

ここで想定されているユーザーとはラッパー製作者の方でしょうか,それともライブラリの利用者の方でしょうか.
恐らく,言語にかなり熟達しないと一般の開発者はラッパーなしに動的ライブラリとの連携は難しいような気がします.
一方,,ラッパー製作者はjsonエンコードされたデータ文字列を渡されるよりstructを渡してもらった方がインターフェースを構築するのは楽な筈です.
無論,stringをそのまま渡すだけのライブラリなら簡単に作れるかもしれませんがそのために利用者にjsonのパースを求めるのは天秤が釣り合っていないように感じます.

structの中でvectorなどを使わずに可変長の値持つのってできましたっけ・・・?

C言語で可変長の値を持つには配列(mallocで確保するメモリへのポインタ) を用います. reallocやfree等がデストラクタとして実装できないので面倒ですがC APIなら仕方ないところがあると思います.

@qwerty2501
Copy link

@Hiroshiba

Python用にCythonでCラッパーを書いて思ったのですが、structやvectorなどのCの独自言語仕様があるとコンパイルが面倒なんですよね・・・

これはOpaqueポインタで隠蔽すれば発生しない問題ですよね。

あとそういえば、返したい中間パラメータはAudioQueryなのですが、これは内部で可変長の値を持つのでそもそもstructは無理かもです。

これもOpaqueポインタで隠蔽すれば内部での実装はC++を使えるため、structフィールドとしてvectorを使用可能です。代わりにアクセサ用の関数を結構生やしてあげる必要はありますが
mallocでもできますが、この文脈ではわざわざ危険を犯してまでvectorを使わずにmallocする必要はないと思います。

@Hiroshiba
Copy link
Member Author

実際のユーザーの方(ライブラリの利用者)を想定していました!
たしかにラッパーがないと利用はかなり難しそうです。

ので、たしかに(ラッパー製作者も含めた)C++ユーザーから使いやすい形が良さそうに感じました!
structが良さそうです!

いろいろ議論していて、中間パラメータ(struct)周りは @qwerty2501 さんにおまかせできるとすごく嬉しいのかなと感じました!!!

  • 単純なTTS(文字→音声)の実装
  • AquesTalk記法の実装

の2つを @y-chan さんにお願いし、

  • 中間表現(エンジンのQuery)のやりとりを実装

@qwerty2501 さんにお願いできればおそらく最高かと思ったのですが、どうでしょう・・・?👀

@qwerty2501
Copy link

OKです。
私が担当するのは外部公開用の関数実装と、やりとりするための型定義でいいですかね?
Query機能の実装も必要ですか?

@y-chan
Copy link
Member

y-chan commented Feb 12, 2022

言語にかなり熟達しないと一般の開発者はラッパーなしに動的ライブラリとの連携は難しい

一方,,ラッパー製作者はjsonエンコードされたデータ文字列を渡されるよりstructを渡してもらった方がインターフェースを構築するのは楽

私もこれに同意です。C++ライブラリを誰でも使えることを目指すよりも、ラッパーライブラリを作りやすくする方が汎用性が高いはずなので、structを使うのがきれいに収まるかなと思いました。

  • 単純なTTS(文字→音声)の実装
  • AquesTalk記法の実装

問題ないです。現状のエンジンを元に、structの定義等を軽く作ってしまうと思うので、それをqwertyさんに中間表現出力用にいじってもらう形になるかなぁと思いました。

@Segu-g
Copy link
Member

Segu-g commented Feb 12, 2022

これもOpaqueポインタで隠蔽すれば内部での実装はC++を使えるため、structフィールドとしてvectorを使用可能です。代わりにアクセサ用の関数を結構生やしてあげる必要はありますが
mallocでもできますが、この文脈ではわざわざ危険を犯してまでvectorを使わずにmallocする必要はないと思います。

実際にライブラリを開発していくにあたって恐らく外部からQueryの中身を操作したいという欲求が出てくるはずです. ABIを維持するTTSライブラリとABIが変わるSynthesisライブラリ等で分けることもできると思います.
この時, 外部にデータを渡せるCの構造体とコンパイラなどに依存してしまうC++のクラスではかなり勝手が変わってしまうと思います. 前者では不透明参照を解決してあげるだけで外部からデータを見ることができますが,後者ではわざわざアクセサ関数を提供しないといけません.

その時になってから考えても良いとは思いますが,外部に出しうる構造体についてはクラスを使わずに構造体で書いた方が良い思うのですがどうでしょうか?

追記

ABIレベルで後方互換性を確保すべきかは分からないですが,アクセサ関数を提供する形はstructのlayoutに依存しないのでもしかしたら前方互換性が確保できるかも? ABIが変わってるのにロードできるのもそれはそれで怖そうですが・・・

@Hiroshiba
Copy link
Member Author

@y-chan @qwerty2501 お二人ともありがとうございます!!

私が担当するのは外部公開用の関数実装と、やりとりするための型定義でいいですかね?
Query機能の実装も必要ですか?

とりあえず外部公開用の関数実装と、やりとりの型定義をお願いしたいです!
(そこまでいけばみんなコミットできそうなので)

全Query機能の実装は大変な一方、openjtalkが無くても音声合成できるだけの情報・機能があると嬉しそう・・・?
ちょっとパラメータをリストアップしてみました。

class Mora:
    text: str = Field(title="文字")
    consonant: Optional[str] = Field(title="子音の音素")
    consonant_length: Optional[float] = Field(title="子音の音長")
    vowel: str = Field(title="母音の音素")
    vowel_length: float = Field(title="母音の音長")
    pitch: float = Field(title="音高")

class AccentPhrase:
    moras: List[Mora] = Field(title="モーラのリスト")
    accent: int = Field(title="アクセント箇所")
    pause_mora: Optional[Mora] = Field(title="後ろに無音を付けるかどうか")
    is_interrogative: bool = Field(default=False, title="疑問系かどうか")

class AudioQuery:
    accent_phrases: List[AccentPhrase] = Field(title="アクセント句のリスト")
    prePhonemeLength: float = Field(title="音声の前の無音時間")
    postPhonemeLength: float = Field(title="音声の後の無音時間")

is_interrogativeメンバーはありますが、擬似疑問文機能は初手で無くても良いかなと思っています。
(もちろん初手で実装してしまっても・・・!)

ちょっと量が多そうであれば、一旦pitch系とlength系は省いて、音素系とアクセントとpauseを実装とかもありかなと思いました!

@qwerty2501
Copy link

qwerty2501 commented Feb 12, 2022

フィールド結構あるので、その分関数が多くなっちゃうんですが大丈夫ですかね?
正直DLLでの互換性保ちつつ他のやり方知らないので代替案は出せませんが・・・

@Hiroshiba
Copy link
Member Author

関数というのは外に出すAPIでしょうか 👀
APIの数は3個くらい増えるかなと思っていて、それくらいなら全然大丈夫だと思います。
内部の関数がいっぱい増えるのは仕方ないと思います・・・!

@qwerty2501
Copy link

qwerty2501 commented Feb 12, 2022

外に出すAPIですね。
structの実装を全て隠すので、アクセスさせたいフィールドがある場合はそのフィールドへのアクセサ関数を公開する必要があります。

例としては以下のような感じですね。関数名とかは結構適当です。

typedef struct VoicevoxMora_  VoicevoxMora;

char* voicevox_mora_get_text(VoicevoxMora* voicevox_mora);
void voicevox_mora_set_text(VoicevoxMora* voicevox_mora,char* text);
uint64_t voicevox_mora_get_pitch(VoicevoxMora* voicevox_mora);
void voicevox_mora_set_pitch(VoicevoxMora* voicevox_mora,uint64_t pitch);
...

こういう感じでユーザーにアクセスさせたいフィールド毎に関数を公開する必要があるので、フィールド数に比例して関数を公開する必要があり、結構な数になるかと

参考までに例えばgtkはそういう感じの関数定義になっています
https://docs.gtk.org/gtk3/class.Button.html#methods

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Mar 8, 2022

YMM4にCoeFontが初期搭載されるニュースが発表されました。
VOICEVOXが最初に到達できる未来だったかもしれず、正直とても悔しいです。
(思いつけず、不甲斐なくて本当に申し訳ないです・・・。)

VOICEVOXも同じこと(TTSシステムの同梱)が可能になる状態を、なるべく早く実現したいなと感じました。
そのための手がこのC++ライブラリ作成プロジェクトだと思います。

身勝手なのですが、ロードマップ(というか優先順位)を引き直せればと思います🙇
「Windows上でVOICEVOX.exeをインストールすることなくTTSが可能」 という状態を最速で目指すロードマップです。

高優先

  • とりあえず動くTTS関数(テキストを入力したら音声が出てくる)をマージする
    • とりあえずOSは何でもOK
  • Windowsで動くようにする
  • Windowsで動くC++用のサンプルコードを書く(example/cpp?)
  • ↑のドキュメントを書く
  • とりあえずプレリリースする
    • core.zip以外に、tts.zipを作って辞書を同梱する
    • このzipファイルを展開してこのコードを書けば動く、という状態を目指す

オプション

更にオプション

  • AudioQueryの対応
  • 辞書の軽量化
  • 辞書を消しても動くようにする(AquesTalk記法オンリー)
  • 辞書を同梱しない版のzipを作る
  • 日本語ディレクトリで動くかチェック
  • voicevox_library化(coreとは別にTTS機能があるライブラリ。coreをstatic参照してビルド時)

僕たちの今の立ち位置から、僕たちのスキルを合わせれば、おそらく2週間でリリースまで到達できると思います。
その立ち位置にいるのは間違いなくみんな(特に @y-chan さん)のおかげです。

コア開発に携わってくださったVOICEVOXチームの優秀なメンバー(敬称略 @Yosshi999 @Oyaki122 @y-chan @aoirint @PickledChair @qwerty2501 @Segu-g @shigobu )の皆様、もしよければお力をお借りしたいです。
どうか、どうかよろしくおねがいします・・・・・・!!🙇

@Hiroshiba
Copy link
Member Author

(Discordに書きたかったのですが今不調っぽいのでこちらで。。)
初手はおそらく @y-chan さんの、TTSを可能にするプルリクエストが最速かなと感じています。
マージしてしまえばあとはパラレルで動けるので、なるべく早くマージできるとすごく嬉しいです(急かしてしまって申し訳ないです。。)
お手数おかけしてしまうのですが、もしよければ何卒よろしくお願いいたします🙇

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Mar 9, 2022

すごく昔に作ったLite版モデルで音声合成してみました。

↓通常版

default.mp4

↓Lite版

Lite.mp4

onnxモデルのサイズは1/10程度に、生成速度は爆速になりますが、やっぱり品質は明確に落ちそうな印象です。
Lite版作成は実験としては進めますが、優先度はあまり高くせず進めようと思います。

@qwerty2501
Copy link

あまり状況を把握していないのですが、YMMってすでにvoicevox APIに対応してませんでしたっけ。
今あるengineを同梱する方向だとよくないんでしょうか

@Hiroshiba
Copy link
Member Author

ファイル容量がざっと300MBくらい違ったりします。
仮にVOICEVOXの軽量版ができれば(辞書を抜けば)50MBくらいになるので結構差がありそうです。
サーバーを起動するexeとdllだと取り回しやすさがだいぶ違うと思うので、なんにせよ早めに作りたいところです。

@Hiroshiba
Copy link
Member Author

@qwerty2501
あ、issueの内容とちょっと異なるフランクな話題はVOICEVOXのユーザーコミュニティdiscordサーバーを間借りして話していたりします。
かなり気軽にいろんな話ができるので、よかったらぜひ!
https://twitter.com/hk_coil424/status/1432351677026160641

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Mar 10, 2022

@y-chan さんのTTSできるコードがマージされました!
(本当にありがとうございます!!!)
https://github.com/VOICEVOX/voicevox_core/tree/cpp-library

どんどん機能実装&使い勝手を良くしていきたいので、もしよければプルリクエストお待ちしています!
(ブランチがmainではないのでご注意ください)

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Mar 11, 2022

オプション側のコード追加もじゃんじゃんやっていけると嬉しいですね・・・!

@Hiroshiba
Copy link
Member Author

製品版をビルドしてみました。TTSが動きました!

残りやりたいことはまだまだありますが、一段落だと思います。
C++のサンプルコード(example/cpp)実装や、テストの実装などが次の課題だと思います。
じゃんじゃん進めていけるととても嬉しいです。
#1 (comment)

@Hiroshiba
Copy link
Member Author

こちら、別言語で気軽に使えるようにしたり、いろんなサービスで気軽に利用できるようにしたりできると世界が変わってくると思うので、どんどん進めて行きたいかもです。

ここのリストのタスクを整理すると、これらがメインで残っていそうでした。

  • Windowsで動くC++用のサンプルコードを書く(example/cpp?)
  • ↑のドキュメントを書く
  • とりあえずプレリリースする

オプションとしてはこれらがありそうです。

もしよかったらぜひ・・・!

@shigobu
Copy link

shigobu commented Apr 1, 2022

Windowsで動くC++用のサンプルコード、Visual Studio(VSCodeで無い)のプロジェクトで良いなら、私作ります。

@Hiroshiba
Copy link
Member Author

おお!ぜひお願いします!!

@Hiroshiba
Copy link
Member Author

@shigobu さん、Windows用のサンプルありがとうございます!!
@Oyaki122 さんも、埋め込みありがとうございます!!

もう動的TTSライブラリのリリースができる気がします!
ただテストコードがまだだったり、linux用のサンプルコードがなかったりなのが少し不安ポイントでもあります。
引き続き、このあたりの実装を募集しています。

  • Mac・Linuxでも動くようにする
  • TTSのテストを書く
  • AquesTalk記法のテストを書く

よかったらぜひ!!

@PickledChair
Copy link
Member

  • Mac・Linuxでも動くようにする

今日 Mac・Linux 向けの小さなサンプルコードを書いてみていました(コマンドの引数で与えられたセリフから音声を生成し、audio.wav を生成する単純なものです)。問題なく動くようです。あとは CMake でビルドできるようにしたいと思って作業しています。

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Apr 25, 2022

おー!!ありがとうございます!!
もしよければプルリクエストお待ちしております・・・!

@Hiroshiba
Copy link
Member Author

Hiroshiba commented May 2, 2022

@PickledChair さん、ありがとうございます!!!
次のリリースで音声合成ライブラリができたことを胸を張ってリリースできそうです!!

もしC++でのテストに興味があるorできる方がいらっしゃったら、こちらをお願いできると将来的にリファクタリングしやすかったりで安心かもしれません。

  • TTSのテストを書く
  • AquesTalk記法のテストを書く

(詳しくないですが、Google Testというのが良さそうに感じています。)
https://rinatz.github.io/cpp-book/test-how-to-gtest/

@qwerty2501
Copy link

ちょうどユニットテストフレームワーク導入PR作ろうと思って調べてたんですが、Catch2もありかなとは感じました。
data driven testをやろうとすると書きやすさではこっちに軍配があがりそうかなと

@Hiroshiba
Copy link
Member Author

おお!!! PR、お待ちしています!!

Catch2、たしかにdata driven testをしやすそうに見えました。

日本語資料の有無でいうと、google testは調べると(なぜか)OpenCVが語ってくれていて頼りになりそうでした。
Catch2は英語のドキュメントとにらめっこすることになりそうですが、総合的にはこちらのほうが便利そうに感じました。

(google testとcatch2どっちも調べてたんですが、どちらもマクロまみれでテストがめちゃくちゃ書きづらそうだなと感じました・・・・・・・。これVSCodeで補完とか効くんですかね。。。
fixtureもclass定義で実現できるけど、C++のclass定義のややこしさがそのままテストの読みづらさになるので、メンテ大変になりそうだなと直感しました。。。)

@qwerty2501
Copy link

あほんとですね。OpenCVに何故か日本語ドキュメントがある。ただ公式ではない以上ドキュメントがいつまでメンテされるかわからないのであまり当てにはしないほうがよいかなとは思いました。すでに古い可能性もありますし。

google testとcatch2どっちも調べてたんですが、どちらもマクロまみれでテストがめちゃくちゃ書きづらそうだなと感じました・・・・・・・。これVSCodeで補完とか効くんですかね。。。

その2つ以外も含め主要なC++のUnit test frameworkは軒並みマクロに依存しまくってます。まあそういうものだと思って諦めてください。
VSCodeで補完効くかどうかは私はVSCode使ってないのでよくわからないですね。

google testの利点を上げるとすれば、メンテが打ち切られる可能性が限りなく0に近いことでしょうか。ただところどころレガシーな部分は目立つのでそのあたりを天秤にかけてどうかといったところですかね。

@Hiroshiba
Copy link
Member Author

こちらでC APIの改善に関して議論されています。

@Hiroshiba Hiroshiba changed the title C++製のテキスト音声合成ライブラリの作成 テキスト音声合成ライブラリの作成 Aug 8, 2022
@Hiroshiba
Copy link
Member Author

こちら、コアの言語がC++ではなくRustに変わったため、タイトルを変更いたしました。
・・・今思ったけど、もう完了としてしまっても良いかもしれませんね・・・。あとはTTS周りのテストくらい・・・?

@y-chan
Copy link
Member

y-chan commented Mar 17, 2023

こちらですが、一旦closeしてしまって、個別にIssueを立てる方針にしたいと思います。
理由としては、ほぼ全てのタスクが完了し、Rust化の恩恵でテストまで実装できているからです。(e2eテストは実装できてないけど、unitテストでも十分な気がする...?)
プレリリース・リリースについては、VOICEVOX Coreを一般的に配布できる形にはなってきていますが、Coreは現在新APIやクラス設計 (VOICEVOX/voicevox_core#280 VOICEVOX/voicevox_core#370)が進んでおり、多分それが完了するまでプレリリース・リリースはしないので、一旦無視して良いかなと思いました。
あと残っているタスクは辞書APIの同梱(VOICEVOX/voicevox_core#265)や、軽量音声合成モデルが挙げられますが、まあ個別にIssueが展開されていたり、OSSの範囲外だったりするので、このプロジェクトは完了としていいかなと思いました!

というわけで、一旦おつかれさまでした!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants