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

新クラス設計API #370

Merged
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
8906f5a
新クラス設計を元にしたAPIたたき
qwerty2501 Jan 9, 2023
78c1a90
Update crates/voicevox_core/src/engine/model.rs
qwerty2501 Mar 12, 2023
b9f2897
Update crates/voicevox_core_c_api/src/lib.rs
qwerty2501 Mar 13, 2023
a92abc5
Update crates/voicevox_core_c_api/src/lib.rs
qwerty2501 Mar 13, 2023
6cba0ab
Update crates/voicevox_core_c_api/src/lib.rs
qwerty2501 Mar 13, 2023
6a7a842
Update crates/voicevox_core/src/inference_core.rs
qwerty2501 Mar 13, 2023
f243504
Update crates/voicevox_core/src/voice_synthesizer.rs
qwerty2501 Mar 13, 2023
71dd134
Handle::current()からRuntimeに変更
qwerty2501 Mar 13, 2023
bc5774b
dropがnew関数で実行されないように変更
qwerty2501 Mar 13, 2023
3bdc997
不要なasync blockを削除
qwerty2501 Mar 13, 2023
7573a3d
tokioをworkspace化
qwerty2501 Mar 13, 2023
c42978d
VvmRead,OpenFileの比較パターンを追加
qwerty2501 Mar 13, 2023
658ef26
file ioのエラーをハンドリングするように変更
qwerty2501 Mar 13, 2023
af6e7f7
VvmReadにsourceを持たせるようにした
qwerty2501 Mar 13, 2023
7a2d942
removed unused import
qwerty2501 Mar 13, 2023
367d75e
Lazy::newの中で初期化するように変更
qwerty2501 Mar 13, 2023
589d89f
compileエラーを修正
qwerty2501 Mar 13, 2023
4ab08a4
writeを使用するように変更
qwerty2501 Mar 13, 2023
53d19f0
Update crates/voicevox_core/src/result_code.rs
qwerty2501 Mar 13, 2023
1c5707a
format
qwerty2501 Mar 14, 2023
5c49035
コメントの説明間違いを修正
qwerty2501 Mar 14, 2023
f50d846
malloc/freeを使用するのをやめてBoxを使用するように変更した
qwerty2501 Mar 15, 2023
75d3ad8
Rename type names
qwerty2501 Mar 18, 2023
a392582
Merge branch 'main' into feature/new_class_design
qryxip Apr 27, 2023
8605d5e
Merge branch 'main' into feature/new_class_design
qryxip Apr 27, 2023
046fce5
Fix Clippy lints
qryxip Apr 30, 2023
2194a28
`compatible_engine`を復旧
qryxip Apr 30, 2023
630c6ce
C APIのE2Eテストを更新
qryxip Apr 30, 2023
30d025b
`log_mask`の正規表現を修正
qryxip May 1, 2023
ba1ca28
`init_logger`が必ず呼ばれるようにする
qryxip May 1, 2023
ed01b7c
コメントを更新
qryxip May 1, 2023
1ec3610
`RUNTIME`はderefする
qryxip May 1, 2023
1801fda
Blackをかける
qryxip May 1, 2023
2a9e77d
Revert "`RUNTIME`はderefする"
qryxip May 1, 2023
cadaa04
Revert "`init_logger`が必ず呼ばれるようにする"
qryxip May 1, 2023
7426351
`load_model_before_initialize`では`windows_video_cards`の表示は出さない
qryxip May 1, 2023
121aa1d
消えているべきだったpublish.rsが残っていたので消す
qryxip May 4, 2023
8e639fb
Merge branch 'main' into feature/new_class_design
qryxip May 4, 2023
2a28afa
metasの順序もテストする
qryxip May 5, 2023
709accb
`OpenJtalk`の実装をシンプルにする
qryxip May 5, 2023
28446b4
`StyleId`を`Copy`にする
qryxip May 5, 2023
379bc81
importの順序だけisort基準に
qryxip May 5, 2023
175cc64
`__all__`を更新
qryxip May 5, 2023
3e1fe27
_rust.pyiを修正
qryxip May 5, 2023
8f4b108
`Synthesizer.replace_mora_pitch`を追加
qryxip May 5, 2023
619a5db
Minor refactor
qryxip May 5, 2023
e7b7201
`VoiceModel.from_path`が`Path`を取れるようにする
qryxip May 5, 2023
9c7b566
__init__.pyを修正
qryxip May 5, 2023
787959e
`OpenJtalk`が`#[pymodule]`から抜けていたので入れる
qryxip May 5, 2023
de957bb
example/pythonを動くようにする
qryxip May 5, 2023
0faf6f7
抜けていた`#[no_mangle]`を付け加える
qryxip May 5, 2023
4ddba35
`tts`のE2Eテスト
qryxip May 5, 2023
c1ae9fb
Merge commit '9db8fef1f3b6ba0d8c3045c6697b431119056dcd' into feature/…
qryxip May 19, 2023
3ccb826
Black
qryxip May 19, 2023
7d1a85d
Merge commit 'ff7b5a88865d684132f5995ff456273f7cf18f52' into feature/…
qryxip May 20, 2023
8e65db1
Merge commit 'da84ce389b760877eb5b17663f0fae758bafc64c' into feature/…
qryxip May 20, 2023
002010d
Merge commit '546e1735e0719c70834e57546196f6a3377beef6' into feature/…
qryxip May 20, 2023
e40f157
Merge commit 'babce876011463927120e8cab908ad9eb160a2a2' into feature/…
qryxip May 20, 2023
c0fd40d
Merge commit '406f6c41408836840b9a38489d0f670fb960f412' into feature/…
qryxip May 20, 2023
dc54da2
Merge branch 'main' into feature/new_class_design
qryxip May 20, 2023
24a2b62
voicevox_core.hをアップデート
qryxip May 20, 2023
a12a709
Cargo.tomlのdiff部分を手動フォーマット
qryxip May 21, 2023
3f66e61
無駄な`async {}`を外す
qryxip May 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,127 changes: 149 additions & 978 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ thiserror = "1.0.37"
tracing = { version = "0.1.37", features = ["log"] }
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
voicevox_core = { path = "crates/voicevox_core" }
reqwest = { version = "0.11.13", default-features = false, features = ["rustls-tls", "stream"] }
tokio = {version="1.25.0",features=["rt","rt-multi-thread","macros","sync"]}
derive-getters = "0.2.0"

