diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1e38b1492..0496eebdb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -289,7 +289,7 @@ jobs: - name: Exampleを実行 run: | for file in ../../example/python/run{,-asyncio}.py; do - poetry run python "$file" ../../model/sample.vvm --dict-dir ../test_util/data/open_jtalk_dic_utf_8-1.11 + poetry run python "$file" ../test_util/data/model/sample.vvm --dict-dir ../test_util/data/open_jtalk_dic_utf_8-1.11 done build-and-test-java-api: strategy: diff --git a/Cargo.lock b/Cargo.lock index 158dedcdc..4015b7e36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3135,12 +3135,11 @@ name = "test_util" version = "0.0.0" dependencies = [ "anyhow", - "async_zip", "bindgen 0.69.4", "camino", "flate2", "fs-err", - "futures-lite", + "indoc", "libloading", "once_cell", "reqwest", @@ -3148,6 +3147,7 @@ dependencies = [ "serde_json", "tar", "tokio", + "zip", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index bf50cb21e..69d924a16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ heck = "0.4.1" humansize = "2.1.2" indexmap = "2.0.0" indicatif = "0.17.3" +indoc = "2.0.4" inventory = "0.3.4" itertools = "0.10.5" jlabel = "0.1.2" diff --git a/crates/test_util/Cargo.toml b/crates/test_util/Cargo.toml index 168a9ac8c..d113b57ce 100644 --- a/crates/test_util/Cargo.toml +++ b/crates/test_util/Cargo.toml @@ -3,13 +3,10 @@ name = "test_util" edition.workspace = true [dependencies] -async_zip = { workspace = true, features = ["deflate"] } -futures-lite.workspace = true libloading.workspace = true once_cell.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true -tokio = { workspace = true, features = ["fs", "io-util", "sync"] } [build-dependencies] anyhow.workspace = true @@ -18,10 +15,12 @@ bindgen.workspace = true camino.workspace = true flate2.workspace = true fs-err.workspace = true +indoc.workspace = true serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["preserve_order"] } reqwest = { workspace = true, features = ["rustls-tls"] } tar.workspace = true +zip.workspace = true [lints.rust] unsafe_code = "allow" # C APIのbindgen diff --git a/crates/test_util/build.rs b/crates/test_util/build.rs index ab4072d5b..79e3bc90e 100644 --- a/crates/test_util/build.rs +++ b/crates/test_util/build.rs @@ -1,12 +1,15 @@ use std::{ env, - path::{Path, PathBuf}, + io::{self, Cursor, Write as _}, + path::Path, }; -use anyhow::ensure; -use camino::Utf8PathBuf; +use anyhow::{anyhow, ensure}; +use camino::{Utf8Path, Utf8PathBuf}; use flate2::read::GzDecoder; +use indoc::formatdoc; use tar::Archive; +use zip::{write::FileOptions, ZipWriter}; #[path = "src/typing.rs"] mod typing; @@ -15,21 +18,78 @@ const DIC_DIR_NAME: &str = "open_jtalk_dic_utf_8-1.11"; #[tokio::main] async fn main() -> anyhow::Result<()> { - let mut dist = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); - dist.push("data"); + let out_dir = &Utf8PathBuf::from(env::var("OUT_DIR").unwrap()); + let dist = &Utf8Path::new(env!("CARGO_MANIFEST_DIR")).join("data"); let dic_dir = dist.join(DIC_DIR_NAME); if !dic_dir.try_exists()? { - download_open_jtalk_dict(&dist).await?; - ensure!(dic_dir.exists(), "`{}` does not exist", dic_dir.display()); + download_open_jtalk_dict(dist.as_ref()).await?; + ensure!(dic_dir.exists(), "`{dic_dir}` does not exist"); } - generate_example_data_json(&dist)?; + create_sample_voice_model_file(out_dir, dist)?; + + generate_example_data_json(dist.as_ref())?; println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=src/typing.rs"); - generate_c_api_rs_bindings() + generate_c_api_rs_bindings(out_dir) +} + +fn create_sample_voice_model_file(out_dir: &Utf8Path, dist: &Utf8Path) -> anyhow::Result<()> { + const SRC: &str = "../../model/sample.vvm"; + + let files = fs_err::read_dir(SRC)? + .map(|entry| { + let entry = entry?; + let md = entry.metadata()?; + ensure!(!md.is_dir(), "directory in {SRC}"); + let mtime = md.modified()?; + let name = entry + .file_name() + .into_string() + .map_err(|name| anyhow!("{name:?}"))?; + Ok((name, entry.path(), mtime)) + }) + .collect::>>()?; + + let output_dir = &dist.join("model"); + let output_file = &output_dir.join("sample.vvm"); + + let up_to_date = fs_err::metadata(output_file) + .and_then(|md| md.modified()) + .map(|t1| files.iter().all(|&(_, _, t2)| t1 >= t2)); + let up_to_date = match up_to_date { + Ok(p) => p, + Err(e) if e.kind() == io::ErrorKind::NotFound => false, + Err(e) => return Err(e.into()), + }; + + if !up_to_date { + let mut zip = ZipWriter::new(Cursor::new(vec![])); + for (name, path, _) in files { + let content = &fs_err::read(path)?; + zip.start_file(name, FileOptions::default().compression_level(Some(0)))?; + zip.write_all(content)?; + } + let zip = zip.finish()?; + fs_err::create_dir_all(output_dir)?; + fs_err::write(output_file, zip.get_ref())?; + } + + fs_err::write( + out_dir.join("sample_voice_model_file.rs"), + formatdoc! {" + pub const SAMPLE_VOICE_MODEL_FILE_PATH: &::std::primitive::str = {output_file:?}; + + const SAMPLE_VOICE_MODEL_FILE_C_PATH: &::std::ffi::CStr = c{output_file:?}; + const VV_MODELS_ROOT_DIR: &::std::primitive::str = {output_dir:?}; + ", + }, + )?; + println!("cargo:rerun-if-changed={SRC}"); + Ok(()) } /// OpenJTalkの辞書をダウンロードして展開する。 @@ -120,11 +180,10 @@ fn generate_example_data_json(dist: &Path) -> anyhow::Result<()> { Ok(()) } -fn generate_c_api_rs_bindings() -> anyhow::Result<()> { +fn generate_c_api_rs_bindings(out_dir: &Utf8Path) -> anyhow::Result<()> { static C_BINDINGS_PATH: &str = "../voicevox_core_c_api/include/voicevox_core.h"; static ADDITIONAL_C_BINDINGS_PATH: &str = "./compatible_engine.h"; - let out_dir = Utf8PathBuf::from(env::var("OUT_DIR").unwrap()); bindgen::Builder::default() .header(C_BINDINGS_PATH) .header(ADDITIONAL_C_BINDINGS_PATH) diff --git a/crates/test_util/src/lib.rs b/crates/test_util/src/lib.rs index c80f3d575..f234d7f76 100644 --- a/crates/test_util/src/lib.rs +++ b/crates/test_util/src/lib.rs @@ -1,5 +1,7 @@ mod typing; +include!(concat!(env!("OUT_DIR"), "/sample_voice_model_file.rs")); + #[allow( non_camel_case_types, non_snake_case, @@ -10,20 +12,12 @@ mod typing; )] pub mod c_api { include!(concat!(env!("OUT_DIR"), "/c_api.rs")); + + pub const SAMPLE_VOICE_MODEL_FILE_PATH: &std::ffi::CStr = super::SAMPLE_VOICE_MODEL_FILE_C_PATH; + pub const VV_MODELS_ROOT_DIR: &str = super::VV_MODELS_ROOT_DIR; } -use async_zip::{base::write::ZipFileWriter, Compression, ZipEntryBuilder}; -use futures_lite::AsyncWriteExt as _; use once_cell::sync::Lazy; -use std::{ - collections::HashMap, - path::{Path, PathBuf}, -}; -use tokio::{ - fs::{self, File}, - io::AsyncReadExt, - sync::Mutex, -}; pub use self::typing::{ DecodeExampleData, DurationExampleData, ExampleData, IntonationExampleData, @@ -42,43 +36,3 @@ const EXAMPLE_DATA_JSON: &str = include_str!(concat!( pub static EXAMPLE_DATA: Lazy = Lazy::new(|| { serde_json::from_str(EXAMPLE_DATA_JSON).expect("failed to parse example_data.json") }); - -static PATH_MUTEX: Lazy>>> = - Lazy::new(|| Mutex::new(HashMap::default())); - -pub async fn convert_zip_vvm(dir: impl AsRef) -> PathBuf { - let dir = dir.as_ref(); - let output_file_name = dir.file_name().unwrap().to_str().unwrap().to_owned() + ".vvm"; - - let out_file_path = PathBuf::from(env!("OUT_DIR")) - .join("test_data/models/") - .join(output_file_name); - let mut path_map = PATH_MUTEX.lock().await; - if !path_map.contains_key(&out_file_path) { - path_map.insert(out_file_path.clone(), Mutex::new(())); - } - let _m = path_map.get(&out_file_path).unwrap().lock().await; - - if !out_file_path.exists() { - fs::create_dir_all(out_file_path.parent().unwrap()) - .await - .unwrap(); - let mut writer = ZipFileWriter::new(vec![]); - - for entry in dir.read_dir().unwrap().flatten() { - let entry_builder = ZipEntryBuilder::new( - entry.path().file_name().unwrap().to_str().unwrap().into(), - Compression::Deflate, - ); - let mut entry_writer = writer.write_entry_stream(entry_builder).await.unwrap(); - let mut file = File::open(entry.path()).await.unwrap(); - let mut buf = Vec::with_capacity(entry.metadata().unwrap().len() as usize); - file.read_to_end(&mut buf).await.unwrap(); - entry_writer.write_all(&buf).await.unwrap(); - entry_writer.close().await.unwrap(); - } - let zip = writer.close().await.unwrap(); - fs::write(&out_file_path, zip).await.unwrap(); - } - out_file_path -} diff --git a/crates/voicevox_core/src/__internal/doctest_fixtures.rs b/crates/voicevox_core/src/__internal/doctest_fixtures.rs index 426f6cd09..f314845fe 100644 --- a/crates/voicevox_core/src/__internal/doctest_fixtures.rs +++ b/crates/voicevox_core/src/__internal/doctest_fixtures.rs @@ -1,8 +1,11 @@ +use std::path::Path; + use camino::Utf8Path; use crate::{AccelerationMode, InitializeOptions}; pub async fn synthesizer_with_sample_voice_model( + voice_model_path: impl AsRef, open_jtalk_dic_dir: impl AsRef, ) -> anyhow::Result> { let syntesizer = crate::tokio::Synthesizer::new( @@ -13,11 +16,7 @@ pub async fn synthesizer_with_sample_voice_model( }, )?; - let model = &crate::tokio::VoiceModel::from_path(concat!( - env!("CARGO_MANIFEST_DIR"), - "/../../model/sample.vvm", - )) - .await?; + let model = &crate::tokio::VoiceModel::from_path(voice_model_path).await?; syntesizer.load_voice_model(model).await?; Ok(syntesizer) diff --git a/crates/voicevox_core/src/status.rs b/crates/voicevox_core/src/status.rs index 40eef430e..a47de689b 100644 --- a/crates/voicevox_core/src/status.rs +++ b/crates/voicevox_core/src/status.rs @@ -352,7 +352,6 @@ mod tests { }, macros::tests::assert_debug_fmt_eq, synthesizer::InferenceRuntimeImpl, - test_util::open_default_vvm_file, }; use super::Status; @@ -399,7 +398,7 @@ mod tests { let status = Status::::new(InferenceDomainMap { talk: enum_map!(_ => InferenceSessionOptions::new(0, false)), }); - let model = &open_default_vvm_file().await; + let model = &crate::tokio::VoiceModel::sample().await.unwrap(); let model_contents = &model.read_inference_models().await.unwrap(); let result = status.insert_model(model.header(), model_contents); assert_debug_fmt_eq!(Ok(()), result); @@ -412,7 +411,7 @@ mod tests { let status = Status::::new(InferenceDomainMap { talk: enum_map!(_ => InferenceSessionOptions::new(0, false)), }); - let vvm = open_default_vvm_file().await; + let vvm = &crate::tokio::VoiceModel::sample().await.unwrap(); let model_header = vvm.header(); let model_contents = &vvm.read_inference_models().await.unwrap(); assert!( diff --git a/crates/voicevox_core/src/synthesizer.rs b/crates/voicevox_core/src/synthesizer.rs index d90cdce3c..5e4894415 100644 --- a/crates/voicevox_core/src/synthesizer.rs +++ b/crates/voicevox_core/src/synthesizer.rs @@ -443,6 +443,7 @@ pub(crate) mod blocking { /// # async fn main() -> anyhow::Result<()> { /// # let synthesizer = /// # voicevox_core::__internal::doctest_fixtures::synthesizer_with_sample_voice_model( + /// # test_util::SAMPLE_VOICE_MODEL_FILE_PATH, /// # test_util::OPEN_JTALK_DIC_DIR, /// # ) /// # .await?; @@ -682,6 +683,7 @@ pub(crate) mod blocking { /// # async fn main() -> anyhow::Result<()> { /// # let synthesizer = /// # voicevox_core::__internal::doctest_fixtures::synthesizer_with_sample_voice_model( + /// # test_util::SAMPLE_VOICE_MODEL_FILE_PATH, /// # test_util::OPEN_JTALK_DIC_DIR, /// # ) /// # .await?; @@ -730,6 +732,7 @@ pub(crate) mod blocking { /// # async fn main() -> anyhow::Result<()> { /// # let synthesizer = /// # voicevox_core::__internal::doctest_fixtures::synthesizer_with_sample_voice_model( + /// # test_util::SAMPLE_VOICE_MODEL_FILE_PATH, /// # test_util::OPEN_JTALK_DIC_DIR, /// # ) /// # .await?; @@ -762,6 +765,7 @@ pub(crate) mod blocking { /// # async fn main() -> anyhow::Result<()> { /// # let synthesizer = /// # voicevox_core::__internal::doctest_fixtures::synthesizer_with_sample_voice_model( + /// # test_util::SAMPLE_VOICE_MODEL_FILE_PATH, /// # test_util::OPEN_JTALK_DIC_DIR, /// # ) /// # .await?; @@ -1291,8 +1295,7 @@ mod tests { use super::{blocking::PerformInference as _, AccelerationMode, InitializeOptions}; use crate::{ - engine::MoraModel, macros::tests::assert_debug_fmt_eq, test_util::open_default_vvm_file, - AccentPhraseModel, Result, StyleId, + engine::MoraModel, macros::tests::assert_debug_fmt_eq, AccentPhraseModel, Result, StyleId, }; use ::test_util::OPEN_JTALK_DIC_DIR; use rstest::rstest; @@ -1311,7 +1314,7 @@ mod tests { .unwrap(); let result = syntesizer - .load_voice_model(&open_default_vvm_file().await) + .load_voice_model(&crate::tokio::VoiceModel::sample().await.unwrap()) .await; assert_debug_fmt_eq!( @@ -1353,7 +1356,7 @@ mod tests { "expected is_model_loaded to return false, but got true", ); syntesizer - .load_voice_model(&open_default_vvm_file().await) + .load_voice_model(&crate::tokio::VoiceModel::sample().await.unwrap()) .await .unwrap(); @@ -1378,7 +1381,7 @@ mod tests { .unwrap(); syntesizer - .load_voice_model(&open_default_vvm_file().await) + .load_voice_model(&crate::tokio::VoiceModel::sample().await.unwrap()) .await .unwrap(); @@ -1408,7 +1411,7 @@ mod tests { ) .unwrap(); syntesizer - .load_voice_model(&open_default_vvm_file().await) + .load_voice_model(&crate::tokio::VoiceModel::sample().await.unwrap()) .await .unwrap(); @@ -1447,7 +1450,7 @@ mod tests { ) .unwrap(); syntesizer - .load_voice_model(&open_default_vvm_file().await) + .load_voice_model(&crate::tokio::VoiceModel::sample().await.unwrap()) .await .unwrap(); diff --git a/crates/voicevox_core/src/test_util.rs b/crates/voicevox_core/src/test_util.rs index d60785246..5b97f21fc 100644 --- a/crates/voicevox_core/src/test_util.rs +++ b/crates/voicevox_core/src/test_util.rs @@ -1,27 +1,9 @@ -use std::path::PathBuf; +use ::test_util::SAMPLE_VOICE_MODEL_FILE_PATH; use crate::Result; -pub(crate) async fn open_default_vvm_file() -> crate::tokio::VoiceModel { - crate::tokio::VoiceModel::from_path( - ::test_util::convert_zip_vvm( - PathBuf::from(env!("CARGO_WORKSPACE_DIR")) - .join(file!()) - .parent() - .unwrap() - .join("test_data/model_sources") - .join("load_model_works1"), - ) - .await, - ) - .await - .unwrap() -} - impl crate::tokio::VoiceModel { pub(crate) async fn sample() -> Result { - return Self::from_path(PATH).await; - - static PATH: &str = concat!(env!("CARGO_WORKSPACE_DIR"), "/model/sample.vvm"); + Self::from_path(SAMPLE_VOICE_MODEL_FILE_PATH).await } } diff --git a/crates/voicevox_core_c_api/tests/e2e/main.rs b/crates/voicevox_core_c_api/tests/e2e/main.rs index 5e8e19a9c..91f5e06e9 100644 --- a/crates/voicevox_core_c_api/tests/e2e/main.rs +++ b/crates/voicevox_core_c_api/tests/e2e/main.rs @@ -1,3 +1,5 @@ +use test_util::c_api::VV_MODELS_ROOT_DIR; + mod assert_cdylib; mod float_assert; mod log_mask; @@ -33,6 +35,6 @@ fn main() -> anyhow::Result<()> { ("ORT_USE_CUDA", "0"), ]; const RUNTIME_ENVS: &'static [(&'static str, &'static str)] = - &[("VV_MODELS_ROOT_DIR", "../../model")]; + &[("VV_MODELS_ROOT_DIR", VV_MODELS_ROOT_DIR)]; } } diff --git a/crates/voicevox_core_c_api/tests/e2e/testcases/simple_tts.rs b/crates/voicevox_core_c_api/tests/e2e/testcases/simple_tts.rs index 85709d2bf..4ac4030e1 100644 --- a/crates/voicevox_core_c_api/tests/e2e/testcases/simple_tts.rs +++ b/crates/voicevox_core_c_api/tests/e2e/testcases/simple_tts.rs @@ -1,7 +1,6 @@ use std::{collections::HashMap, ffi::CString, mem::MaybeUninit}; use assert_cmd::assert::AssertResult; -use cstr::cstr; use libloading::Library; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; @@ -32,7 +31,7 @@ impl assert_cdylib::TestCase for TestCase { let model = { let mut model = MaybeUninit::uninit(); assert_ok(lib.voicevox_voice_model_new_from_path( - cstr!("../../model/sample.vvm").as_ptr(), + c_api::SAMPLE_VOICE_MODEL_FILE_PATH.as_ptr(), model.as_mut_ptr(), )); model.assume_init() diff --git a/crates/voicevox_core_c_api/tests/e2e/testcases/synthesizer_new_output_json.rs b/crates/voicevox_core_c_api/tests/e2e/testcases/synthesizer_new_output_json.rs index 4727a3c06..c27bd4703 100644 --- a/crates/voicevox_core_c_api/tests/e2e/testcases/synthesizer_new_output_json.rs +++ b/crates/voicevox_core_c_api/tests/e2e/testcases/synthesizer_new_output_json.rs @@ -4,7 +4,6 @@ use std::{ }; use assert_cmd::assert::AssertResult; -use cstr::cstr; use libloading::Library; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; @@ -55,7 +54,7 @@ impl assert_cdylib::TestCase for TestCase { let model = { let mut model = MaybeUninit::uninit(); assert_ok(lib.voicevox_voice_model_new_from_path( - cstr!("../../model/sample.vvm").as_ptr(), + c_api::SAMPLE_VOICE_MODEL_FILE_PATH.as_ptr(), model.as_mut_ptr(), )); model.assume_init() diff --git a/crates/voicevox_core_c_api/tests/e2e/testcases/tts_via_audio_query.rs b/crates/voicevox_core_c_api/tests/e2e/testcases/tts_via_audio_query.rs index 606e82aeb..d380b71b2 100644 --- a/crates/voicevox_core_c_api/tests/e2e/testcases/tts_via_audio_query.rs +++ b/crates/voicevox_core_c_api/tests/e2e/testcases/tts_via_audio_query.rs @@ -1,7 +1,6 @@ use std::{collections::HashMap, ffi::CString, mem::MaybeUninit}; use assert_cmd::assert::AssertResult; -use cstr::cstr; use libloading::Library; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; @@ -32,7 +31,7 @@ impl assert_cdylib::TestCase for TestCase { let model = { let mut model = MaybeUninit::uninit(); assert_ok(lib.voicevox_voice_model_new_from_path( - cstr!("../../model/sample.vvm").as_ptr(), + c_api::SAMPLE_VOICE_MODEL_FILE_PATH.as_ptr(), model.as_mut_ptr(), )); model.assume_init() diff --git a/crates/voicevox_core_c_api/tests/e2e/testcases/user_dict_load.rs b/crates/voicevox_core_c_api/tests/e2e/testcases/user_dict_load.rs index dfbb5ca3c..2e6875e97 100644 --- a/crates/voicevox_core_c_api/tests/e2e/testcases/user_dict_load.rs +++ b/crates/voicevox_core_c_api/tests/e2e/testcases/user_dict_load.rs @@ -48,7 +48,7 @@ impl assert_cdylib::TestCase for TestCase { let model = { let mut model = MaybeUninit::uninit(); assert_ok(lib.voicevox_voice_model_new_from_path( - cstr!("../../model/sample.vvm").as_ptr(), + c_api::SAMPLE_VOICE_MODEL_FILE_PATH.as_ptr(), model.as_mut_ptr(), )); model.assume_init() diff --git a/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/MetaTest.java b/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/MetaTest.java index 741f84e79..60df7359f 100644 --- a/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/MetaTest.java +++ b/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/MetaTest.java @@ -13,7 +13,7 @@ class MetaTest { void checkLoad() { // cwdはvoicevox_core/crates/voicevox_core_java_api/lib String cwd = System.getProperty("user.dir"); - File path = new File(cwd + "/../../../model/sample.vvm"); + File path = new File(cwd + "/../../test_util/data/model/sample.vvm"); VoiceModel model = new VoiceModel(path.getAbsolutePath()); assertNotNull(model.metas); } diff --git a/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/TestUtils.java b/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/TestUtils.java index 670eddbdb..032c38a3d 100644 --- a/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/TestUtils.java +++ b/crates/voicevox_core_java_api/lib/src/test/java/jp/hiroshiba/voicevoxcore/TestUtils.java @@ -6,7 +6,7 @@ class TestUtils { VoiceModel loadModel() { // cwdはvoicevox_core/crates/voicevox_core_java_api/lib String cwd = System.getProperty("user.dir"); - File path = new File(cwd + "/../../../model/sample.vvm"); + File path = new File(cwd + "/../../test_util/data/model/sample.vvm"); try { return new VoiceModel(path.getCanonicalPath()); diff --git a/crates/voicevox_core_python_api/python/test/conftest.py b/crates/voicevox_core_python_api/python/test/conftest.py index 628f4dc56..eec642cb9 100644 --- a/crates/voicevox_core_python_api/python/test/conftest.py +++ b/crates/voicevox_core_python_api/python/test/conftest.py @@ -10,7 +10,9 @@ open_jtalk_dic_dir = ( root_dir.parent.parent.parent / "test_util" / "data" / "open_jtalk_dic_utf_8-1.11" ) -model_dir = root_dir.parent.parent.parent.parent / "model" / "sample.vvm" +model_dir = ( + root_dir.parent.parent.parent / "test_util" / "data" / "model" / "sample.vvm" +) class DurationExampleData(TypedDict): diff --git a/docs/vvm.md b/docs/vvm.md index c2de7fb41..cc7b9232e 100644 --- a/docs/vvm.md +++ b/docs/vvm.md @@ -14,7 +14,7 @@ model は `.onnx` や `.bin` など様々ある。例えば `sample.vvm` は `predict_duration.onnx` / `predict_intonation.onnx` / `decode.onnx` を含む。 -VOICEVOX OSS が提供する VVM には [`sample.vvm`](https://github.com/VOICEVOX/voicevox_core/tree/main/model) がある。 +VOICEVOX OSS が提供する VVM には `sample.vvm` がある(ビルドを行うと `crates/test_util/data/model/sample.vvm` が生成される)。 製品版 VOICEVOX で利用される VVM は [こちらのレポジトリ](https://github.com/VOICEVOX/voicevox_fat_resource/tree/main/core/model) で確認できる。 ## マニフェストファイル diff --git a/example/kotlin/README.md b/example/kotlin/README.md index 908bdd51f..3bcdafc94 100644 --- a/example/kotlin/README.md +++ b/example/kotlin/README.md @@ -57,9 +57,9 @@ Options: ## 実行例 ```console -❯ ./gradlew run --args="--vvm ../../model/sample.vvm" +❯ ./gradlew run --args="--vvm ../../crates/test_util/data/model/sample.vvm" Inititalizing: AUTO, ./open_jtalk_dic_utf_8-1.11 -Loading: ../../model/sample.vvm +Loading: ../../crates/test_util/data/model/sample.vvm Creating an AudioQuery from the text: この音声は、ボイスボックスを使用して、出力されています。 Synthesizing... Saving the audio to ./output.wav diff --git a/example/python/README.md b/example/python/README.md index 392896030..97303eb81 100644 --- a/example/python/README.md +++ b/example/python/README.md @@ -69,12 +69,12 @@ optional arguments: ## 実行例 ```console -❯ python ./run.py ../../model/sample.vvm +❯ python ./run.py ../../crates/test_util/data/model/sample.vvm [DEBUG] __main__: voicevox_core.supported_devices()=SupportedDevices(cpu=True, cuda=False, dml=False) [INFO] __main__: Initializing (acceleration_mode=, open_jtalk_dict_dir=PosixPath('open_jtalk_dic_utf_8-1.11')) [DEBUG] __main__: synthesizer.metas=[] [DEBUG] __main__: synthesizer.is_gpu_mode=False -[INFO] __main__: Loading `../../model/sample.vvm` +[INFO] __main__: Loading `../../crates/test_util/data/model/sample.vvm` [INFO] __main__: Creating an AudioQuery from 'この音声は、ボイスボックスを使用して、出力されています。' [INFO] __main__: Synthesizing with {"accent_phrases": [{"moras": [{"text": "コ", "consonant": "k", "consonant_length": 0.0556899, "vowel": "o", "vowel_length": 0.075180575, "pitch": 5.542309}, {"text": "ノ", "consonant": "n", "consonant_length": 0.06551014, "vowel": "o", "vowel_length": 0.09984577, "pitch": 5.6173983}], "accent": 2, "pause_mora": null, "is_interrogative": false}, {"moras": [{"text": "オ", "consonant": null, "consonant_length": null, "vowel": "o", "vowel_length": 0.116150305, "pitch": 5.7063766}, {"text": "ン", "consonant": null, "consonant_length": null, "vowel": "N", "vowel_length": 0.044380233, "pitch": 5.785717}, {"text": "セ", "consonant": "s", "consonant_length": 0.07719758, "vowel": "e", "vowel_length": 0.08653869, "pitch": 5.662092}, {"text": "エ", "consonant": null, "consonant_length": null, "vowel": "e", "vowel_length": 0.08311573, "pitch": 5.532917}, {"text": "ワ", "consonant": "w", "consonant_length": 0.06373148, "vowel": "a", "vowel_length": 0.16219379, "pitch": 5.293258}], "accent": 1, "pause_mora": {"text": "、", "consonant": null, "consonant_length": null, "vowel": "pau", "vowel_length": 0.35826492, "pitch": 0.0}, "is_interrogative": false}, {"moras": [{"text": "ボ", "consonant": "b", "consonant_length": 0.047082342, "vowel": "o", "vowel_length": 0.12611786, "pitch": 5.583892}, {"text": "イ", "consonant": null, "consonant_length": null, "vowel": "i", "vowel_length": 0.059451744, "pitch": 5.7947493}, {"text": "ス", "consonant": "s", "consonant_length": 0.089278996, "vowel": "u", "vowel_length": 0.11847979, "pitch": 5.818695}, {"text": "ボ", "consonant": "b", "consonant_length": 0.06535433, "vowel": "o", "vowel_length": 0.120458946, "pitch": 5.7965107}, {"text": "ッ", "consonant": null, "consonant_length": null, "vowel": "cl", "vowel_length": 0.06940381, "pitch": 0.0}, {"text": "ク", "consonant": "k", "consonant_length": 0.053739145, "vowel": "U", "vowel_length": 0.05395376, "pitch": 0.0}, {"text": "ス", "consonant": "s", "consonant_length": 0.10222931, "vowel": "u", "vowel_length": 0.071811065, "pitch": 5.8024883}, {"text": "オ", "consonant": null, "consonant_length": null, "vowel": "o", "vowel_length": 0.11092262, "pitch": 5.5036163}], "accent": 4, "pause_mora": null, "is_interrogative": false}, {"moras": [{"text": "シ", "consonant": "sh", "consonant_length": 0.09327768, "vowel": "i", "vowel_length": 0.09126951, "pitch": 5.369444}, {"text": "ヨ", "consonant": "y", "consonant_length": 0.06251812, "vowel": "o", "vowel_length": 0.07805054, "pitch": 5.5021667}, {"text": "オ", "consonant": null, "consonant_length": null, "vowel": "o", "vowel_length": 0.09904325, "pitch": 5.5219536}], "accent": 3, "pause_mora": null, "is_interrogative": false}, {"moras": [{"text": "シ", "consonant": "sh", "consonant_length": 0.04879771, "vowel": "I", "vowel_length": 0.06514315, "pitch": 0.0}, {"text": "テ", "consonant": "t", "consonant_length": 0.0840496, "vowel": "e", "vowel_length": 0.19438823, "pitch": 5.4875555}], "accent": 2, "pause_mora": {"text": "、", "consonant": null, "consonant_length": null, "vowel": "pau", "vowel_length": 0.35208154, "pitch": 0.0}, "is_interrogative": false}, {"moras": [{"text": "シュ", "consonant": "sh", "consonant_length": 0.05436731, "vowel": "U", "vowel_length": 0.06044446, "pitch": 0.0}, {"text": "ツ", "consonant": "ts", "consonant_length": 0.102865085, "vowel": "u", "vowel_length": 0.057028636, "pitch": 5.6402535}, {"text": "リョ", "consonant": "ry", "consonant_length": 0.058293864, "vowel": "o", "vowel_length": 0.080050275, "pitch": 5.6997967}, {"text": "ク", "consonant": "k", "consonant_length": 0.054767884, "vowel": "U", "vowel_length": 0.042932786, "pitch": 0.0}], "accent": 2, "pause_mora": null, "is_interrogative": false}, {"moras": [{"text": "サ", "consonant": "s", "consonant_length": 0.08067487, "vowel": "a", "vowel_length": 0.07377973, "pitch": 5.652378}, {"text": "レ", "consonant": "r", "consonant_length": 0.040600352, "vowel": "e", "vowel_length": 0.079322875, "pitch": 5.6290326}, {"text": "テ", "consonant": "t", "consonant_length": 0.06773268, "vowel": "e", "vowel_length": 0.08347456, "pitch": 5.6427326}], "accent": 3, "pause_mora": null, "is_interrogative": false}, {"moras": [{"text": "イ", "consonant": null, "consonant_length": null, "vowel": "i", "vowel_length": 0.07542324, "pitch": 5.641289}, {"text": "マ", "consonant": "m", "consonant_length": 0.066299975, "vowel": "a", "vowel_length": 0.107257664, "pitch": 5.6201453}, {"text": "ス", "consonant": "s", "consonant_length": 0.07186453, "vowel": "U", "vowel_length": 0.1163103, "pitch": 0.0}], "accent": 2, "pause_mora": null, "is_interrogative": false}], "speed_scale": 1.0, "pitch_scale": 0.0, "intonation_scale": 1.0, "volume_scale": 1.0, "pre_phoneme_length": 0.1, "post_phoneme_length": 0.1, "output_sampling_rate": 24000, "output_stereo": false, "kana": "コノ'/オ'ンセエワ、ボイスボ'ッ_クスオ/シヨオ'/_シテ'、_シュツ' リョ_ク/サレテ'/イマ'_ス"} [INFO] __main__: Wrote `output.wav` diff --git a/model/sample.vvm b/model/sample.vvm deleted file mode 100644 index f541ae082..000000000 Binary files a/model/sample.vvm and /dev/null differ diff --git a/crates/voicevox_core/src/test_data/model_sources/load_model_works1/decode.onnx b/model/sample.vvm/decode.onnx similarity index 100% rename from crates/voicevox_core/src/test_data/model_sources/load_model_works1/decode.onnx rename to model/sample.vvm/decode.onnx diff --git a/crates/voicevox_core/src/test_data/model_sources/load_model_works1/manifest.json b/model/sample.vvm/manifest.json similarity index 100% rename from crates/voicevox_core/src/test_data/model_sources/load_model_works1/manifest.json rename to model/sample.vvm/manifest.json diff --git a/crates/voicevox_core/src/test_data/model_sources/load_model_works1/metas.json b/model/sample.vvm/metas.json similarity index 100% rename from crates/voicevox_core/src/test_data/model_sources/load_model_works1/metas.json rename to model/sample.vvm/metas.json diff --git a/crates/voicevox_core/src/test_data/model_sources/load_model_works1/predict_duration.onnx b/model/sample.vvm/predict_duration.onnx similarity index 100% rename from crates/voicevox_core/src/test_data/model_sources/load_model_works1/predict_duration.onnx rename to model/sample.vvm/predict_duration.onnx diff --git a/crates/voicevox_core/src/test_data/model_sources/load_model_works1/predict_intonation.onnx b/model/sample.vvm/predict_intonation.onnx similarity index 100% rename from crates/voicevox_core/src/test_data/model_sources/load_model_works1/predict_intonation.onnx rename to model/sample.vvm/predict_intonation.onnx