diff --git a/crates/voicevox_core/src/__internal/doctest_fixtures.rs b/crates/voicevox_core/src/__internal/doctest_fixtures.rs index dd088b218..c9029079c 100644 --- a/crates/voicevox_core/src/__internal/doctest_fixtures.rs +++ b/crates/voicevox_core/src/__internal/doctest_fixtures.rs @@ -1,12 +1,12 @@ -use std::{path::Path, sync::Arc}; +use std::path::Path; use crate::{AccelerationMode, InitializeOptions, OpenJtalk, Synthesizer, VoiceModel}; pub async fn synthesizer_with_sample_voice_model( open_jtalk_dic_dir: impl AsRef, -) -> anyhow::Result { +) -> anyhow::Result> { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new(open_jtalk_dic_dir).await.unwrap()), + OpenJtalk::new(open_jtalk_dic_dir).await?, &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() diff --git a/crates/voicevox_core/src/engine/open_jtalk.rs b/crates/voicevox_core/src/engine/open_jtalk.rs index e45f9a5fa..1cffe6757 100644 --- a/crates/voicevox_core/src/engine/open_jtalk.rs +++ b/crates/voicevox_core/src/engine/open_jtalk.rs @@ -1,9 +1,6 @@ use std::io::Write; use std::sync::Arc; -use std::{ - path::{Path, PathBuf}, - sync::Mutex, -}; +use std::{path::Path, sync::Mutex}; use anyhow::anyhow; use tempfile::NamedTempFile; @@ -21,9 +18,10 @@ pub(crate) struct OpenjtalkFunctionError { } /// テキスト解析器としてのOpen JTalk。 +#[derive(Clone)] pub struct OpenJtalk { resources: Arc>, - dict_dir: Option, + dict_dir: Arc, // FIXME: `camino::Utf8PathBuf`にする } struct Resources { @@ -36,46 +34,41 @@ struct Resources { unsafe impl Send for Resources {} impl OpenJtalk { - // FIXME: この関数は廃止し、`Synthesizer`は`Option`という形でこの構造体を持つ - pub fn new_without_dic() -> Self { - Self { - resources: Mutex::new(Resources { + pub async fn new(open_jtalk_dict_dir: impl AsRef) -> crate::result::Result { + let dict_dir = open_jtalk_dict_dir + .as_ref() + .to_str() + .unwrap_or_else(|| todo!()) // FIXME: `camino::Utf8Path`を要求するようにする + .to_owned(); + let dict_dir = Arc::new(dict_dir); + + crate::task::asyncify(move || { + let mut resources = Resources { mecab: ManagedResource::initialize(), njd: ManagedResource::initialize(), jpcommon: ManagedResource::initialize(), - }) - .into(), - dict_dir: None, - } - } + }; - pub async fn new(open_jtalk_dict_dir: impl AsRef) -> crate::result::Result { - let open_jtalk_dict_dir = open_jtalk_dict_dir.as_ref().to_owned(); - - crate::task::asyncify(move || { - let mut s = Self::new_without_dic(); - s.load(open_jtalk_dict_dir).map_err(|()| { + let result = resources.mecab.load(&*dict_dir); + if !result { // FIXME: 「システム辞書を読もうとしたけど読めなかった」というエラーをちゃんと用意する - ErrorRepr::NotLoadedOpenjtalkDict - })?; - Ok(s) + return Err(ErrorRepr::NotLoadedOpenjtalkDict.into()); + } + + Ok(Self { + resources: Mutex::new(resources).into(), + dict_dir, + }) }) .await } - // 先に`load`を呼ぶ必要がある。 /// ユーザー辞書を設定する。 /// /// この関数を呼び出した後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。 pub async fn use_user_dict(&self, user_dict: &UserDict) -> crate::result::Result<()> { - let dict_dir = self - .dict_dir - .as_ref() - .and_then(|dict_dir| dict_dir.to_str()) - .ok_or(ErrorRepr::NotLoadedOpenjtalkDict)? - .to_owned(); - let resources = self.resources.clone(); + let dict_dir = self.dict_dir.clone(); let words = user_dict.to_mecab_format(); @@ -108,7 +101,7 @@ impl OpenJtalk { let Resources { mecab, .. } = &mut *resources.lock().unwrap(); - Ok(mecab.load_with_userdic(dict_dir.as_ref(), Some(Path::new(&temp_dict_path)))) + Ok(mecab.load_with_userdic((*dict_dir).as_ref(), Some(Path::new(&temp_dict_path)))) }) .await?; @@ -167,26 +160,6 @@ impl OpenJtalk { }) } } - - fn load(&mut self, open_jtalk_dict_dir: impl AsRef) -> std::result::Result<(), ()> { - let result = self - .resources - .lock() - .unwrap() - .mecab - .load(open_jtalk_dict_dir.as_ref()); - if result { - self.dict_dir = Some(open_jtalk_dict_dir.as_ref().into()); - Ok(()) - } else { - self.dict_dir = None; - Err(()) - } - } - - pub fn dict_loaded(&self) -> bool { - self.dict_dir.is_some() - } } #[cfg(test)] diff --git a/crates/voicevox_core/src/synthesizer.rs b/crates/voicevox_core/src/synthesizer.rs index 383e8f6c0..556877e08 100644 --- a/crates/voicevox_core/src/synthesizer.rs +++ b/crates/voicevox_core/src/synthesizer.rs @@ -3,7 +3,6 @@ use std::{ sync::Arc, }; -use easy_ext::ext; use enum_map::enum_map; use crate::{ @@ -95,11 +94,11 @@ pub(crate) type InferenceRuntimeImpl = Onnxruntime; /// 音声シンセサイザ。 #[derive(Clone)] -pub struct Synthesizer(Arc); +pub struct Synthesizer(Arc>); // FIXME: docを書く -impl Synthesizer { - pub fn new(open_jtalk: Arc, options: &InitializeOptions) -> Result { +impl Synthesizer { + pub fn new(open_jtalk: O, options: &InitializeOptions) -> Result { blocking::Synthesizer::new(open_jtalk, options) .map(Into::into) .map(Self) @@ -155,17 +154,6 @@ impl Synthesizer { .await } - pub async fn create_accent_phrases( - &self, - text: &str, - style_id: StyleId, - ) -> Result> { - let blocking = self.0.clone(); - let text = text.to_owned(); - - crate::task::asyncify(move || blocking.create_accent_phrases(&text, style_id)).await - } - pub async fn replace_mora_data( &self, accent_phrases: &[AccentPhraseModel], @@ -211,13 +199,6 @@ impl Synthesizer { crate::task::asyncify(move || blocking.audio_query_from_kana(&kana, style_id)).await } - pub async fn audio_query(&self, text: &str, style_id: StyleId) -> Result { - let blocking = self.0.clone(); - let text = text.to_owned(); - - crate::task::asyncify(move || blocking.audio_query(&text, style_id)).await - } - pub async fn tts_from_kana( &self, kana: &str, @@ -230,6 +211,26 @@ impl Synthesizer { crate::task::asyncify(move || blocking.tts_from_kana(&kana, style_id, &options)).await } +} + +impl Synthesizer { + pub async fn create_accent_phrases( + &self, + text: &str, + style_id: StyleId, + ) -> Result> { + let blocking = self.0.clone(); + let text = text.to_owned(); + + crate::task::asyncify(move || blocking.create_accent_phrases(&text, style_id)).await + } + + pub async fn audio_query(&self, text: &str, style_id: StyleId) -> Result { + let blocking = self.0.clone(); + let text = text.to_owned(); + + crate::task::asyncify(move || blocking.audio_query(&text, style_id)).await + } pub async fn tts( &self, @@ -245,9 +246,12 @@ impl Synthesizer { } } +// FIXME: コードのdiffを抑えるため`impl blocking::Synthesizer`と +// `impl blocking::Synthesizer`がそれぞれ3つ誕生しているので、一つずつにまとめる + // FIXME: ここのdocのコードブロックはasync版のものなので、↑の方に移した上で、(ブロッキング版を // public APIにするならの話ではあるが)ブロッキング版はブロッキング版でコード例を用意する -impl blocking::Synthesizer { +impl blocking::Synthesizer { /// `Synthesizer`をコンストラクトする。 /// /// # Example @@ -275,7 +279,7 @@ impl blocking::Synthesizer { /// # Ok(()) /// # } /// ``` - fn new(open_jtalk: Arc, options: &InitializeOptions) -> Result { + fn new(open_jtalk: O, options: &InitializeOptions) -> Result { #[cfg(windows)] list_windows_video_cards(); @@ -599,7 +603,9 @@ impl blocking::Synthesizer { ) -> Result> { self.replace_mora_data(&parse_kana(kana)?, style_id) } +} +impl blocking::Synthesizer { /// 日本語のテキストからAccentPhrase (アクセント句)の配列を生成する。 /// /// # Example @@ -628,10 +634,6 @@ impl blocking::Synthesizer { text: &str, style_id: StyleId, ) -> Result> { - if !self.open_jtalk.dict_loaded() { - return Err(ErrorRepr::NotLoadedOpenjtalkDict.into()); - } - if text.is_empty() { return Ok(Vec::new()); } @@ -703,7 +705,9 @@ impl blocking::Synthesizer { self.replace_mora_data(&accent_phrases, style_id) } +} +impl blocking::Synthesizer { /// AccentPhraseの配列の音高・音素長を、特定の声で生成しなおす。 fn replace_mora_data( &self, @@ -939,7 +943,9 @@ impl blocking::Synthesizer { let accent_phrases = self.create_accent_phrases_from_kana(kana, style_id)?; Ok(AudioQueryModel::from_accent_phrases(accent_phrases).with_kana(Some(kana.to_owned()))) } +} +impl blocking::Synthesizer { /// 日本語のテキストから[AudioQuery]を生成する。 /// /// # Examples @@ -969,7 +975,9 @@ impl blocking::Synthesizer { let accent_phrases = self.create_accent_phrases(text, style_id)?; Ok(AudioQueryModel::from_accent_phrases(accent_phrases)) } +} +impl blocking::Synthesizer { /// AquesTalk風記法から音声合成を行う。 fn tts_from_kana( &self, @@ -980,7 +988,9 @@ impl blocking::Synthesizer { let audio_query = &self.audio_query_from_kana(kana, style_id)?; self.synthesis(audio_query, style_id, &SynthesisOptions::from(options)) } +} +impl blocking::Synthesizer { /// 日本語のテキストから音声合成を行う。 fn tts(&self, text: &str, style_id: StyleId, options: &TtsOptions) -> Result> { let audio_query = &self.audio_query(text, style_id)?; @@ -988,7 +998,48 @@ impl blocking::Synthesizer { } } -impl PerformInference for Synthesizer { +pub trait PerformInference { + /// `predict_duration`を実行する。 + /// + /// # Performance + /// + /// CPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 + fn predict_duration(&self, phoneme_vector: &[i64], style_id: StyleId) -> Result>; + + /// `predict_intonation`を実行する。 + /// + /// # Performance + /// + /// CPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 + #[allow(clippy::too_many_arguments)] + fn predict_intonation( + &self, + length: usize, + vowel_phoneme_vector: &[i64], + consonant_phoneme_vector: &[i64], + start_accent_vector: &[i64], + end_accent_vector: &[i64], + start_accent_phrase_vector: &[i64], + end_accent_phrase_vector: &[i64], + style_id: StyleId, + ) -> Result>; + + /// `decode`を実行する。 + /// + /// # Performance + /// + /// CPU/GPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 + fn decode( + &self, + length: usize, + phoneme_size: usize, + f0: &[f32], + phoneme_vector: &[f32], + style_id: StyleId, + ) -> Result>; +} + +impl PerformInference for Synthesizer { fn predict_duration(&self, phoneme_vector: &[i64], style_id: StyleId) -> Result> { self.0.predict_duration(phoneme_vector, style_id) } @@ -1029,14 +1080,8 @@ impl PerformInference for Synthesizer { } } -#[ext(PerformInference)] -impl blocking::Synthesizer { - /// `predict_duration`を実行する。 - /// - /// # Performance - /// - /// CPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 - pub fn predict_duration(&self, phoneme_vector: &[i64], style_id: StyleId) -> Result> { +impl PerformInference for blocking::Synthesizer { + fn predict_duration(&self, phoneme_vector: &[i64], style_id: StyleId) -> Result> { // FIXME: `Status::ids_for`があるため、ここは不要なはず if !self.status.validate_speaker_id(style_id) { return Err(ErrorRepr::StyleNotFound { style_id }.into()); @@ -1066,13 +1111,7 @@ impl blocking::Synthesizer { const PHONEME_LENGTH_MINIMAL: f32 = 0.01; } - /// `predict_intonation`を実行する。 - /// - /// # Performance - /// - /// CPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 - #[allow(clippy::too_many_arguments)] - pub fn predict_intonation( + fn predict_intonation( &self, length: usize, vowel_phoneme_vector: &[i64], @@ -1107,12 +1146,7 @@ impl blocking::Synthesizer { Ok(output.into_raw_vec()) } - /// `decode`を実行する。 - /// - /// # Performance - /// - /// CPU/GPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 - pub fn decode( + fn decode( &self, length: usize, phoneme_size: usize, @@ -1360,18 +1394,13 @@ impl AudioQueryModel { } mod blocking { - use std::sync::Arc; - - use crate::{ - engine::OpenJtalk, - infer::{domain::InferenceDomainImpl, status::Status}, - }; + use crate::infer::{domain::InferenceDomainImpl, status::Status}; use super::InferenceRuntimeImpl; - pub(super) struct Synthesizer { + pub(super) struct Synthesizer { pub(super) status: Status, - pub(super) open_jtalk: Arc, + pub(super) open_jtalk: O, pub(super) use_gpu: bool, } } @@ -1388,7 +1417,7 @@ mod tests { #[tokio::test] async fn load_model_works(#[case] expected_result_at_initialized: Result<()>) { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new_without_dic()), + (), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1411,7 +1440,7 @@ mod tests { #[tokio::test] async fn is_use_gpu_works() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new_without_dic()), + (), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1427,7 +1456,7 @@ mod tests { async fn is_loaded_model_by_style_id_works(#[case] style_id: u32, #[case] expected: bool) { let style_id = StyleId::new(style_id); let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new_without_dic()), + (), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1455,7 +1484,7 @@ mod tests { #[tokio::test] async fn predict_duration_works() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new_without_dic()), + (), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1484,7 +1513,7 @@ mod tests { #[tokio::test] async fn predict_intonation_works() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new_without_dic()), + (), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1523,7 +1552,7 @@ mod tests { #[tokio::test] async fn decode_works() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new_without_dic()), + (), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1613,7 +1642,7 @@ mod tests { #[case] expected_kana_text: &str, ) { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap()), + OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap(), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1681,7 +1710,7 @@ mod tests { #[case] expected_text_consonant_vowel_data: &TextConsonantVowelData, ) { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap()), + OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap(), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1746,7 +1775,7 @@ mod tests { #[tokio::test] async fn create_accent_phrases_works_for_japanese_commas_and_periods() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap()), + OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap(), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1805,7 +1834,7 @@ mod tests { #[tokio::test] async fn mora_length_works() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap()), + OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap(), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1841,7 +1870,7 @@ mod tests { #[tokio::test] async fn mora_pitch_works() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap()), + OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap(), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() @@ -1873,7 +1902,7 @@ mod tests { #[tokio::test] async fn mora_data_works() { let syntesizer = Synthesizer::new( - Arc::new(OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap()), + OpenJtalk::new(OPEN_JTALK_DIC_DIR).await.unwrap(), &InitializeOptions { acceleration_mode: AccelerationMode::Cpu, ..Default::default() diff --git a/crates/voicevox_core_c_api/src/c_impls.rs b/crates/voicevox_core_c_api/src/c_impls.rs index 74e783fdc..aa1421049 100644 --- a/crates/voicevox_core_c_api/src/c_impls.rs +++ b/crates/voicevox_core_c_api/src/c_impls.rs @@ -1,4 +1,4 @@ -use std::{ffi::CString, path::Path, sync::Arc}; +use std::{ffi::CString, path::Path}; use voicevox_core::{InitializeOptions, OpenJtalk, Result, Synthesizer, VoiceModel, VoiceModelId}; @@ -7,7 +7,7 @@ use crate::{CApiResult, OpenJtalkRc, VoicevoxSynthesizer, VoicevoxVoiceModel}; impl OpenJtalkRc { pub(crate) async fn new(open_jtalk_dic_dir: impl AsRef) -> Result { Ok(Self { - open_jtalk: Arc::new(OpenJtalk::new(open_jtalk_dic_dir).await?), + open_jtalk: OpenJtalk::new(open_jtalk_dic_dir).await?, }) } } diff --git a/crates/voicevox_core_c_api/src/compatible_engine.rs b/crates/voicevox_core_c_api/src/compatible_engine.rs index 8f2d7c5cc..cf19d9d3b 100644 --- a/crates/voicevox_core_c_api/src/compatible_engine.rs +++ b/crates/voicevox_core_c_api/src/compatible_engine.rs @@ -1,9 +1,9 @@ -use std::{collections::BTreeMap, sync::Arc}; +use std::collections::BTreeMap; use super::*; use libc::c_int; -use voicevox_core::{OpenJtalk, StyleId, VoiceModel, __internal::interop::PerformInference as _}; +use voicevox_core::{StyleId, VoiceModel, __internal::interop::PerformInference as _}; macro_rules! ensure_initialized { ($synthesizer:expr $(,)?) => { @@ -88,10 +88,10 @@ fn voice_model_set() -> &'static VoiceModelSet { &VOICE_MODEL_SET } -static SYNTHESIZER: Lazy>> = +static SYNTHESIZER: Lazy>>> = Lazy::new(|| Mutex::new(None)); -fn lock_synthesizer() -> MutexGuard<'static, Option> { +fn lock_synthesizer() -> MutexGuard<'static, Option>> { SYNTHESIZER.lock().unwrap() } @@ -108,7 +108,7 @@ pub extern "C" fn initialize(use_gpu: bool, cpu_num_threads: c_int, load_all_mod // で行っているという構造になってしまっているので、外すとロガーの初期化が遅れてしまでう let result = RUNTIME.block_on(async { let synthesizer = voicevox_core::Synthesizer::new( - Arc::new(OpenJtalk::new_without_dic()), + (), &voicevox_core::InitializeOptions { acceleration_mode: if use_gpu { voicevox_core::AccelerationMode::Gpu diff --git a/crates/voicevox_core_c_api/src/lib.rs b/crates/voicevox_core_c_api/src/lib.rs index ac72b6359..b9e50ba5d 100644 --- a/crates/voicevox_core_c_api/src/lib.rs +++ b/crates/voicevox_core_c_api/src/lib.rs @@ -104,7 +104,7 @@ static RUNTIME: Lazy = Lazy::new(|| { /// ``` /// } pub struct OpenJtalkRc { - open_jtalk: Arc, + open_jtalk: OpenJtalk, } /// ::OpenJtalkRc を構築(_construct_)する。 @@ -317,7 +317,7 @@ pub extern "C" fn voicevox_voice_model_delete(model: Box) { /// 構築(_construction_)は ::voicevox_synthesizer_new で行い、破棄(_destruction_)は ::voicevox_synthesizer_delete で行う。 #[derive(Getters)] pub struct VoicevoxSynthesizer { - synthesizer: Synthesizer, + synthesizer: Synthesizer, } /// ::VoicevoxSynthesizer を構築(_construct_)する。 diff --git a/crates/voicevox_core_java_api/src/open_jtalk.rs b/crates/voicevox_core_java_api/src/open_jtalk.rs index bbb03608c..422dd0fa8 100644 --- a/crates/voicevox_core_java_api/src/open_jtalk.rs +++ b/crates/voicevox_core_java_api/src/open_jtalk.rs @@ -17,7 +17,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_OpenJtalk_rsNew<'local> let open_jtalk_dict_dir = &*Cow::from(&open_jtalk_dict_dir); let internal = RUNTIME.block_on(voicevox_core::OpenJtalk::new(open_jtalk_dict_dir))?; - env.set_rust_field(&this, "handle", Arc::new(internal))?; + env.set_rust_field(&this, "handle", internal)?; Ok(()) }) @@ -31,7 +31,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_OpenJtalk_rsUseUserDict ) { throw_if_err(env, (), |env| { let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::OpenJtalk>(&this, "handle")? .clone(); let user_dict = env diff --git a/crates/voicevox_core_java_api/src/synthesizer.rs b/crates/voicevox_core_java_api/src/synthesizer.rs index 5e2cbb8d2..8828c6e78 100644 --- a/crates/voicevox_core_java_api/src/synthesizer.rs +++ b/crates/voicevox_core_java_api/src/synthesizer.rs @@ -50,7 +50,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsNew<'loca options.cpu_num_threads = cpu_num_threads.i().expect("cpuNumThreads is not integer") as u16; let open_jtalk = env - .get_rust_field::<_, _, Arc>(&open_jtalk, "handle")? + .get_rust_field::<_, _, voicevox_core::OpenJtalk>(&open_jtalk, "handle")? .clone(); let internal = voicevox_core::Synthesizer::new(open_jtalk, Box::leak(Box::new(options)))?; env.set_rust_field(&this, "handle", internal)?; @@ -64,7 +64,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsIsGpuMode ) -> jboolean { throw_if_err(env, false, |env| { let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); Ok(internal.is_gpu_mode()) @@ -78,7 +80,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsGetMetasJ ) -> jobject { throw_if_err(env, std::ptr::null_mut(), |env| { let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let metas_json = serde_json::to_string(&internal.metas()).expect("should not fail"); @@ -100,7 +104,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsLoadVoice .get_rust_field::<_, _, Arc>(&model, "handle")? .clone(); let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); RUNTIME.block_on(internal.load_voice_model(&model))?; Ok(()) @@ -117,7 +123,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsUnloadVoi let model_id: String = env.get_string(&model_id)?.into(); let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); internal.unload_voice_model(&voicevox_core::VoiceModelId::new(model_id))?; @@ -138,7 +146,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsIsLoadedV let model_id: String = env.get_string(&model_id)?.into(); let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let is_loaded = internal.is_loaded_voice_model(&voicevox_core::VoiceModelId::new(model_id)); @@ -162,7 +172,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAudioQuer let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let audio_query = RUNTIME.block_on( @@ -189,7 +201,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAudioQuer let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let audio_query = @@ -217,7 +231,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAccentPhr let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let accent_phrases = RUNTIME.block_on( @@ -244,7 +260,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAccentPhr let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let accent_phrases = RUNTIME.block_on( @@ -273,7 +291,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsReplaceMo let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let replaced_accent_phrases = RUNTIME.block_on( @@ -303,7 +323,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsReplacePh let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let replaced_accent_phrases = { @@ -334,7 +356,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsReplaceMo let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let replaced_accent_phrases = RUNTIME.block_on( @@ -363,7 +387,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsSynthesis let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let wave = { @@ -397,7 +423,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsTtsFromKa let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let wave = { @@ -431,7 +459,9 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsTts<'loca let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>( + &this, "handle", + )? .clone(); let wave = { diff --git a/crates/voicevox_core_python_api/src/lib.rs b/crates/voicevox_core_python_api/src/lib.rs index 86a64e394..956c924b2 100644 --- a/crates/voicevox_core_python_api/src/lib.rs +++ b/crates/voicevox_core_python_api/src/lib.rs @@ -114,7 +114,7 @@ impl VoiceModel { #[pyclass] #[derive(Clone)] struct OpenJtalk { - open_jtalk: Arc, + open_jtalk: voicevox_core::OpenJtalk, } #[pymethods] @@ -127,7 +127,7 @@ impl OpenJtalk { ) -> PyResult<&PyAny> { pyo3_asyncio::tokio::future_into_py(py, async move { let open_jtalk = voicevox_core::OpenJtalk::new(open_jtalk_dict_dir).await; - let open_jtalk = Python::with_gil(|py| open_jtalk.into_py_result(py))?.into(); + let open_jtalk = Python::with_gil(|py| open_jtalk.into_py_result(py))?; Ok(Self { open_jtalk }) }) } @@ -144,7 +144,7 @@ impl OpenJtalk { #[pyclass] struct Synthesizer { - synthesizer: Closable, + synthesizer: Closable, Self>, } #[pymethods]