# min-sized-rustを元にrelease buildのサイズが小さくなるようにした
# https://github.com/johnthagen/min-sized-rust
Expand Down
4 changes: 2 additions & 2 deletions crates/download/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ octocrab = { git = "https://github.com/XAMPPRocky/octocrab.git", rev = "7db3611f
once_cell.workspace = true
platforms = "3.0.2"
rayon = "1.6.1"
reqwest = { version = "0.11.13", default-features = false, features = ["rustls-tls", "stream"] }
reqwest.workspace=true
strum = { version = "0.24.1", features = ["derive"] }
tokio = { version = "1.24.1", features = ["macros", "rt-multi-thread", "sync"] }
tokio.workspace=true
tracing.workspace = true
tracing-subscriber.workspace = true
url = "2.3.0"
Expand Down
9 changes: 6 additions & 3 deletions crates/voicevox_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ directml = ["onnxruntime/directml"]
[dependencies]
anyhow.workspace = true
cfg-if = "1.0.0"
derive-getters = "0.2.0"
derive-getters.workspace = true
derive-new = "0.5.9"
easy-ext.workspace = true
fs-err.workspace = true
Expand All @@ -25,15 +25,18 @@ thiserror.workspace = true
tracing.workspace = true
open_jtalk = { git = "https://github.com/VOICEVOX/open_jtalk-rs.git", rev="9edab53f0bfa877dbb37224d17fd0f3efbe32abd" }
regex = "1.6.0"
async_zip = { version ="0.0.11",features=["full"]}
futures = "0.3.26"
nanoid = "0.4.0"
tokio.workspace = true

[dev-dependencies]
rstest = "0.15.0"
pretty_assertions = "1.3.0"
async-std = { version = "1.12.0", features = ["attributes"] }
surf = "2.3.2"
flate2 = "1.0.24"
tar = "0.4.38"
heck = "0.4.0"
reqwest.workspace=true

[target."cfg(windows)".dependencies]
humansize = "2.1.2"
Expand Down
49 changes: 49 additions & 0 deletions crates/voicevox_core/src/devices.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use serde::{Deserialize, Serialize};

use super::*;

#[derive(Getters, Debug, Serialize, Deserialize)]
pub struct SupportedDevices {
cpu: bool,
cuda: bool,
dml: bool,
}

impl SupportedDevices {
/// サポートされているデバイス情報を取得する
pub fn get_supported_devices() -> Result<Self> {
let mut cuda_support = false;
let mut dml_support = false;
for provider in onnxruntime::session::get_available_providers()
.map_err(|e| Error::GetSupportedDevices(e.into()))?
.iter()
{
match provider.as_str() {
"CUDAExecutionProvider" => cuda_support = true,
"DmlExecutionProvider" => dml_support = true,
_ => {}
}
}

Ok(SupportedDevices {
cpu: true,
cuda: cuda_support,
dml: dml_support,
})
}

pub fn to_json(&self) -> serde_json::Value {
serde_json::to_value(self).expect("should not fail")
}
}

#[cfg(test)]
mod tests {
use super::*;
#[rstest]
fn supported_devices_get_supported_devices_works() {
let result = SupportedDevices::get_supported_devices();
// 環境によって結果が変わるので、関数呼び出しが成功するかどうかの確認のみ行う
assert!(result.is_ok(), "{result:?}");
}
}
2 changes: 1 addition & 1 deletion crates/voicevox_core/src/engine/full_context_label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ impl Utterance {
}

pub fn extract_full_context_label(
open_jtalk: &mut open_jtalk::OpenJtalk,
open_jtalk: &open_jtalk::OpenJtalk,
text: impl AsRef<str>,
) -> Result<Self> {
let labels = open_jtalk.extract_fullcontext(text)?;
Expand Down
97 changes: 59 additions & 38 deletions crates/voicevox_core/src/engine/open_jtalk.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use std::path::{Path, PathBuf};
use std::{
path::{Path, PathBuf},
sync::Mutex,
};

use ::open_jtalk::*;

use crate::Error;

#[derive(thiserror::Error, Debug)]
pub enum OpenJtalkError {
#[error("open_jtalk load error")]
Expand Down Expand Up @@ -47,55 +52,69 @@ impl PartialEq for OpenJtalkError {
pub type Result<T> = std::result::Result<T, OpenJtalkError>;

pub struct OpenJtalk {
mecab: ManagedResource<Mecab>,
njd: ManagedResource<Njd>,
jpcommon: ManagedResource<JpCommon>,
mecab: Mutex<ManagedResource<Mecab>>,
njd: Mutex<ManagedResource<Njd>>,
jpcommon: Mutex<ManagedResource<JpCommon>>,
qryxip marked this conversation as resolved.
Show resolved Hide resolved
dict_loaded: bool,
}

#[allow(unsafe_code)]
unsafe impl Send for OpenJtalk {}

#[allow(unsafe_code)]
unsafe impl Sync for OpenJtalk {}

impl OpenJtalk {
pub fn initialize() -> Self {
pub fn new_without_dic() -> Self {
Self {
mecab: ManagedResource::initialize(),
njd: ManagedResource::initialize(),
jpcommon: ManagedResource::initialize(),
mecab: Mutex::new(ManagedResource::initialize()),
njd: Mutex::new(ManagedResource::initialize()),
jpcommon: Mutex::new(ManagedResource::initialize()),
dict_loaded: false,
}
}

pub fn extract_fullcontext(&mut self, text: impl AsRef<str>) -> Result<Vec<String>> {
let result = self.extract_fullcontext_non_reflesh(text);
self.jpcommon.refresh();
self.njd.refresh();
self.mecab.refresh();
result
pub fn new_with_initialize(
open_jtalk_dict_dir: impl AsRef<Path>,
) -> crate::result::Result<Self> {
let mut s = Self::new_without_dic();
s.load(open_jtalk_dict_dir)
.map_err(|_| Error::NotLoadedOpenjtalkDict)?;
Ok(s)
}

fn extract_fullcontext_non_reflesh(&mut self, text: impl AsRef<str>) -> Result<Vec<String>> {
pub fn extract_fullcontext(&self, text: impl AsRef<str>) -> Result<Vec<String>> {
let mut jpcommon = self.jpcommon.lock().unwrap();
let mut njd = self.njd.lock().unwrap();
let mut mecab = self.mecab.lock().unwrap();

jpcommon.refresh();
njd.refresh();
mecab.refresh();

let mecab_text =
text2mecab(text.as_ref()).map_err(|e| OpenJtalkError::ExtractFullContext {
text: text.as_ref().into(),
source: Some(e.into()),
})?;
if self.mecab.analysis(mecab_text) {
self.njd.mecab2njd(
self.mecab
if mecab.analysis(mecab_text) {
njd.mecab2njd(
mecab
.get_feature()
.ok_or(OpenJtalkError::ExtractFullContext {
text: text.as_ref().into(),
source: None,
})?,
self.mecab.get_size(),
mecab.get_size(),
);
self.njd.set_pronunciation();
self.njd.set_digit();
self.njd.set_accent_phrase();
self.njd.set_accent_type();
self.njd.set_unvoiced_vowel();
self.njd.set_long_vowel();
self.jpcommon.njd2jpcommon(&self.njd);
self.jpcommon.make_label();
self.jpcommon
njd.set_pronunciation();
njd.set_digit();
njd.set_accent_phrase();
njd.set_accent_type();
njd.set_unvoiced_vowel();
njd.set_long_vowel();
jpcommon.njd2jpcommon(&njd);
jpcommon.make_label();
jpcommon
.get_label_feature_to_iter()
.ok_or_else(|| OpenJtalkError::ExtractFullContext {
text: text.as_ref().into(),
Expand All @@ -110,15 +129,19 @@ impl OpenJtalk {
}
}

pub fn load(&mut self, mecab_dict_dir: impl AsRef<Path>) -> Result<()> {
let result = self.mecab.load(mecab_dict_dir.as_ref());
fn load(&mut self, open_jtalk_dict_dir: impl AsRef<Path>) -> Result<()> {
let result = self
.mecab
.lock()
.unwrap()
.load(open_jtalk_dict_dir.as_ref());
if result {
self.dict_loaded = true;
Ok(())
} else {
self.dict_loaded = false;
Err(OpenJtalkError::Load {
mecab_dict_dir: mecab_dict_dir.as_ref().into(),
mecab_dict_dir: open_jtalk_dict_dir.as_ref().into(),
})
}
}
Expand Down Expand Up @@ -225,28 +248,26 @@ mod tests {
#[rstest]
#[case("",Err(OpenJtalkError::ExtractFullContext{text:"".into(),source:None}))]
#[case("こんにちは、ヒホです。", Ok(testdata_hello_hiho()))]
#[async_std::test]
#[tokio::test]
async fn extract_fullcontext_works(
#[case] text: &str,
#[case] expected: super::Result<Vec<String>>,
) {
let open_jtalk_dic_dir = download_open_jtalk_dict_if_no_exists().await;
let mut open_jtalk = OpenJtalk::initialize();
open_jtalk.load(&open_jtalk_dic_dir).unwrap();
let open_jtalk = OpenJtalk::new_with_initialize(open_jtalk_dic_dir).unwrap();
let result = open_jtalk.extract_fullcontext(text);
assert_eq!(expected, result);
}

#[rstest]
#[case("こんにちは、ヒホです。", Ok(testdata_hello_hiho()))]
#[async_std::test]
#[tokio::test]
async fn extract_fullcontext_loop_works(
#[case] text: &str,
#[case] expected: super::Result<Vec<String>>,
) {
let open_jtalk_dic_dir = download_open_jtalk_dict_if_no_exists().await;
let mut open_jtalk = OpenJtalk::initialize();
open_jtalk.load(&open_jtalk_dic_dir).unwrap();
let open_jtalk = OpenJtalk::new_with_initialize(&open_jtalk_dic_dir).unwrap();
for _ in 0..10 {
let result = open_jtalk.extract_fullcontext(text);
assert_eq!(expected, result);
Expand Down
Loading