From c8b54bc45db0a6e7d8e612e4ffd18bc1c4ef1dc2 Mon Sep 17 00:00:00 2001 From: femshima <49227365+femshima@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:11:29 +0900 Subject: [PATCH 1/3] add test for full-context label and text analyzer --- Cargo.lock | 13 + Cargo.toml | 1 + crates/voicevox_core/Cargo.toml | 1 + .../src/engine/full_context_label.rs | 448 ++++++++++++++++++ crates/voicevox_core/src/engine/model.rs | 4 +- crates/voicevox_core/src/lib.rs | 5 + 6 files changed, 470 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cae922ff..2ecd9e6ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3206,6 +3206,18 @@ dependencies = [ "syn 1.0.102", ] +[[package]] +name = "rstest_reuse" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88530b681abe67924d42cca181d070e3ac20e0740569441a9e35a7cedd2b34a4" +dependencies = [ + "quote", + "rand 0.8.5", + "rustc_version 0.4.0", + "syn 2.0.38", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -4359,6 +4371,7 @@ dependencies = [ "rayon", "regex", "rstest", + "rstest_reuse", "serde", "serde_json", "tempfile", diff --git a/Cargo.toml b/Cargo.toml index 8500292a4..e1f5ecfba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,6 +62,7 @@ rayon = "1.6.1" regex = "1.10.0" reqwest = { version = "0.11.13", default-features = false } rstest = "0.15.0" +rstest_reuse = "0.6.0" serde = "1.0.145" serde_json = "1.0.85" serde_with = "3.3.0" diff --git a/crates/voicevox_core/Cargo.toml b/crates/voicevox_core/Cargo.toml index 36d501b06..1bb228e16 100644 --- a/crates/voicevox_core/Cargo.toml +++ b/crates/voicevox_core/Cargo.toml @@ -45,6 +45,7 @@ zip.workspace = true heck.workspace = true pretty_assertions.workspace = true rstest.workspace = true +rstest_reuse.workspace = true test_util.workspace = true tokio = { workspace = true, features = ["rt", "macros"] } diff --git a/crates/voicevox_core/src/engine/full_context_label.rs b/crates/voicevox_core/src/engine/full_context_label.rs index 79928d246..92eaa1d6e 100644 --- a/crates/voicevox_core/src/engine/full_context_label.rs +++ b/crates/voicevox_core/src/engine/full_context_label.rs @@ -338,3 +338,451 @@ impl Utterance { }) } } + +#[cfg(test)] +mod tests { + use rstest_reuse::*; + + use ::test_util::OPEN_JTALK_DIC_DIR; + use rstest::rstest; + + use crate::{ + engine::{open_jtalk::FullcontextExtractor, MoraModel}, + text_analyzer::{OpenJTalkAnalyzer, TextAnalyzer}, + AccentPhraseModel, + }; + + #[template] + #[rstest] + #[case( + "いぇ", + &[ + "xx^xx-sil+y=e/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:1_1%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_1/K:1+1-1", + "xx^sil-y+e=sil/A:0+1+1/B:xx-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:1_1#0_xx@1_1|1_1/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-1@1+1&1-1|1+1/J:xx_xx/K:1+1-1", + "sil^y-e+sil=xx/A:0+1+1/B:xx-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:1_1#0_xx@1_1|1_1/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-1@1+1&1-1|1+1/J:xx_xx/K:1+1-1", + "y^e-sil+xx=xx/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:1_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:1_1/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+1-1", + ], + &[ + AccentPhraseModel::new( + vec![MoraModel::new( + "イェ".into(), + Some("y".into()), + Some(0.0), + "e".into(), + 0.0, + 0.0, + )], + 1, + None, + false, + ) + ] + )] + #[case( + "んーっ", + &[ + "xx^xx-sil+N=N/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:3_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_3/K:1+1-3", + "xx^sil-N+N=cl/A:-2+1+3/B:xx-xx_xx/C:09_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_1|1_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-3@1+1&1-1|1+3/J:xx_xx/K:1+1-3", + "sil^N-N+cl=sil/A:-1+2+2/B:xx-xx_xx/C:09_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_1|1_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-3@1+1&1-1|1+3/J:xx_xx/K:1+1-3", + "N^N-cl+sil=xx/A:0+3+1/B:09-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_1|1_3/G:xx_xx%xx_xx_xx/H:xx_xx/I:1-3@1+1&1-1|1+3/J:xx_xx/K:1+1-3", + "N^cl-sil+xx=xx/A:xx+xx+xx/B:09-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:3_3!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:1_3/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+1-3", + ], + &[ + AccentPhraseModel::new( + vec![ + MoraModel::new( + "ン".into(), + None, + None, + "N".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ン".into(), + None, + None, + "N".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ッ".into(), + None, + None, + "cl".into(), + 0.0, + 0.0, + ) + ], + 3, + None, + false, + ), + ] + )] + #[case( + "これはテストです", + &[ + "xx^xx-sil+k=o/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:04+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:3_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:2_8/K:1+2-8", + "xx^sil-k+o=r/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "sil^k-o+r=e/A:-2+1+3/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "k^o-r+e=w/A:-1+2+2/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "o^r-e+w=a/A:-1+2+2/B:xx-xx_xx/C:04_xx+xx/D:24+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "r^e-w+a=t/A:0+3+1/B:04-xx_xx/C:24_xx+xx/D:03+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "e^w-a+t=e/A:0+3+1/B:04-xx_xx/C:24_xx+xx/D:03+xx_xx/E:xx_xx!xx_xx-xx/F:3_3#0_xx@1_2|1_8/G:5_1%0_xx_1/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "w^a-t+e=s/A:0+1+5/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "a^t-e+s=U/A:0+1+5/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "t^e-s+U=t/A:1+2+4/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "e^s-U+t=o/A:1+2+4/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "s^U-t+o=d/A:2+3+3/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "U^t-o+d=e/A:2+3+3/B:24-xx_xx/C:03_xx+xx/D:10+7_2/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "t^o-d+e=s/A:3+4+2/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "o^d-e+s=U/A:3+4+2/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "d^e-s+U=sil/A:4+5+1/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "e^s-U+sil=xx/A:4+5+1/B:03-xx_xx/C:10_7+2/D:xx+xx_xx/E:3_3!0_xx-1/F:5_1#0_xx@2_1|4_5/G:xx_xx%xx_xx_xx/H:xx_xx/I:2-8@1+1&1-2|1+8/J:xx_xx/K:1+2-8", + "s^U-sil+xx=xx/A:xx+xx+xx/B:10-7_2/C:xx_xx+xx/D:xx+xx_xx/E:5_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:2_8/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:1+2-8", + ], + &[ + AccentPhraseModel::new( + vec![ + MoraModel::new( + "コ".into(), + Some("k".into()), + Some(0.0), + "o".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "レ".into(), + Some("r".into()), + Some(0.0), + "e".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ワ".into(), + Some("w".into()), + Some(0.0), + "a".into(), + 0.0, + 0.0, + ), + ], + 3, + None, + false, + ), + AccentPhraseModel::new( + vec![ + MoraModel::new( + "テ".into(), + Some("t".into()), + Some(0.0), + "e".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ス".into(), + Some("s".into()), + Some(0.0), + "U".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ト".into(), + Some("t".into()), + Some(0.0), + "o".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "デ".into(), + Some("d".into()), + Some(0.0), + "e".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ス".into(), + Some("s".into()), + Some(0.0), + "U".into(), + 0.0, + 0.0, + ), + ], + 1, + None, + false, + ), + ] + )] + #[case( + "1、1000、100万、1億?", + &[ + "xx^xx-sil+i=ch/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:2_2%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_2/K:4+4-12", + "xx^sil-i+ch=i/A:-1+1+2/B:xx-xx_xx/C:05_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:2_2#0_xx@1_1|1_2/G:2_1%0_xx_0/H:xx_xx/I:1-2@1+4&1-4|1+12/J:1_2/K:4+4-12", + "sil^i-ch+i=pau/A:0+2+1/B:xx-xx_xx/C:05_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:2_2#0_xx@1_1|1_2/G:2_1%0_xx_0/H:xx_xx/I:1-2@1+4&1-4|1+12/J:1_2/K:4+4-12", + "i^ch-i+pau=s/A:0+2+1/B:xx-xx_xx/C:05_xx+xx/D:05+xx_xx/E:xx_xx!xx_xx-xx/F:2_2#0_xx@1_1|1_2/G:2_1%0_xx_0/H:xx_xx/I:1-2@1+4&1-4|1+12/J:1_2/K:4+4-12", + "ch^i-pau+s=e/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:2_2!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:2_1%0_xx_xx/H:1_2/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_2/K:4+4-12", + "i^pau-s+e=N/A:0+1+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_2!0_xx-0/F:2_1#0_xx@1_1|1_2/G:4_3%0_xx_0/H:1_2/I:1-2@2+3&2-3|3+10/J:1_4/K:4+4-12", + "pau^s-e+N=pau/A:0+1+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_2!0_xx-0/F:2_1#0_xx@1_1|1_2/G:4_3%0_xx_0/H:1_2/I:1-2@2+3&2-3|3+10/J:1_4/K:4+4-12", + "s^e-N+pau=hy/A:1+2+1/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_2!0_xx-0/F:2_1#0_xx@1_1|1_2/G:4_3%0_xx_0/H:1_2/I:1-2@2+3&2-3|3+10/J:1_4/K:4+4-12", + "e^N-pau+hy=a/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:2_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:4_3%0_xx_xx/H:1_2/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_4/K:4+4-12", + "N^pau-hy+a=k/A:-2+1+4/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "pau^hy-a+k=u/A:-2+1+4/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "hy^a-k+u=m/A:-1+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "a^k-u+m=a/A:-1+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "k^u-m+a=N/A:0+3+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "u^m-a+N=pau/A:0+3+2/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "m^a-N+pau=i/A:1+4+1/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:2_1!0_xx-0/F:4_3#0_xx@1_1|1_4/G:4_2%1_xx_0/H:1_2/I:1-4@3+2&3-2|5+8/J:1_4/K:4+4-12", + "a^N-pau+i=ch/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:05+xx_xx/E:4_3!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:4_2%1_xx_xx/H:1_4/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_4/K:4+4-12", + "N^pau-i+ch=i/A:-1+1+4/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "pau^i-ch+i=o/A:0+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "i^ch-i+o=k/A:0+2+3/B:05-xx_xx/C:05_xx+xx/D:05+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "ch^i-o+k=u/A:1+3+2/B:05-xx_xx/C:05_xx+xx/D:xx+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "i^o-k+u=sil/A:2+4+1/B:05-xx_xx/C:05_xx+xx/D:xx+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "o^k-u+sil=xx/A:2+4+1/B:05-xx_xx/C:05_xx+xx/D:xx+xx_xx/E:4_3!0_xx-0/F:4_2#1_xx@1_1|1_4/G:xx_xx%xx_xx_xx/H:1_4/I:1-4@4+1&4-1|9+4/J:xx_xx/K:4+4-12", + "k^u-sil+xx=xx/A:xx+xx+xx/B:05-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:4_2!1_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:1_4/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:4+4-12", + ], + &[ + AccentPhraseModel::new( + vec![ + MoraModel::new("イ".into(), None, None, "i".into(), 0.0, 0.0), + MoraModel::new( + "チ".into(), + Some("ch".into()), + Some(0.0), + "i".into(), + 0.0, + 0.0, + ), + ], + 2, + Some(MoraModel::new( + "、".into(), + None, + None, + "pau".into(), + 0.0, + 0.0, + )), + false, + ), + AccentPhraseModel::new( + vec![ + MoraModel::new( + "セ".into(), + Some("s".into()), + Some(0.0), + "e".into(), + 0.0, + 0.0, + ), + MoraModel::new("ン".into(), None, None, "N".into(), 0.0, 0.0), + ], + 1, + Some(MoraModel::new( + "、".into(), + None, + None, + "pau".into(), + 0.0, + 0.0, + )), + false, + ), + AccentPhraseModel::new( + vec![ + MoraModel::new( + "ヒャ".into(), + Some("hy".into()), + Some(0.0), + "a".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ク".into(), + Some("k".into()), + Some(0.0), + "u".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "マ".into(), + Some("m".into()), + Some(0.0), + "a".into(), + 0.0, + 0.0, + ), + MoraModel::new("ン".into(), None, None, "N".into(), 0.0, 0.0), + ], + 3, + Some(MoraModel::new( + "、".into(), + None, + None, + "pau".into(), + 0.0, + 0.0, + )), + false, + ), + AccentPhraseModel::new( + vec![ + MoraModel::new("イ".into(), None, None, "i".into(), 0.0, 0.0), + MoraModel::new( + "チ".into(), + Some("ch".into()), + Some(0.0), + "i".into(), + 0.0, + 0.0, + ), + MoraModel::new("オ".into(), None, None, "o".into(), 0.0, 0.0), + MoraModel::new( + "ク".into(), + Some("k".into()), + Some(0.0), + "u".into(), + 0.0, + 0.0, + ), + ], + 2, + None, + true, + ), + ] + )] + #[case( + "クヮルテット。あーあ、。", + &[ + "xx^xx-sil+kw=a/A:xx+xx+xx/B:xx-xx_xx/C:xx_xx+xx/D:02+xx_xx/E:xx_xx!xx_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:5_3%0_xx_xx/H:xx_xx/I:xx-xx@xx+xx&xx-xx|xx+xx/J:1_5/K:2+3-8", + "xx^sil-kw+a=r/A:-2+1+5/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "sil^kw-a+r=u/A:-2+1+5/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "kw^a-r+u=t/A:-1+2+4/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "a^r-u+t=e/A:-1+2+4/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "r^u-t+e=cl/A:0+3+3/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "u^t-e+cl=t/A:0+3+3/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "t^e-cl+t=o/A:1+4+2/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "e^cl-t+o=pau/A:2+5+1/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "cl^t-o+pau=a/A:2+5+1/B:xx-xx_xx/C:02_xx+xx/D:09+xx_xx/E:xx_xx!xx_xx-xx/F:5_3#0_xx@1_1|1_5/G:2_1%0_xx_0/H:xx_xx/I:1-5@1+2&1-3|1+8/J:2_3/K:2+3-8", + "t^o-pau+a=a/A:xx+xx+xx/B:02-xx_xx/C:xx_xx+xx/D:09+xx_xx/E:5_3!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:2_1%0_xx_xx/H:1_5/I:xx-xx@xx+xx&xx-xx|xx+xx/J:2_3/K:2+3-8", + "o^pau-a+a=a/A:0+1+2/B:02-xx_xx/C:09_xx+xx/D:09+xx_xx/E:5_3!0_xx-0/F:2_1#0_xx@1_2|1_3/G:1_1%0_xx_1/H:1_5/I:2-3@2+1&2-2|6+3/J:xx_xx/K:2+3-8", + "pau^a-a+a=sil/A:1+2+1/B:02-xx_xx/C:09_xx+xx/D:09+xx_xx/E:5_3!0_xx-0/F:2_1#0_xx@1_2|1_3/G:1_1%0_xx_1/H:1_5/I:2-3@2+1&2-2|6+3/J:xx_xx/K:2+3-8", + "a^a-a+sil=xx/A:0+1+1/B:09-xx_xx/C:09_xx+xx/D:xx+xx_xx/E:2_1!0_xx-1/F:1_1#0_xx@2_1|3_1/G:xx_xx%xx_xx_xx/H:1_5/I:2-3@2+1&2-2|6+3/J:xx_xx/K:2+3-8", + "a^a-sil+xx=xx/A:xx+xx+xx/B:09-xx_xx/C:xx_xx+xx/D:xx+xx_xx/E:1_1!0_xx-xx/F:xx_xx#xx_xx@xx_xx|xx_xx/G:xx_xx%xx_xx_xx/H:2_3/I:xx-xx@xx+xx&xx-xx|xx+xx/J:xx_xx/K:2+3-8", + ], + &[ + AccentPhraseModel::new( + vec![ + MoraModel::new( + "クヮ".into(), + Some("kw".into()), + Some(0.0), + "a".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "ル".into(), + Some("r".into()), + Some(0.0), + "u".into(), + 0.0, + 0.0, + ), + MoraModel::new( + "テ".into(), + Some("t".into()), + Some(0.0), + "e".into(), + 0.0, + 0.0, + ), + MoraModel::new("ッ".into(), None, None, "cl".into(), 0.0, 0.0), + MoraModel::new( + "ト".into(), + Some("t".into()), + Some(0.0), + "o".into(), + 0.0, + 0.0, + ), + ], + 3, + Some(MoraModel::new( + "、".into(), + None, + None, + "pau".into(), + 0.0, + 0.0, + )), + false, + ), + AccentPhraseModel::new( + vec![ + MoraModel::new("ア".into(), None, None, "a".into(), 0.0, 0.0), + MoraModel::new("ア".into(), None, None, "a".into(), 0.0, 0.0), + ], + 1, + None, + false, + ), + AccentPhraseModel::new( + vec![MoraModel::new( + "ア".into(), + None, + None, + "a".into(), + 0.0, + 0.0, + )], + 1, + None, + false, + ), + ] + )] + fn label_cases( + #[case] text: &str, + #[case] labels: &[&str], + #[case] accent_phrase: &[AccentPhraseModel], + ) { + } + + #[apply(label_cases)] + #[tokio::test] + async fn open_jtalk(text: &str, labels: &[&str], _accent_phrase: &[AccentPhraseModel]) { + let open_jtalk = crate::tokio::OpenJtalk::new(OPEN_JTALK_DIC_DIR) + .await + .unwrap(); + assert_eq!(&open_jtalk.extract_fullcontext(text).unwrap(), labels); + } + + #[apply(label_cases)] + #[tokio::test] + async fn extract_fullcontext( + text: &str, + _labels: &[&str], + accent_phrase: &[AccentPhraseModel], + ) { + let open_jtalk = crate::tokio::OpenJtalk::new(OPEN_JTALK_DIC_DIR) + .await + .unwrap(); + let analyzer = OpenJTalkAnalyzer::new(open_jtalk); + assert_eq!(analyzer.analyze(text).unwrap(), accent_phrase); + } +} diff --git a/crates/voicevox_core/src/engine/model.rs b/crates/voicevox_core/src/engine/model.rs index 77adbebe7..de0f388f9 100644 --- a/crates/voicevox_core/src/engine/model.rs +++ b/crates/voicevox_core/src/engine/model.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; /* 各フィールドのjsonフィールド名はsnake_caseとする*/ /// モーラ(子音+母音)ごとの情報。 -#[derive(Clone, Debug, new, Getters, Deserialize, Serialize)] +#[derive(Clone, Debug, new, Getters, Deserialize, Serialize, PartialEq)] pub struct MoraModel { /// 文字。 text: String, @@ -22,7 +22,7 @@ pub struct MoraModel { } /// AccentPhrase (アクセント句ごとの情報)。 -#[derive(Clone, Debug, new, Getters, Deserialize, Serialize)] +#[derive(Clone, Debug, new, Getters, Deserialize, Serialize, PartialEq)] pub struct AccentPhraseModel { /// モーラの配列。 moras: Vec, diff --git a/crates/voicevox_core/src/lib.rs b/crates/voicevox_core/src/lib.rs index f0a948354..c4b9834c3 100644 --- a/crates/voicevox_core/src/lib.rs +++ b/crates/voicevox_core/src/lib.rs @@ -24,6 +24,11 @@ pub mod tokio; #[cfg(test)] mod test_util; +// https://crates.io/crates/rstest_reuse#use-rstest_resuse-at-the-top-of-your-crate +#[allow(clippy::single_component_path_imports)] +#[cfg(test)] +use rstest_reuse; + pub use self::{ devices::SupportedDevices, engine::{AccentPhraseModel, AudioQueryModel, FullcontextExtractor}, From b6ab06a996d9372510cc0659b7a06527a806ca12 Mon Sep 17 00:00:00 2001 From: femshima <49227365+femshima@users.noreply.github.com> Date: Fri, 23 Feb 2024 08:01:30 +0900 Subject: [PATCH 2/3] reduce number of lines by wrapping MoraModel::new --- .../src/engine/full_context_label.rs | 279 +++--------------- 1 file changed, 47 insertions(+), 232 deletions(-) diff --git a/crates/voicevox_core/src/engine/full_context_label.rs b/crates/voicevox_core/src/engine/full_context_label.rs index 92eaa1d6e..733fb5dfd 100644 --- a/crates/voicevox_core/src/engine/full_context_label.rs +++ b/crates/voicevox_core/src/engine/full_context_label.rs @@ -352,6 +352,17 @@ mod tests { AccentPhraseModel, }; + fn mora_model(text: &str, consonant: Option<&str>, vowel: &str) -> MoraModel { + MoraModel::new( + text.into(), + consonant.map(|c| c.into()), + consonant.and(Some(0.0)), + vowel.into(), + 0.0, + 0.0, + ) + } + #[template] #[rstest] #[case( @@ -364,14 +375,7 @@ mod tests { ], &[ AccentPhraseModel::new( - vec![MoraModel::new( - "イェ".into(), - Some("y".into()), - Some(0.0), - "e".into(), - 0.0, - 0.0, - )], + vec![mora_model("イェ", Some("y"), "e")], 1, None, false, @@ -390,30 +394,9 @@ mod tests { &[ AccentPhraseModel::new( vec![ - MoraModel::new( - "ン".into(), - None, - None, - "N".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ン".into(), - None, - None, - "N".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ッ".into(), - None, - None, - "cl".into(), - 0.0, - 0.0, - ) + mora_model("ン", None, "N"), + mora_model("ン", None, "N"), + mora_model("ッ", None, "cl"), ], 3, None, @@ -446,30 +429,9 @@ mod tests { &[ AccentPhraseModel::new( vec![ - MoraModel::new( - "コ".into(), - Some("k".into()), - Some(0.0), - "o".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "レ".into(), - Some("r".into()), - Some(0.0), - "e".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ワ".into(), - Some("w".into()), - Some(0.0), - "a".into(), - 0.0, - 0.0, - ), + mora_model("コ", Some("k"), "o"), + mora_model("レ", Some("r"), "e"), + mora_model("ワ", Some("w"), "a"), ], 3, None, @@ -477,46 +439,11 @@ mod tests { ), AccentPhraseModel::new( vec![ - MoraModel::new( - "テ".into(), - Some("t".into()), - Some(0.0), - "e".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ス".into(), - Some("s".into()), - Some(0.0), - "U".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ト".into(), - Some("t".into()), - Some(0.0), - "o".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "デ".into(), - Some("d".into()), - Some(0.0), - "e".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ス".into(), - Some("s".into()), - Some(0.0), - "U".into(), - 0.0, - 0.0, - ), + mora_model("テ", Some("t"), "e"), + mora_model("ス", Some("s"), "U"), + mora_model("ト", Some("t"), "o"), + mora_model("デ", Some("d"), "e"), + mora_model("ス", Some("s"), "U"), ], 1, None, @@ -555,109 +482,39 @@ mod tests { &[ AccentPhraseModel::new( vec![ - MoraModel::new("イ".into(), None, None, "i".into(), 0.0, 0.0), - MoraModel::new( - "チ".into(), - Some("ch".into()), - Some(0.0), - "i".into(), - 0.0, - 0.0, - ), + mora_model("イ", None, "i"), + mora_model("チ", Some("ch"), "i"), ], 2, - Some(MoraModel::new( - "、".into(), - None, - None, - "pau".into(), - 0.0, - 0.0, - )), + Some(mora_model("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - MoraModel::new( - "セ".into(), - Some("s".into()), - Some(0.0), - "e".into(), - 0.0, - 0.0, - ), - MoraModel::new("ン".into(), None, None, "N".into(), 0.0, 0.0), + mora_model("セ", Some("s"), "e"), + mora_model("ン", None, "N"), ], 1, - Some(MoraModel::new( - "、".into(), - None, - None, - "pau".into(), - 0.0, - 0.0, - )), + Some(mora_model("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - MoraModel::new( - "ヒャ".into(), - Some("hy".into()), - Some(0.0), - "a".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ク".into(), - Some("k".into()), - Some(0.0), - "u".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "マ".into(), - Some("m".into()), - Some(0.0), - "a".into(), - 0.0, - 0.0, - ), - MoraModel::new("ン".into(), None, None, "N".into(), 0.0, 0.0), + mora_model("ヒャ", Some("hy"), "a"), + mora_model("ク", Some("k"), "u"), + mora_model("マ", Some("m"), "a"), + mora_model("ン", None, "N"), ], 3, - Some(MoraModel::new( - "、".into(), - None, - None, - "pau".into(), - 0.0, - 0.0, - )), + Some(mora_model("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - MoraModel::new("イ".into(), None, None, "i".into(), 0.0, 0.0), - MoraModel::new( - "チ".into(), - Some("ch".into()), - Some(0.0), - "i".into(), - 0.0, - 0.0, - ), - MoraModel::new("オ".into(), None, None, "o".into(), 0.0, 0.0), - MoraModel::new( - "ク".into(), - Some("k".into()), - Some(0.0), - "u".into(), - 0.0, - 0.0, - ), + mora_model("イ", None, "i"), + mora_model("チ", Some("ch"), "i"), + mora_model("オ", None, "o"), + mora_model("ク", Some("k"), "u"), ], 2, None, @@ -687,69 +544,27 @@ mod tests { &[ AccentPhraseModel::new( vec![ - MoraModel::new( - "クヮ".into(), - Some("kw".into()), - Some(0.0), - "a".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "ル".into(), - Some("r".into()), - Some(0.0), - "u".into(), - 0.0, - 0.0, - ), - MoraModel::new( - "テ".into(), - Some("t".into()), - Some(0.0), - "e".into(), - 0.0, - 0.0, - ), - MoraModel::new("ッ".into(), None, None, "cl".into(), 0.0, 0.0), - MoraModel::new( - "ト".into(), - Some("t".into()), - Some(0.0), - "o".into(), - 0.0, - 0.0, - ), + mora_model("クヮ", Some("kw"), "a"), + mora_model("ル", Some("r"), "u"), + mora_model("テ", Some("t"), "e"), + mora_model("ッ", None, "cl"), + mora_model("ト", Some("t"), "o"), ], 3, - Some(MoraModel::new( - "、".into(), - None, - None, - "pau".into(), - 0.0, - 0.0, - )), + Some(mora_model("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - MoraModel::new("ア".into(), None, None, "a".into(), 0.0, 0.0), - MoraModel::new("ア".into(), None, None, "a".into(), 0.0, 0.0), + mora_model("ア", None, "a"), + mora_model("ア", None, "a"), ], 1, None, false, ), AccentPhraseModel::new( - vec![MoraModel::new( - "ア".into(), - None, - None, - "a".into(), - 0.0, - 0.0, - )], + vec![mora_model("ア", None, "a")], 1, None, false, From d134b2252d933bfb11db1040c17f20dce52d12e5 Mon Sep 17 00:00:00 2001 From: femshima <49227365+femshima@users.noreply.github.com> Date: Fri, 23 Feb 2024 19:47:55 +0900 Subject: [PATCH 3/3] rename `mora_model` to `mora` --- .../src/engine/full_context_label.rs | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/crates/voicevox_core/src/engine/full_context_label.rs b/crates/voicevox_core/src/engine/full_context_label.rs index 733fb5dfd..edda52394 100644 --- a/crates/voicevox_core/src/engine/full_context_label.rs +++ b/crates/voicevox_core/src/engine/full_context_label.rs @@ -352,7 +352,7 @@ mod tests { AccentPhraseModel, }; - fn mora_model(text: &str, consonant: Option<&str>, vowel: &str) -> MoraModel { + fn mora(text: &str, consonant: Option<&str>, vowel: &str) -> MoraModel { MoraModel::new( text.into(), consonant.map(|c| c.into()), @@ -375,7 +375,7 @@ mod tests { ], &[ AccentPhraseModel::new( - vec![mora_model("イェ", Some("y"), "e")], + vec![mora("イェ", Some("y"), "e")], 1, None, false, @@ -394,9 +394,9 @@ mod tests { &[ AccentPhraseModel::new( vec![ - mora_model("ン", None, "N"), - mora_model("ン", None, "N"), - mora_model("ッ", None, "cl"), + mora("ン", None, "N"), + mora("ン", None, "N"), + mora("ッ", None, "cl"), ], 3, None, @@ -429,9 +429,9 @@ mod tests { &[ AccentPhraseModel::new( vec![ - mora_model("コ", Some("k"), "o"), - mora_model("レ", Some("r"), "e"), - mora_model("ワ", Some("w"), "a"), + mora("コ", Some("k"), "o"), + mora("レ", Some("r"), "e"), + mora("ワ", Some("w"), "a"), ], 3, None, @@ -439,11 +439,11 @@ mod tests { ), AccentPhraseModel::new( vec![ - mora_model("テ", Some("t"), "e"), - mora_model("ス", Some("s"), "U"), - mora_model("ト", Some("t"), "o"), - mora_model("デ", Some("d"), "e"), - mora_model("ス", Some("s"), "U"), + mora("テ", Some("t"), "e"), + mora("ス", Some("s"), "U"), + mora("ト", Some("t"), "o"), + mora("デ", Some("d"), "e"), + mora("ス", Some("s"), "U"), ], 1, None, @@ -482,39 +482,39 @@ mod tests { &[ AccentPhraseModel::new( vec![ - mora_model("イ", None, "i"), - mora_model("チ", Some("ch"), "i"), + mora("イ", None, "i"), + mora("チ", Some("ch"), "i"), ], 2, - Some(mora_model("、", None, "pau")), + Some(mora("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - mora_model("セ", Some("s"), "e"), - mora_model("ン", None, "N"), + mora("セ", Some("s"), "e"), + mora("ン", None, "N"), ], 1, - Some(mora_model("、", None, "pau")), + Some(mora("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - mora_model("ヒャ", Some("hy"), "a"), - mora_model("ク", Some("k"), "u"), - mora_model("マ", Some("m"), "a"), - mora_model("ン", None, "N"), + mora("ヒャ", Some("hy"), "a"), + mora("ク", Some("k"), "u"), + mora("マ", Some("m"), "a"), + mora("ン", None, "N"), ], 3, - Some(mora_model("、", None, "pau")), + Some(mora("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - mora_model("イ", None, "i"), - mora_model("チ", Some("ch"), "i"), - mora_model("オ", None, "o"), - mora_model("ク", Some("k"), "u"), + mora("イ", None, "i"), + mora("チ", Some("ch"), "i"), + mora("オ", None, "o"), + mora("ク", Some("k"), "u"), ], 2, None, @@ -544,27 +544,27 @@ mod tests { &[ AccentPhraseModel::new( vec![ - mora_model("クヮ", Some("kw"), "a"), - mora_model("ル", Some("r"), "u"), - mora_model("テ", Some("t"), "e"), - mora_model("ッ", None, "cl"), - mora_model("ト", Some("t"), "o"), + mora("クヮ", Some("kw"), "a"), + mora("ル", Some("r"), "u"), + mora("テ", Some("t"), "e"), + mora("ッ", None, "cl"), + mora("ト", Some("t"), "o"), ], 3, - Some(mora_model("、", None, "pau")), + Some(mora("、", None, "pau")), false, ), AccentPhraseModel::new( vec![ - mora_model("ア", None, "a"), - mora_model("ア", None, "a"), + mora("ア", None, "a"), + mora("ア", None, "a"), ], 1, None, false, ), AccentPhraseModel::new( - vec![mora_model("ア", None, "a")], + vec![mora("ア", None, "a")], 1, None, false,