From 402c994c6568bf38c99c8b3dc24fc6f6ec36628c Mon Sep 17 00:00:00 2001 From: Ryo Yamashita Date: Sun, 26 Nov 2023 00:54:10 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=E9=9F=B3=E5=A3=B0=E5=90=88=E6=88=90?= =?UTF-8?q?=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92=E4=B8=B8=E3=81=94=E3=81=A8?= =?UTF-8?q?=E3=82=B9=E3=83=AC=E3=83=83=E3=83=89=E5=88=86=E9=9B=A2=E3=81=97?= =?UTF-8?q?=E3=81=A6=E5=AE=9F=E8=A1=8C=E3=81=99=E3=82=8B=20(#692)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/voicevox_core/src/__internal.rs | 1 + .../voicevox_core/src/__internal/interop.rs | 1 + crates/voicevox_core/src/engine/open_jtalk.rs | 8 +- crates/voicevox_core/src/infer/status.rs | 13 +- crates/voicevox_core/src/lib.rs | 6 +- crates/voicevox_core/src/synthesizer.rs | 456 ++++++++++++------ crates/voicevox_core/src/task.rs | 16 + .../src/compatible_engine.rs | 16 +- .../voicevox_core_java_api/src/synthesizer.rs | 32 +- crates/voicevox_core_python_api/src/lib.rs | 4 +- 10 files changed, 380 insertions(+), 173 deletions(-) create mode 100644 crates/voicevox_core/src/__internal/interop.rs create mode 100644 crates/voicevox_core/src/task.rs diff --git a/crates/voicevox_core/src/__internal.rs b/crates/voicevox_core/src/__internal.rs index ff9f5ce3c..a23dcf086 100644 --- a/crates/voicevox_core/src/__internal.rs +++ b/crates/voicevox_core/src/__internal.rs @@ -1,4 +1,5 @@ pub mod doctest_fixtures; +pub mod interop; // VOICEVOX CORE内のラッパー向けの実装 // FIXME: 要議論: https://github.com/VOICEVOX/voicevox_core/issues/595 diff --git a/crates/voicevox_core/src/__internal/interop.rs b/crates/voicevox_core/src/__internal/interop.rs new file mode 100644 index 000000000..d76df9d88 --- /dev/null +++ b/crates/voicevox_core/src/__internal/interop.rs @@ -0,0 +1 @@ +pub use crate::synthesizer::PerformInference; diff --git a/crates/voicevox_core/src/engine/open_jtalk.rs b/crates/voicevox_core/src/engine/open_jtalk.rs index fa2e91304..e45f9a5fa 100644 --- a/crates/voicevox_core/src/engine/open_jtalk.rs +++ b/crates/voicevox_core/src/engine/open_jtalk.rs @@ -52,7 +52,7 @@ impl OpenJtalk { 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(); - tokio::task::spawn_blocking(move || { + crate::task::asyncify(move || { let mut s = Self::new_without_dic(); s.load(open_jtalk_dict_dir).map_err(|()| { // FIXME: 「システム辞書を読もうとしたけど読めなかった」というエラーをちゃんと用意する @@ -61,7 +61,6 @@ impl OpenJtalk { Ok(s) }) .await - .unwrap() } // 先に`load`を呼ぶ必要がある。 @@ -80,7 +79,7 @@ impl OpenJtalk { let words = user_dict.to_mecab_format(); - let result = tokio::task::spawn_blocking(move || -> crate::Result<_> { + let result = crate::task::asyncify(move || -> crate::Result<_> { // ユーザー辞書用のcsvを作成 let mut temp_csv = NamedTempFile::new().map_err(|e| ErrorRepr::UseUserDict(e.into()))?; @@ -111,8 +110,7 @@ impl OpenJtalk { Ok(mecab.load_with_userdic(dict_dir.as_ref(), Some(Path::new(&temp_dict_path)))) }) - .await - .unwrap()?; + .await?; if !result { return Err(ErrorRepr::UseUserDict(anyhow!("辞書のコンパイルに失敗しました")).into()); diff --git a/crates/voicevox_core/src/infer/status.rs b/crates/voicevox_core/src/infer/status.rs index 7903cb8ff..62805d37a 100644 --- a/crates/voicevox_core/src/infer/status.rs +++ b/crates/voicevox_core/src/infer/status.rs @@ -90,10 +90,16 @@ impl Status { self.is_loaded_model_by_style_id(style_id) } + /// 推論を実行する。 + /// + /// # Performance + /// + /// CPU/GPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 + /// /// # Panics /// /// `self`が`model_id`を含んでいないとき、パニックする。 - pub(crate) async fn run_session( + pub(crate) fn run_session( &self, model_id: &VoiceModelId, input: I, @@ -103,10 +109,7 @@ impl Status { I::Signature: InferenceSignature, { let sess = self.loaded_models.lock().unwrap().get(model_id); - - tokio::task::spawn_blocking(move || sess.run(input)) - .await - .unwrap() + sess.run(input) } } diff --git a/crates/voicevox_core/src/lib.rs b/crates/voicevox_core/src/lib.rs index 5bed99fdd..78552a9f8 100644 --- a/crates/voicevox_core/src/lib.rs +++ b/crates/voicevox_core/src/lib.rs @@ -11,11 +11,11 @@ mod metas; mod numerics; mod result; mod synthesizer; +mod task; mod user_dict; mod version; mod voice_model; -#[doc(hidden)] pub mod __internal; #[cfg(test)] @@ -31,7 +31,9 @@ pub use self::result::*; pub use self::voice_model::*; pub use devices::*; pub use manifest::*; -pub use synthesizer::*; +pub use synthesizer::{ + AccelerationMode, InitializeOptions, SynthesisOptions, Synthesizer, TtsOptions, +}; pub use user_dict::*; pub use version::*; diff --git a/crates/voicevox_core/src/synthesizer.rs b/crates/voicevox_core/src/synthesizer.rs index bb4afb153..383e8f6c0 100644 --- a/crates/voicevox_core/src/synthesizer.rs +++ b/crates/voicevox_core/src/synthesizer.rs @@ -3,6 +3,7 @@ use std::{ sync::Arc, }; +use easy_ext::ext; use enum_map::enum_map; use crate::{ @@ -11,9 +12,8 @@ use crate::{ }, infer::{ domain::{ - DecodeInput, DecodeOutput, InferenceDomainImpl, InferenceOperationImpl, - PredictDurationInput, PredictDurationOutput, PredictIntonationInput, - PredictIntonationOutput, + DecodeInput, DecodeOutput, InferenceOperationImpl, PredictDurationInput, + PredictDurationOutput, PredictIntonationInput, PredictIntonationOutput, }, runtimes::Onnxruntime, status::Status, @@ -27,6 +27,7 @@ use super::*; /// [`Synthesizer::synthesis`]のオプション。 /// /// [`Synthesizer::synthesis`]: Synthesizer::synthesis +#[derive(Clone)] pub struct SynthesisOptions { pub enable_interrogative_upspeak: bool, } @@ -48,6 +49,7 @@ impl From<&TtsOptions> for SynthesisOptions { /// [`Synthesizer::tts`]のオプション。 /// /// [`Synthesizer::tts`]: Synthesizer::tts +#[derive(Clone)] pub struct TtsOptions { pub enable_interrogative_upspeak: bool, } @@ -92,13 +94,160 @@ const DEFAULT_SAMPLING_RATE: u32 = 24000; pub(crate) type InferenceRuntimeImpl = Onnxruntime; /// 音声シンセサイザ。 -pub struct Synthesizer { - status: Status, - open_jtalk: Arc, - use_gpu: bool, -} +#[derive(Clone)] +pub struct Synthesizer(Arc); +// FIXME: docを書く impl Synthesizer { + pub fn new(open_jtalk: Arc, options: &InitializeOptions) -> Result { + blocking::Synthesizer::new(open_jtalk, options) + .map(Into::into) + .map(Self) + } + + pub fn is_gpu_mode(&self) -> bool { + self.0.is_gpu_mode() + } + + pub async fn load_voice_model(&self, model: &VoiceModel) -> Result<()> { + self.0.load_voice_model(model).await + } + + pub fn unload_voice_model(&self, voice_model_id: &VoiceModelId) -> Result<()> { + self.0.unload_voice_model(voice_model_id) + } + + pub fn is_loaded_voice_model(&self, voice_model_id: &VoiceModelId) -> bool { + self.0.is_loaded_voice_model(voice_model_id) + } + + #[doc(hidden)] + pub fn is_loaded_model_by_style_id(&self, style_id: StyleId) -> bool { + self.0.is_loaded_model_by_style_id(style_id) + } + + pub fn metas(&self) -> VoiceModelMeta { + self.0.metas() + } + + pub async fn synthesis( + &self, + audio_query: &AudioQueryModel, + style_id: StyleId, + options: &SynthesisOptions, + ) -> Result> { + let blocking = self.0.clone(); + let audio_query = audio_query.clone(); + let options = options.clone(); + + crate::task::asyncify(move || blocking.synthesis(&audio_query, style_id, &options)).await + } + + pub async fn create_accent_phrases_from_kana( + &self, + kana: &str, + style_id: StyleId, + ) -> Result> { + let blocking = self.0.clone(); + let kana = kana.to_owned(); + + crate::task::asyncify(move || blocking.create_accent_phrases_from_kana(&kana, style_id)) + .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], + style_id: StyleId, + ) -> Result> { + let blocking = self.0.clone(); + let accent_phrases = accent_phrases.to_owned(); + + crate::task::asyncify(move || blocking.replace_mora_data(&accent_phrases, style_id)).await + } + + pub async fn replace_phoneme_length( + &self, + accent_phrases: &[AccentPhraseModel], + style_id: StyleId, + ) -> Result> { + let blocking = self.0.clone(); + let accent_phrases = accent_phrases.to_owned(); + + crate::task::asyncify(move || blocking.replace_phoneme_length(&accent_phrases, style_id)) + .await + } + + pub async fn replace_mora_pitch( + &self, + accent_phrases: &[AccentPhraseModel], + style_id: StyleId, + ) -> Result> { + let blocking = self.0.clone(); + let accent_phrases = accent_phrases.to_owned(); + + crate::task::asyncify(move || blocking.replace_mora_pitch(&accent_phrases, style_id)).await + } + + pub async fn audio_query_from_kana( + &self, + kana: &str, + style_id: StyleId, + ) -> Result { + let blocking = self.0.clone(); + let kana = kana.to_owned(); + + 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, + style_id: StyleId, + options: &TtsOptions, + ) -> Result> { + let blocking = self.0.clone(); + let kana = kana.to_owned(); + let options = options.clone(); + + crate::task::asyncify(move || blocking.tts_from_kana(&kana, style_id, &options)).await + } + + pub async fn tts( + &self, + text: &str, + style_id: StyleId, + options: &TtsOptions, + ) -> Result> { + let blocking = self.0.clone(); + let text = text.to_owned(); + let options = options.clone(); + + crate::task::asyncify(move || blocking.tts(&text, style_id, &options)).await + } +} + +// FIXME: ここのdocのコードブロックはasync版のものなので、↑の方に移した上で、(ブロッキング版を +// public APIにするならの話ではあるが)ブロッキング版はブロッキング版でコード例を用意する +impl blocking::Synthesizer { /// `Synthesizer`をコンストラクトする。 /// /// # Example @@ -126,7 +275,7 @@ impl Synthesizer { /// # Ok(()) /// # } /// ``` - pub fn new(open_jtalk: Arc, options: &InitializeOptions) -> Result { + fn new(open_jtalk: Arc, options: &InitializeOptions) -> Result { #[cfg(windows)] list_windows_video_cards(); @@ -183,38 +332,38 @@ impl Synthesizer { } /// ハードウェアアクセラレーションがGPUモードか判定する。 - pub fn is_gpu_mode(&self) -> bool { + fn is_gpu_mode(&self) -> bool { self.use_gpu } + // FIXME: ブロッキング版を作る /// 音声モデルを読み込む。 - pub async fn load_voice_model(&self, model: &VoiceModel) -> Result<()> { + async fn load_voice_model(&self, model: &VoiceModel) -> Result<()> { let model_bytes = &model.read_inference_models().await?; self.status.load_model(model, model_bytes).await } /// 音声モデルの読み込みを解除する。 - pub fn unload_voice_model(&self, voice_model_id: &VoiceModelId) -> Result<()> { + fn unload_voice_model(&self, voice_model_id: &VoiceModelId) -> Result<()> { self.status.unload_model(voice_model_id) } /// 指定したIDの音声モデルが読み込まれているか判定する。 - pub fn is_loaded_voice_model(&self, voice_model_id: &VoiceModelId) -> bool { + fn is_loaded_voice_model(&self, voice_model_id: &VoiceModelId) -> bool { self.status.is_loaded_model(voice_model_id) } - #[doc(hidden)] - pub fn is_loaded_model_by_style_id(&self, style_id: StyleId) -> bool { + fn is_loaded_model_by_style_id(&self, style_id: StyleId) -> bool { self.status.is_loaded_model_by_style_id(style_id) } /// 今読み込んでいる音声モデルのメタ情報を返す。 - pub fn metas(&self) -> VoiceModelMeta { + fn metas(&self) -> VoiceModelMeta { self.status.metas() } /// AudioQueryから音声合成を行う。 - pub async fn synthesis( + fn synthesis( &self, audio_query: &AudioQueryModel, style_id: StyleId, @@ -315,15 +464,13 @@ impl Synthesizer { // 2次元のvectorを1次元に変換し、アドレスを連続させる let flatten_phoneme = phoneme.into_iter().flatten().collect::>(); - let wave = &self - .decode( - f0.len(), - OjtPhoneme::num_phoneme(), - &f0, - &flatten_phoneme, - style_id, - ) - .await?; + let wave = &self.decode( + f0.len(), + OjtPhoneme::num_phoneme(), + &f0, + &flatten_phoneme, + style_id, + )?; return Ok(to_wav(wave, audio_query)); fn adjust_interrogative_accent_phrases( @@ -445,12 +592,12 @@ impl Synthesizer { /// # Ok(()) /// # } /// ``` - pub async fn create_accent_phrases_from_kana( + fn create_accent_phrases_from_kana( &self, kana: &str, style_id: StyleId, ) -> Result> { - self.replace_mora_data(&parse_kana(kana)?, style_id).await + self.replace_mora_data(&parse_kana(kana)?, style_id) } /// 日本語のテキストからAccentPhrase (アクセント句)の配列を生成する。 @@ -476,7 +623,7 @@ impl Synthesizer { /// # Ok(()) /// # } /// ``` - pub async fn create_accent_phrases( + fn create_accent_phrases( &self, text: &str, style_id: StyleId, @@ -554,23 +701,21 @@ impl Synthesizer { accum_vec }); - self.replace_mora_data(&accent_phrases, style_id).await + self.replace_mora_data(&accent_phrases, style_id) } /// AccentPhraseの配列の音高・音素長を、特定の声で生成しなおす。 - pub async fn replace_mora_data( + fn replace_mora_data( &self, accent_phrases: &[AccentPhraseModel], style_id: StyleId, ) -> Result> { - let accent_phrases = self - .replace_phoneme_length(accent_phrases, style_id) - .await?; - self.replace_mora_pitch(&accent_phrases, style_id).await + let accent_phrases = self.replace_phoneme_length(accent_phrases, style_id)?; + self.replace_mora_pitch(&accent_phrases, style_id) } /// AccentPhraseの配列の音素長を、特定の声で生成しなおす。 - pub async fn replace_phoneme_length( + fn replace_phoneme_length( &self, accent_phrases: &[AccentPhraseModel], style_id: StyleId, @@ -583,7 +728,7 @@ impl Synthesizer { .iter() .map(|phoneme_data| phoneme_data.phoneme_id()) .collect(); - let phoneme_length = self.predict_duration(&phoneme_list_s, style_id).await?; + let phoneme_length = self.predict_duration(&phoneme_list_s, style_id)?; let mut index = 0; let new_accent_phrases = accent_phrases @@ -630,7 +775,7 @@ impl Synthesizer { } /// AccentPhraseの配列の音高を、特定の声で生成しなおす。 - pub async fn replace_mora_pitch( + fn replace_mora_pitch( &self, accent_phrases: &[AccentPhraseModel], style_id: StyleId, @@ -679,18 +824,16 @@ impl Synthesizer { end_accent_phrase_list.push(base_end_accent_phrase_list[vowel_index as usize]); } - let mut f0_list = self - .predict_intonation( - vowel_phoneme_list.len(), - &vowel_phoneme_list, - &consonant_phoneme_list, - &start_accent_list, - &end_accent_list, - &start_accent_phrase_list, - &end_accent_phrase_list, - style_id, - ) - .await?; + let mut f0_list = self.predict_intonation( + vowel_phoneme_list.len(), + &vowel_phoneme_list, + &consonant_phoneme_list, + &start_accent_list, + &end_accent_list, + &start_accent_phrase_list, + &end_accent_phrase_list, + style_id, + )?; for i in 0..vowel_phoneme_data_list.len() { const UNVOICED_MORA_PHONEME_LIST: &[&str] = &["A", "I", "U", "E", "O", "cl", "pau"]; @@ -792,12 +935,8 @@ impl Synthesizer { /// ``` /// /// [AudioQuery]: crate::AudioQueryModel - pub async fn audio_query_from_kana( - &self, - kana: &str, - style_id: StyleId, - ) -> Result { - let accent_phrases = self.create_accent_phrases_from_kana(kana, style_id).await?; + fn audio_query_from_kana(&self, kana: &str, style_id: StyleId) -> Result { + 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()))) } @@ -826,45 +965,78 @@ impl Synthesizer { /// ``` /// /// [AudioQuery]: crate::AudioQueryModel - pub async fn audio_query(&self, text: &str, style_id: StyleId) -> Result { - let accent_phrases = self.create_accent_phrases(text, style_id).await?; + fn audio_query(&self, text: &str, style_id: StyleId) -> Result { + let accent_phrases = self.create_accent_phrases(text, style_id)?; Ok(AudioQueryModel::from_accent_phrases(accent_phrases)) } /// AquesTalk風記法から音声合成を行う。 - pub async fn tts_from_kana( + fn tts_from_kana( &self, kana: &str, style_id: StyleId, options: &TtsOptions, ) -> Result> { - let audio_query = &self.audio_query_from_kana(kana, style_id).await?; + let audio_query = &self.audio_query_from_kana(kana, style_id)?; self.synthesis(audio_query, style_id, &SynthesisOptions::from(options)) - .await } /// 日本語のテキストから音声合成を行う。 - pub async fn tts( - &self, - text: &str, - style_id: StyleId, - options: &TtsOptions, - ) -> Result> { - let audio_query = &self.audio_query(text, style_id).await?; + fn tts(&self, text: &str, style_id: StyleId, options: &TtsOptions) -> Result> { + let audio_query = &self.audio_query(text, style_id)?; self.synthesis(audio_query, style_id, &SynthesisOptions::from(options)) - .await } } -// FIXME: `async`を剥がしたのち`pub trait PerformInference`(sealed)に切り出し、それを -// `crate::__internal`から外に出す -#[doc(hidden)] -impl Synthesizer { - pub async fn predict_duration( +impl PerformInference for Synthesizer { + fn predict_duration(&self, phoneme_vector: &[i64], style_id: StyleId) -> Result> { + self.0.predict_duration(phoneme_vector, style_id) + } + + fn predict_intonation( &self, - phoneme_vector: &[i64], + 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> { + self.0.predict_intonation( + length, + vowel_phoneme_vector, + consonant_phoneme_vector, + start_accent_vector, + end_accent_vector, + start_accent_phrase_vector, + end_accent_phrase_vector, + style_id, + ) + } + + fn decode( + &self, + length: usize, + phoneme_size: usize, + f0: &[f32], + phoneme_vector: &[f32], + style_id: StyleId, + ) -> Result> { + self.0 + .decode(length, phoneme_size, f0, phoneme_vector, style_id) + } +} + +#[ext(PerformInference)] +impl blocking::Synthesizer { + /// `predict_duration`を実行する。 + /// + /// # Performance + /// + /// CPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 + pub 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()); @@ -874,16 +1046,13 @@ impl Synthesizer { let PredictDurationOutput { phoneme_length: output, - } = self - .status - .run_session( - &model_id, - PredictDurationInput { - phoneme_list: ndarray::arr1(phoneme_vector), - speaker_id: ndarray::arr1(&[model_inner_id.raw_id().into()]), - }, - ) - .await?; + } = self.status.run_session( + &model_id, + PredictDurationInput { + phoneme_list: ndarray::arr1(phoneme_vector), + speaker_id: ndarray::arr1(&[model_inner_id.raw_id().into()]), + }, + )?; let mut output = output.into_raw_vec(); for output_item in output.iter_mut() { @@ -897,8 +1066,13 @@ impl Synthesizer { const PHONEME_LENGTH_MINIMAL: f32 = 0.01; } + /// `predict_intonation`を実行する。 + /// + /// # Performance + /// + /// CPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 #[allow(clippy::too_many_arguments)] - pub async fn predict_intonation( + pub fn predict_intonation( &self, length: usize, vowel_phoneme_vector: &[i64], @@ -916,27 +1090,29 @@ impl Synthesizer { let (model_id, model_inner_id) = self.status.ids_for(style_id)?; - let PredictIntonationOutput { f0_list: output } = self - .status - .run_session( - &model_id, - PredictIntonationInput { - length: ndarray::arr0(length as i64), - vowel_phoneme_list: ndarray::arr1(vowel_phoneme_vector), - consonant_phoneme_list: ndarray::arr1(consonant_phoneme_vector), - start_accent_list: ndarray::arr1(start_accent_vector), - end_accent_list: ndarray::arr1(end_accent_vector), - start_accent_phrase_list: ndarray::arr1(start_accent_phrase_vector), - end_accent_phrase_list: ndarray::arr1(end_accent_phrase_vector), - speaker_id: ndarray::arr1(&[model_inner_id.raw_id().into()]), - }, - ) - .await?; + let PredictIntonationOutput { f0_list: output } = self.status.run_session( + &model_id, + PredictIntonationInput { + length: ndarray::arr0(length as i64), + vowel_phoneme_list: ndarray::arr1(vowel_phoneme_vector), + consonant_phoneme_list: ndarray::arr1(consonant_phoneme_vector), + start_accent_list: ndarray::arr1(start_accent_vector), + end_accent_list: ndarray::arr1(end_accent_vector), + start_accent_phrase_list: ndarray::arr1(start_accent_phrase_vector), + end_accent_phrase_list: ndarray::arr1(end_accent_phrase_vector), + speaker_id: ndarray::arr1(&[model_inner_id.raw_id().into()]), + }, + )?; Ok(output.into_raw_vec()) } - pub async fn decode( + /// `decode`を実行する。 + /// + /// # Performance + /// + /// CPU/GPU-boundな操作であるため、非同期ランタイム上では直接実行されるべきではない。 + pub fn decode( &self, length: usize, phoneme_size: usize, @@ -966,21 +1142,18 @@ impl Synthesizer { padding_size, ); - let DecodeOutput { wave: output } = self - .status - .run_session( - &model_id, - DecodeInput { - f0: ndarray::arr1(&f0_with_padding) - .into_shape([length_with_padding, 1]) - .unwrap(), - phoneme: ndarray::arr1(&phoneme_with_padding) - .into_shape([length_with_padding, phoneme_size]) - .unwrap(), - speaker_id: ndarray::arr1(&[model_inner_id.raw_id().into()]), - }, - ) - .await?; + let DecodeOutput { wave: output } = self.status.run_session( + &model_id, + DecodeInput { + f0: ndarray::arr1(&f0_with_padding) + .into_shape([length_with_padding, 1]) + .unwrap(), + phoneme: ndarray::arr1(&phoneme_with_padding) + .into_shape([length_with_padding, phoneme_size]) + .unwrap(), + speaker_id: ndarray::arr1(&[model_inner_id.raw_id().into()]), + }, + )?; return Ok(trim_padding_from_output( output.into_raw_vec(), @@ -1186,6 +1359,23 @@ impl AudioQueryModel { } } +mod blocking { + use std::sync::Arc; + + use crate::{ + engine::OpenJtalk, + infer::{domain::InferenceDomainImpl, status::Status}, + }; + + use super::InferenceRuntimeImpl; + + pub(super) struct Synthesizer { + pub(super) status: Status, + pub(super) open_jtalk: Arc, + pub(super) use_gpu: bool, + } +} + #[cfg(test)] mod tests { @@ -1284,9 +1474,7 @@ mod tests { 30, 35, 14, 23, 7, 21, 14, 43, 30, 30, 23, 30, 35, 30, 0, ]; - let result = syntesizer - .predict_duration(&phoneme_vector, StyleId::new(1)) - .await; + let result = syntesizer.predict_duration(&phoneme_vector, StyleId::new(1)); assert!(result.is_ok(), "{result:?}"); assert_eq!(result.unwrap().len(), phoneme_vector.len()); @@ -1316,18 +1504,16 @@ mod tests { let start_accent_phrase_vector = [0, 1, 0, 0, 0]; let end_accent_phrase_vector = [0, 0, 0, 1, 0]; - let result = syntesizer - .predict_intonation( - vowel_phoneme_vector.len(), - &vowel_phoneme_vector, - &consonant_phoneme_vector, - &start_accent_vector, - &end_accent_vector, - &start_accent_phrase_vector, - &end_accent_phrase_vector, - StyleId::new(1), - ) - .await; + let result = syntesizer.predict_intonation( + vowel_phoneme_vector.len(), + &vowel_phoneme_vector, + &consonant_phoneme_vector, + &start_accent_vector, + &end_accent_vector, + &start_accent_phrase_vector, + &end_accent_phrase_vector, + StyleId::new(1), + ); assert!(result.is_ok(), "{result:?}"); assert_eq!(result.unwrap().len(), vowel_phoneme_vector.len()); @@ -1371,9 +1557,7 @@ mod tests { set_one(30, 45..60); set_one(0, 60..69); - let result = syntesizer - .decode(F0_LENGTH, PHONEME_SIZE, &f0, &phoneme, StyleId::new(1)) - .await; + let result = syntesizer.decode(F0_LENGTH, PHONEME_SIZE, &f0, &phoneme, StyleId::new(1)); assert!(result.is_ok(), "{result:?}"); assert_eq!(result.unwrap().len(), F0_LENGTH * 256); diff --git a/crates/voicevox_core/src/task.rs b/crates/voicevox_core/src/task.rs new file mode 100644 index 000000000..951e3c19e --- /dev/null +++ b/crates/voicevox_core/src/task.rs @@ -0,0 +1,16 @@ +use std::panic; + +/// ブロッキング操作を非同期化する。 +/// +/// # Panics +/// +/// - `f`がパニックした場合、パニックがそのままunwindされる。 +/// - tokioのランタイムの都合で`f`の実行が"cancel"された場合パニックする。 +pub(crate) async fn asyncify R + Send + 'static, R: Send + 'static>(f: F) -> R { + tokio::task::spawn_blocking(f) + .await + .unwrap_or_else(|err| match err.try_into_panic() { + Ok(panic) => panic::resume_unwind(panic), + Err(err) => panic!("{err}"), // FIXME: エラーとして回収する + }) +} diff --git a/crates/voicevox_core_c_api/src/compatible_engine.rs b/crates/voicevox_core_c_api/src/compatible_engine.rs index dd8ce8e94..8f2d7c5cc 100644 --- a/crates/voicevox_core_c_api/src/compatible_engine.rs +++ b/crates/voicevox_core_c_api/src/compatible_engine.rs @@ -3,7 +3,7 @@ use std::{collections::BTreeMap, sync::Arc}; use super::*; use libc::c_int; -use voicevox_core::{OpenJtalk, StyleId, VoiceModel}; +use voicevox_core::{OpenJtalk, StyleId, VoiceModel, __internal::interop::PerformInference as _}; macro_rules! ensure_initialized { ($synthesizer:expr $(,)?) => { @@ -104,6 +104,8 @@ fn set_message(message: &str) { #[no_mangle] pub extern "C" fn initialize(use_gpu: bool, cpu_num_threads: c_int, load_all_models: bool) -> bool { + // FIXME: ここはもう`RUNTIME.block_on`で包む必要は無くなっているのだが、ロガーの設定を`RUNTIME` + // で行っているという構造になってしまっているので、外すとロガーの初期化が遅れてしまでう let result = RUNTIME.block_on(async { let synthesizer = voicevox_core::Synthesizer::new( Arc::new(OpenJtalk::new_without_dic()), @@ -197,10 +199,10 @@ pub extern "C" fn yukarin_s_forward( output: *mut f32, ) -> bool { let synthesizer = &*lock_synthesizer(); - let result = RUNTIME.block_on(ensure_initialized!(synthesizer).predict_duration( + let result = ensure_initialized!(synthesizer).predict_duration( unsafe { std::slice::from_raw_parts_mut(phoneme_list, length as usize) }, StyleId::new(unsafe { *speaker_id as u32 }), - )); + ); match result { Ok(output_vec) => { let output_slice = unsafe { std::slice::from_raw_parts_mut(output, length as usize) }; @@ -227,7 +229,7 @@ pub extern "C" fn yukarin_sa_forward( output: *mut f32, ) -> bool { let synthesizer = &*lock_synthesizer(); - let result = RUNTIME.block_on(ensure_initialized!(synthesizer).predict_intonation( + let result = ensure_initialized!(synthesizer).predict_intonation( length as usize, unsafe { std::slice::from_raw_parts(vowel_phoneme_list, length as usize) }, unsafe { std::slice::from_raw_parts(consonant_phoneme_list, length as usize) }, @@ -236,7 +238,7 @@ pub extern "C" fn yukarin_sa_forward( unsafe { std::slice::from_raw_parts(start_accent_phrase_list, length as usize) }, unsafe { std::slice::from_raw_parts(end_accent_phrase_list, length as usize) }, StyleId::new(unsafe { *speaker_id as u32 }), - )); + ); match result { Ok(output_vec) => { let output_slice = unsafe { std::slice::from_raw_parts_mut(output, length as usize) }; @@ -262,13 +264,13 @@ pub extern "C" fn decode_forward( let length = length as usize; let phoneme_size = phoneme_size as usize; let synthesizer = &*lock_synthesizer(); - let result = RUNTIME.block_on(ensure_initialized!(synthesizer).decode( + let result = ensure_initialized!(synthesizer).decode( length, phoneme_size, unsafe { std::slice::from_raw_parts(f0, length) }, unsafe { std::slice::from_raw_parts(phoneme, phoneme_size * length) }, StyleId::new(unsafe { *speaker_id as u32 }), - )); + ); match result { Ok(output_vec) => { let output_slice = unsafe { std::slice::from_raw_parts_mut(output, length * 256) }; diff --git a/crates/voicevox_core_java_api/src/synthesizer.rs b/crates/voicevox_core_java_api/src/synthesizer.rs index 9d3cb9f9f..5e2cbb8d2 100644 --- a/crates/voicevox_core_java_api/src/synthesizer.rs +++ b/crates/voicevox_core_java_api/src/synthesizer.rs @@ -53,7 +53,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsNew<'loca .get_rust_field::<_, _, Arc>(&open_jtalk, "handle")? .clone(); let internal = voicevox_core::Synthesizer::new(open_jtalk, Box::leak(Box::new(options)))?; - env.set_rust_field(&this, "handle", Arc::new(internal))?; + env.set_rust_field(&this, "handle", internal)?; Ok(()) }) } @@ -64,7 +64,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsIsGpuMode ) -> jboolean { throw_if_err(env, false, |env| { let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); Ok(internal.is_gpu_mode()) @@ -78,7 +78,7 @@ 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::<_, _, Arc>(&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 +100,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsLoadVoice .get_rust_field::<_, _, Arc>(&model, "handle")? .clone(); let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); RUNTIME.block_on(internal.load_voice_model(&model))?; Ok(()) @@ -117,7 +117,7 @@ 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::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); internal.unload_voice_model(&voicevox_core::VoiceModelId::new(model_id))?; @@ -138,7 +138,7 @@ 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::<_, _, Arc>(&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 +162,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAudioQuer let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let audio_query = RUNTIME.block_on( @@ -189,7 +189,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAudioQuer let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let audio_query = @@ -217,7 +217,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAccentPhr let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let accent_phrases = RUNTIME.block_on( @@ -244,7 +244,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsAccentPhr let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let accent_phrases = RUNTIME.block_on( @@ -273,7 +273,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsReplaceMo let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let replaced_accent_phrases = RUNTIME.block_on( @@ -303,7 +303,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsReplacePh let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let replaced_accent_phrases = { @@ -334,7 +334,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsReplaceMo let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let replaced_accent_phrases = RUNTIME.block_on( @@ -363,7 +363,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsSynthesis let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let wave = { @@ -397,7 +397,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsTtsFromKa let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&this, "handle")? + .get_rust_field::<_, _, voicevox_core::Synthesizer>(&this, "handle")? .clone(); let wave = { @@ -431,7 +431,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_Synthesizer_rsTts<'loca let style_id = style_id as u32; let internal = env - .get_rust_field::<_, _, Arc>(&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 e96a3d8c4..86a64e394 100644 --- a/crates/voicevox_core_python_api/src/lib.rs +++ b/crates/voicevox_core_python_api/src/lib.rs @@ -144,7 +144,7 @@ impl OpenJtalk { #[pyclass] struct Synthesizer { - synthesizer: Closable, Self>, + synthesizer: Closable, } #[pymethods] @@ -167,7 +167,7 @@ impl Synthesizer { cpu_num_threads, }, ); - let synthesizer = Python::with_gil(|py| synthesizer.into_py_result(py))?.into(); + let synthesizer = Python::with_gil(|py| synthesizer.into_py_result(py))?; let synthesizer = Closable::new(synthesizer); Ok(Self { synthesizer }) } From 67640c1853d831f0104ee38dc30c3d7321bfabcd Mon Sep 17 00:00:00 2001 From: Ryo Yamashita Date: Mon, 27 Nov 2023 10:52:10 +0900 Subject: [PATCH 2/4] =?UTF-8?q?`OpenJtalk`=E3=82=92`Synthesizer?= =?UTF-8?q?=20|=20Synthesizer<()>`=E3=81=A8=E3=81=97=E3=81=A6=E6=8C=81?= =?UTF-8?q?=E3=81=A4=20(#694)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/__internal/doctest_fixtures.rs | 6 +- crates/voicevox_core/src/engine/open_jtalk.rs | 77 +++----- crates/voicevox_core/src/synthesizer.rs | 169 ++++++++++-------- crates/voicevox_core_c_api/src/c_impls.rs | 4 +- .../src/compatible_engine.rs | 10 +- crates/voicevox_core_c_api/src/lib.rs | 4 +- .../voicevox_core_java_api/src/open_jtalk.rs | 4 +- .../voicevox_core_java_api/src/synthesizer.rs | 62 +++++-- crates/voicevox_core_python_api/src/lib.rs | 6 +- 9 files changed, 187 insertions(+), 155 deletions(-) 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] From 667f1571bf01b47bfc48aa998f9b9946d9abf75f Mon Sep 17 00:00:00 2001 From: Ryo Yamashita Date: Tue, 28 Nov 2023 03:01:29 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Pydantic=E3=82=92v2=E3=81=AB=E4=B8=8A?= =?UTF-8?q?=E3=81=92=E3=82=8B=20(#695)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/voicevox_core_python_api/poetry.lock | 182 ++++++++++++++---- .../voicevox_core_python_api/pyproject.toml | 4 +- .../python/voicevox_core/_models.py | 8 +- 3 files changed, 147 insertions(+), 47 deletions(-) diff --git a/crates/voicevox_core_python_api/poetry.lock b/crates/voicevox_core_python_api/poetry.lock index df5f580ed..0a78abec8 100644 --- a/crates/voicevox_core_python_api/poetry.lock +++ b/crates/voicevox_core_python_api/poetry.lock @@ -25,6 +25,20 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} + [[package]] name = "anyascii" version = "0.3.2" @@ -543,55 +557,139 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "1.10.13" -description = "Data validation and settings management using python type hints" +version = "2.5.2" +description = "Data validation using Python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, - {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, - {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, - {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, - {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, - {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, - {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, - {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, - {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, - {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, + {file = "pydantic-2.5.2-py3-none-any.whl", hash = "sha256:80c50fb8e3dcecfddae1adbcc00ec5822918490c99ab31f6cf6140ca1c1429f0"}, + {file = "pydantic-2.5.2.tar.gz", hash = "sha256:ff177ba64c6faf73d7afa2e8cad38fd456c0dbe01c9954e71038001cd15a6edd"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.14.5" +typing-extensions = ">=4.6.1" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.14.5" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic_core-2.14.5-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:7e88f5696153dc516ba6e79f82cc4747e87027205f0e02390c21f7cb3bd8abfd"}, + {file = "pydantic_core-2.14.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4641e8ad4efb697f38a9b64ca0523b557c7931c5f84e0fd377a9a3b05121f0de"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:774de879d212db5ce02dfbf5b0da9a0ea386aeba12b0b95674a4ce0593df3d07"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ebb4e035e28f49b6f1a7032920bb9a0c064aedbbabe52c543343d39341a5b2a3"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b53e9ad053cd064f7e473a5f29b37fc4cc9dc6d35f341e6afc0155ea257fc911"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aa1768c151cf562a9992462239dfc356b3d1037cc5a3ac829bb7f3bda7cc1f9"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eac5c82fc632c599f4639a5886f96867ffced74458c7db61bc9a66ccb8ee3113"}, + {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae91f50ccc5810b2f1b6b858257c9ad2e08da70bf890dee02de1775a387c66"}, + {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6b9ff467ffbab9110e80e8c8de3bcfce8e8b0fd5661ac44a09ae5901668ba997"}, + {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61ea96a78378e3bd5a0be99b0e5ed00057b71f66115f5404d0dae4819f495093"}, + {file = "pydantic_core-2.14.5-cp310-none-win32.whl", hash = "sha256:bb4c2eda937a5e74c38a41b33d8c77220380a388d689bcdb9b187cf6224c9720"}, + {file = "pydantic_core-2.14.5-cp310-none-win_amd64.whl", hash = "sha256:b7851992faf25eac90bfcb7bfd19e1f5ffa00afd57daec8a0042e63c74a4551b"}, + {file = "pydantic_core-2.14.5-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:4e40f2bd0d57dac3feb3a3aed50f17d83436c9e6b09b16af271b6230a2915459"}, + {file = "pydantic_core-2.14.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab1cdb0f14dc161ebc268c09db04d2c9e6f70027f3b42446fa11c153521c0e88"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aae7ea3a1c5bb40c93cad361b3e869b180ac174656120c42b9fadebf685d121b"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60b7607753ba62cf0739177913b858140f11b8af72f22860c28eabb2f0a61937"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2248485b0322c75aee7565d95ad0e16f1c67403a470d02f94da7344184be770f"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:823fcc638f67035137a5cd3f1584a4542d35a951c3cc68c6ead1df7dac825c26"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96581cfefa9123accc465a5fd0cc833ac4d75d55cc30b633b402e00e7ced00a6"}, + {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a33324437018bf6ba1bb0f921788788641439e0ed654b233285b9c69704c27b4"}, + {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9bd18fee0923ca10f9a3ff67d4851c9d3e22b7bc63d1eddc12f439f436f2aada"}, + {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:853a2295c00f1d4429db4c0fb9475958543ee80cfd310814b5c0ef502de24dda"}, + {file = "pydantic_core-2.14.5-cp311-none-win32.whl", hash = "sha256:cb774298da62aea5c80a89bd58c40205ab4c2abf4834453b5de207d59d2e1651"}, + {file = "pydantic_core-2.14.5-cp311-none-win_amd64.whl", hash = "sha256:e87fc540c6cac7f29ede02e0f989d4233f88ad439c5cdee56f693cc9c1c78077"}, + {file = "pydantic_core-2.14.5-cp311-none-win_arm64.whl", hash = "sha256:57d52fa717ff445cb0a5ab5237db502e6be50809b43a596fb569630c665abddf"}, + {file = "pydantic_core-2.14.5-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:e60f112ac88db9261ad3a52032ea46388378034f3279c643499edb982536a093"}, + {file = "pydantic_core-2.14.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6e227c40c02fd873c2a73a98c1280c10315cbebe26734c196ef4514776120aeb"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0cbc7fff06a90bbd875cc201f94ef0ee3929dfbd5c55a06674b60857b8b85ed"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:103ef8d5b58596a731b690112819501ba1db7a36f4ee99f7892c40da02c3e189"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c949f04ecad823f81b1ba94e7d189d9dfb81edbb94ed3f8acfce41e682e48cef"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1452a1acdf914d194159439eb21e56b89aa903f2e1c65c60b9d874f9b950e5d"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb4679d4c2b089e5ef89756bc73e1926745e995d76e11925e3e96a76d5fa51fc"}, + {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf9d3fe53b1ee360e2421be95e62ca9b3296bf3f2fb2d3b83ca49ad3f925835e"}, + {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:70f4b4851dbb500129681d04cc955be2a90b2248d69273a787dda120d5cf1f69"}, + {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:59986de5710ad9613ff61dd9b02bdd2f615f1a7052304b79cc8fa2eb4e336d2d"}, + {file = "pydantic_core-2.14.5-cp312-none-win32.whl", hash = "sha256:699156034181e2ce106c89ddb4b6504c30db8caa86e0c30de47b3e0654543260"}, + {file = "pydantic_core-2.14.5-cp312-none-win_amd64.whl", hash = "sha256:5baab5455c7a538ac7e8bf1feec4278a66436197592a9bed538160a2e7d11e36"}, + {file = "pydantic_core-2.14.5-cp312-none-win_arm64.whl", hash = "sha256:e47e9a08bcc04d20975b6434cc50bf82665fbc751bcce739d04a3120428f3e27"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:af36f36538418f3806048f3b242a1777e2540ff9efaa667c27da63d2749dbce0"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:45e95333b8418ded64745f14574aa9bfc212cb4fbeed7a687b0c6e53b5e188cd"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e47a76848f92529879ecfc417ff88a2806438f57be4a6a8bf2961e8f9ca9ec7"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d81e6987b27bc7d101c8597e1cd2bcaa2fee5e8e0f356735c7ed34368c471550"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34708cc82c330e303f4ce87758828ef6e457681b58ce0e921b6e97937dd1e2a3"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:652c1988019752138b974c28f43751528116bcceadad85f33a258869e641d753"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e4d090e73e0725b2904fdbdd8d73b8802ddd691ef9254577b708d413bf3006e"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5c7d5b5005f177764e96bd584d7bf28d6e26e96f2a541fdddb934c486e36fd59"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a71891847f0a73b1b9eb86d089baee301477abef45f7eaf303495cd1473613e4"}, + {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a717aef6971208f0851a2420b075338e33083111d92041157bbe0e2713b37325"}, + {file = "pydantic_core-2.14.5-cp37-none-win32.whl", hash = "sha256:de790a3b5aa2124b8b78ae5faa033937a72da8efe74b9231698b5a1dd9be3405"}, + {file = "pydantic_core-2.14.5-cp37-none-win_amd64.whl", hash = "sha256:6c327e9cd849b564b234da821236e6bcbe4f359a42ee05050dc79d8ed2a91588"}, + {file = "pydantic_core-2.14.5-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:ef98ca7d5995a82f43ec0ab39c4caf6a9b994cb0b53648ff61716370eadc43cf"}, + {file = "pydantic_core-2.14.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6eae413494a1c3f89055da7a5515f32e05ebc1a234c27674a6956755fb2236f"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcf4e6d85614f7a4956c2de5a56531f44efb973d2fe4a444d7251df5d5c4dcfd"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6637560562134b0e17de333d18e69e312e0458ee4455bdad12c37100b7cad706"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77fa384d8e118b3077cccfcaf91bf83c31fe4dc850b5e6ee3dc14dc3d61bdba1"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16e29bad40bcf97aac682a58861249ca9dcc57c3f6be22f506501833ddb8939c"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531f4b4252fac6ca476fbe0e6f60f16f5b65d3e6b583bc4d87645e4e5ddde331"}, + {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:074f3d86f081ce61414d2dc44901f4f83617329c6f3ab49d2bc6c96948b2c26b"}, + {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c2adbe22ab4babbca99c75c5d07aaf74f43c3195384ec07ccbd2f9e3bddaecec"}, + {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0f6116a558fd06d1b7c2902d1c4cf64a5bd49d67c3540e61eccca93f41418124"}, + {file = "pydantic_core-2.14.5-cp38-none-win32.whl", hash = "sha256:fe0a5a1025eb797752136ac8b4fa21aa891e3d74fd340f864ff982d649691867"}, + {file = "pydantic_core-2.14.5-cp38-none-win_amd64.whl", hash = "sha256:079206491c435b60778cf2b0ee5fd645e61ffd6e70c47806c9ed51fc75af078d"}, + {file = "pydantic_core-2.14.5-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a6a16f4a527aae4f49c875da3cdc9508ac7eef26e7977952608610104244e1b7"}, + {file = "pydantic_core-2.14.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:abf058be9517dc877227ec3223f0300034bd0e9f53aebd63cf4456c8cb1e0863"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b08aae5013640a3bfa25a8eebbd95638ec3f4b2eaf6ed82cf0c7047133f03b"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2d97e906b4ff36eb464d52a3bc7d720bd6261f64bc4bcdbcd2c557c02081ed2"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3128e0bbc8c091ec4375a1828d6118bc20404883169ac95ffa8d983b293611e6"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88e74ab0cdd84ad0614e2750f903bb0d610cc8af2cc17f72c28163acfcf372a4"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c339dabd8ee15f8259ee0f202679b6324926e5bc9e9a40bf981ce77c038553db"}, + {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3387277f1bf659caf1724e1afe8ee7dbc9952a82d90f858ebb931880216ea955"}, + {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ba6b6b3846cfc10fdb4c971980a954e49d447cd215ed5a77ec8190bc93dd7bc5"}, + {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca61d858e4107ce5e1330a74724fe757fc7135190eb5ce5c9d0191729f033209"}, + {file = "pydantic_core-2.14.5-cp39-none-win32.whl", hash = "sha256:ec1e72d6412f7126eb7b2e3bfca42b15e6e389e1bc88ea0069d0cc1742f477c6"}, + {file = "pydantic_core-2.14.5-cp39-none-win_amd64.whl", hash = "sha256:c0b97ec434041827935044bbbe52b03d6018c2897349670ff8fe11ed24d1d4ab"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79e0a2cdbdc7af3f4aee3210b1172ab53d7ddb6a2d8c24119b5706e622b346d0"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:678265f7b14e138d9a541ddabbe033012a2953315739f8cfa6d754cc8063e8ca"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b15e855ae44f0c6341ceb74df61b606e11f1087e87dcb7482377374aac6abe"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09b0e985fbaf13e6b06a56d21694d12ebca6ce5414b9211edf6f17738d82b0f8"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ad873900297bb36e4b6b3f7029d88ff9829ecdc15d5cf20161775ce12306f8a"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2d0ae0d8670164e10accbeb31d5ad45adb71292032d0fdb9079912907f0085f4"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d37f8ec982ead9ba0a22a996129594938138a1503237b87318392a48882d50b7"}, + {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:35613015f0ba7e14c29ac6c2483a657ec740e5ac5758d993fdd5870b07a61d8b"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab4ea451082e684198636565224bbb179575efc1658c48281b2c866bfd4ddf04"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ce601907e99ea5b4adb807ded3570ea62186b17f88e271569144e8cca4409c7"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb2ed8b3fe4bf4506d6dab3b93b83bbc22237e230cba03866d561c3577517d18"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70f947628e074bb2526ba1b151cee10e4c3b9670af4dbb4d73bc8a89445916b5"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4bc536201426451f06f044dfbf341c09f540b4ebdb9fd8d2c6164d733de5e634"}, + {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4791cf0f8c3104ac668797d8c514afb3431bc3305f5638add0ba1a5a37e0d88"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:038c9f763e650712b899f983076ce783175397c848da04985658e7628cbe873b"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:27548e16c79702f1e03f5628589c6057c9ae17c95b4c449de3c66b589ead0520"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97bee68898f3f4344eb02fec316db93d9700fb1e6a5b760ffa20d71d9a46ce3"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9b759b77f5337b4ea024f03abc6464c9f35d9718de01cfe6bae9f2e139c397e"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:439c9afe34638ace43a49bf72d201e0ffc1a800295bed8420c2a9ca8d5e3dbb3"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ba39688799094c75ea8a16a6b544eb57b5b0f3328697084f3f2790892510d144"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ccd4d5702bb90b84df13bd491be8d900b92016c5a455b7e14630ad7449eb03f8"}, + {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:81982d78a45d1e5396819bbb4ece1fadfe5f079335dd28c4ab3427cd95389944"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:7f8210297b04e53bc3da35db08b7302a6a1f4889c79173af69b72ec9754796b8"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:8c8a8812fe6f43a3a5b054af6ac2d7b8605c7bcab2804a8a7d68b53f3cd86e00"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:206ed23aecd67c71daf5c02c3cd19c0501b01ef3cbf7782db9e4e051426b3d0d"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2027d05c8aebe61d898d4cffd774840a9cb82ed356ba47a90d99ad768f39789"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40180930807ce806aa71eda5a5a5447abb6b6a3c0b4b3b1b1962651906484d68"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:615a0a4bff11c45eb3c1996ceed5bdaa2f7b432425253a7c2eed33bb86d80abc"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5e412d717366e0677ef767eac93566582518fe8be923361a5c204c1a62eaafe"}, + {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:513b07e99c0a267b1d954243845d8a833758a6726a3b5d8948306e3fe14675e3"}, + {file = "pydantic_core-2.14.5.tar.gz", hash = "sha256:6d30226dfc816dd0fdf120cae611dd2215117e4f9b124af8c60ab9093b6e8e71"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydata-sphinx-theme" @@ -992,4 +1090,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.13" -content-hash = "775d436e43d6da637cdc673b8509d4acfb7673fbf5a87153c732d4cfbc0628c3" +content-hash = "42faee9d02ea5ad43eaef485f2127f0ffd77a5f8951ef71529eb1e85249e9c04" diff --git a/crates/voicevox_core_python_api/pyproject.toml b/crates/voicevox_core_python_api/pyproject.toml index 3164bc528..5ad0bd6d8 100644 --- a/crates/voicevox_core_python_api/pyproject.toml +++ b/crates/voicevox_core_python_api/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "voicevox_core" requires-python = ">=3.8" -dependencies = ["pydantic>=1.9.2,<2"] +dependencies = ["pydantic>=2.5.2,<3"] description = "VOICEVOX CORE の Python バインディングです。" authors = [{ name = "Hiroshiba", email = "hihokaruta@gmail.com" }] classifiers = [ @@ -37,7 +37,7 @@ authors = [] [tool.poetry.dependencies] python = ">=3.8,<3.13" -pydantic = ">=1.9.2,<2" +pydantic = ">=2.5.2,<3" [tool.poetry.group.docs.dependencies] sphinx = "6.2.1" diff --git a/crates/voicevox_core_python_api/python/voicevox_core/_models.py b/crates/voicevox_core_python_api/python/voicevox_core/_models.py index f93119b43..89c1f3d37 100644 --- a/crates/voicevox_core_python_api/python/voicevox_core/_models.py +++ b/crates/voicevox_core_python_api/python/voicevox_core/_models.py @@ -183,7 +183,7 @@ class AudioQuery: output_stereo: bool """音声データをステレオ出力するか否か。""" - kana: Optional[str] + kana: Optional[str] # FIXME: requiredになっている(他の`Optional`も同様) """ [読み取り専用] AquesTalk風記法。 @@ -246,11 +246,13 @@ class UserDictWord: 1から9までの値を指定することを推奨する。 """ - @pydantic.validator("pronunciation") + @pydantic.field_validator("pronunciation") + @classmethod def _validate_pronunciation(cls, v): _validate_pronunciation(v) return v - @pydantic.validator("surface") + @pydantic.field_validator("surface") + @classmethod def _validate_surface(cls, v): return _to_zenkaku(v) From 76f54d5bb83e329b78dc5dfb47bd3c5b920f9a96 Mon Sep 17 00:00:00 2001 From: mc_fdc Date: Tue, 28 Nov 2023 15:51:48 +0000 Subject: [PATCH 4/4] =?UTF-8?q?pathcelf=E6=9C=89=E5=8A=B9=E3=81=AB?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=81=BF=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/voicevox_core_python_api/poetry.lock | 52 +++++++++++++------ .../voicevox_core_python_api/pyproject.toml | 2 +- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/crates/voicevox_core_python_api/poetry.lock b/crates/voicevox_core_python_api/poetry.lock index 0a78abec8..5b51b9888 100644 --- a/crates/voicevox_core_python_api/poetry.lock +++ b/crates/voicevox_core_python_api/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -465,27 +465,28 @@ files = [ [[package]] name = "maturin" -version = "1.3.1" +version = "1.3.2" description = "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages" optional = false python-versions = ">=3.7" files = [ - {file = "maturin-1.3.1-py3-none-linux_armv6l.whl", hash = "sha256:925f8324d9bbe8fad90b73ebc6c7f6f594645e7f13af50bded72606b6c233208"}, - {file = "maturin-1.3.1-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:f3c2c694b76e63e78c353e4a2a74f8baff5ac6becf807f23435d28e47a567d63"}, - {file = "maturin-1.3.1-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:13188296f389d05043b8bd2265df66692490b61ba219ae7d5abc09e81e5659ce"}, - {file = "maturin-1.3.1-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:11bbf9978695ac066729af08bc24123317ca3fad51757b0fbdfe811212896714"}, - {file = "maturin-1.3.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:d566d2f424fa3f5cd6bd3033fd300b80654884abd061bd53c68f4717753e7d58"}, - {file = "maturin-1.3.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:c0e2b8171f1a70270b86ed72397ba548e3bf4d914f24cd50a228ed85a9d5e914"}, - {file = "maturin-1.3.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:804c6706588a9ca78f18f1a10adf9d24099b9cd3c2917628063ba8d4418b8a50"}, - {file = "maturin-1.3.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:c533d02563bb185125488cdcf161cc6ba2cdd4812ebff1b6504d1b29880ba1f8"}, - {file = "maturin-1.3.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:066b0c515505d4a4c526a9afc26fad4f010972d60937530dc4949dda0f49aa61"}, - {file = "maturin-1.3.1-py3-none-win32.whl", hash = "sha256:4835c332e3b632547db12e6a70abc18cb90ba9df06200dd9a7cc73424919901d"}, - {file = "maturin-1.3.1-py3-none-win_amd64.whl", hash = "sha256:871268417d6b3e2b46018c54a0522efc018bc4918b885d005df90b338e0674c7"}, - {file = "maturin-1.3.1-py3-none-win_arm64.whl", hash = "sha256:659a601c27984a50350f792447ff65ec60309423747f5304c98cb7b7fbb63d39"}, - {file = "maturin-1.3.1.tar.gz", hash = "sha256:efa194e99ae5fff185263d8244acacb12ae256ea73aba62c9446f6075ffc7ac1"}, + {file = "maturin-1.3.2-py3-none-linux_armv6l.whl", hash = "sha256:34630f6a6223e36198b6039e40724fe27f6465ea892531ac82eeff604cfcbbb0"}, + {file = "maturin-1.3.2-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:61b9dc290663040df4c837aa9e1858d485aaf90a10ec31b822f1d92a85334e2c"}, + {file = "maturin-1.3.2-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:5a133d22fa1ad4b687f6a89801cd7a9247164270c2ae639d1b7f53f0701601ab"}, + {file = "maturin-1.3.2-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:1258d380498924626cd87820ff54eeb16b662799ddda10631f54fdfbab780d6a"}, + {file = "maturin-1.3.2-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:8c90336c9bb0cb538bb035f9e5728ab59148c87bb8e76df26359560f8580fef4"}, + {file = "maturin-1.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:d4b66635e3933709a67760e886931b087089e484e441b1b6be358da474947cea"}, + {file = "maturin-1.3.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:4b9cc75d7912b1c0512d4ea9dd66b8b401cbc11c69e32a23215b10a9f2bccdf4"}, + {file = "maturin-1.3.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:b0b408fb55a7ce037562c44321ab40e2cee0f670b335de44b3b39c2334a0aea1"}, + {file = "maturin-1.3.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a469deffd61dc36ceafa0a74a437f39556c4f3c909d2eeb221b2ef2ca594469f"}, + {file = "maturin-1.3.2-py3-none-win32.whl", hash = "sha256:b67c51d5330d73da03726a4579c56404dc300603709e3f6e8945cc6e3550f885"}, + {file = "maturin-1.3.2-py3-none-win_amd64.whl", hash = "sha256:84d5587d2c0168d6cce0bcf720e62f2b7c87f2a9a9f749bcc7b86bc088a32c93"}, + {file = "maturin-1.3.2-py3-none-win_arm64.whl", hash = "sha256:ff0023a21df192a736726ad9fe55fb083f153d6287832d0add4861dfb35a8e83"}, + {file = "maturin-1.3.2.tar.gz", hash = "sha256:952d458b3dea01e9670582ac2dff3c522a34e491f08ed6376b270655a68c24af"}, ] [package.dependencies] +patchelf = {version = "*", optional = true, markers = "extra == \"patchelf\""} tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [package.extras] @@ -514,6 +515,25 @@ files = [ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] +[[package]] +name = "patchelf" +version = "0.17.2.1" +description = "A small utility to modify the dynamic linker and RPATH of ELF executables." +optional = false +python-versions = "*" +files = [ + {file = "patchelf-0.17.2.1-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:fc329da0e8f628bd836dfb8eaf523547e342351fa8f739bf2b3fe4a6db5a297c"}, + {file = "patchelf-0.17.2.1-py2.py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:ccb266a94edf016efe80151172c26cff8c2ec120a57a1665d257b0442784195d"}, + {file = "patchelf-0.17.2.1-py2.py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:f47b5bdd6885cfb20abdd14c707d26eb6f499a7f52e911865548d4aa43385502"}, + {file = "patchelf-0.17.2.1-py2.py3-none-manylinux_2_17_s390x.manylinux2014_s390x.musllinux_1_1_s390x.whl", hash = "sha256:a9e6ebb0874a11f7ed56d2380bfaa95f00612b23b15f896583da30c2059fcfa8"}, + {file = "patchelf-0.17.2.1-py2.py3-none-manylinux_2_5_i686.manylinux1_i686.musllinux_1_1_i686.whl", hash = "sha256:3c8d58f0e4c1929b1c7c45ba8da5a84a8f1aa6a82a46e1cfb2e44a4d40f350e5"}, + {file = "patchelf-0.17.2.1-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:d1a9bc0d4fd80c038523ebdc451a1cce75237cfcc52dbd1aca224578001d5927"}, + {file = "patchelf-0.17.2.1.tar.gz", hash = "sha256:a6eb0dd452ce4127d0d5e1eb26515e39186fa609364274bc1b0b77539cfa7031"}, +] + +[package.extras] +test = ["importlib-metadata", "pytest"] + [[package]] name = "pathspec" version = "0.11.2" @@ -1090,4 +1110,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.13" -content-hash = "42faee9d02ea5ad43eaef485f2127f0ffd77a5f8951ef71529eb1e85249e9c04" +content-hash = "48460c7058c12c92329d903cd128a99741195bc0688b920b3b31ed8466431622" diff --git a/crates/voicevox_core_python_api/pyproject.toml b/crates/voicevox_core_python_api/pyproject.toml index 5ad0bd6d8..ffe207845 100644 --- a/crates/voicevox_core_python_api/pyproject.toml +++ b/crates/voicevox_core_python_api/pyproject.toml @@ -45,7 +45,7 @@ pydata-sphinx-theme = "0.14.1" sphinx-autoapi = "3.0.0" [tool.poetry.group.dev.dependencies] -maturin = "1.3.1" +maturin = {extras = ["patchelf"], version = "^1.3.2"} [tool.poetry.group.test.dependencies] pytest = "7.3.1"