Skip to content

Commit

Permalink
feat!: Rust APIだけTextAnalyzerをパブリックにする
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip committed Jan 5, 2025
1 parent 6ff13e0 commit 50645d8
Show file tree
Hide file tree
Showing 25 changed files with 230 additions and 188 deletions.
2 changes: 1 addition & 1 deletion crates/voicevox_core/src/__internal/doctest_fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub async fn synthesizer_with_sample_voice_model(
#[cfg(feature = "link-onnxruntime")]
crate::nonblocking::Onnxruntime::init_once().await?,
)
.open_jtalk(crate::nonblocking::OpenJtalk::new(open_jtalk_dic_dir).await?)
.text_analyzer(crate::nonblocking::OpenJtalk::new(open_jtalk_dic_dir).await?)
.acceleration_mode(AccelerationMode::Cpu)
.build()?;

Expand Down
3 changes: 2 additions & 1 deletion crates/voicevox_core/src/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
pub use crate::{
engine::open_jtalk::blocking::OpenJtalk, infer::runtimes::onnxruntime::blocking::Onnxruntime,
synthesizer::blocking::AudioFeature, synthesizer::blocking::Synthesizer,
user_dict::dict::blocking::UserDict, voice_model::blocking::VoiceModelFile,
text_analyzer::blocking::TextAnalyzer, user_dict::dict::blocking::UserDict,
voice_model::blocking::VoiceModelFile,
};

pub mod onnxruntime {
Expand Down
5 changes: 2 additions & 3 deletions crates/voicevox_core/src/engine/full_context_label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::{
use jlabel::Label;
use smallvec::SmallVec;

// FIXME: 入力テキストをここで持って、メッセージに含む
#[derive(thiserror::Error, Debug)]
#[error("入力テキストからのフルコンテキストラベル抽出に失敗しました: {context}")]
pub(crate) struct FullContextLabelError {
Expand Down Expand Up @@ -428,7 +427,7 @@ mod tests {
let open_jtalk = crate::nonblocking::OpenJtalk::new(OPEN_JTALK_DIC_DIR)
.await
.unwrap();
assert_eq!(&open_jtalk.extract_fullcontext(text).unwrap(), labels);
assert_eq!(&open_jtalk.0.extract_fullcontext(text).unwrap(), labels);
}

#[apply(label_cases)]
Expand All @@ -451,7 +450,7 @@ mod tests {
.await
.unwrap();
assert_eq!(
&extract_full_context_label(&open_jtalk, text).unwrap(),
&extract_full_context_label(&open_jtalk.0, text).unwrap(),
accent_phrase
);
}
Expand Down
3 changes: 3 additions & 0 deletions crates/voicevox_core/src/engine/kana_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ fn text_to_accent_phrase(phrase: &str) -> KanaParseResult<AccentPhrase> {

pub(crate) fn parse_kana(text: &str) -> KanaParseResult<Vec<AccentPhrase>> {
const TERMINATOR: char = '\0';
if text.is_empty() {
return Ok(vec![]);
}
let mut parsed_result = Vec::new();
let chars_of_text = text.chars().chain([TERMINATOR]);
let mut phrase = String::new();
Expand Down
3 changes: 1 addition & 2 deletions crates/voicevox_core/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ pub(crate) mod open_jtalk;
pub(crate) use self::acoustic_feature_extractor::OjtPhoneme;
pub(crate) use self::audio_file::to_s16le_pcm;
pub use self::audio_file::wav_from_s16le;
pub(crate) use self::full_context_label::{extract_full_context_label, FullContextLabelError};
pub(crate) use self::full_context_label::extract_full_context_label;
pub(crate) use self::interpret_query::{initial_process, split_mora, DecoderFeature};
pub(crate) use self::kana_parser::{create_kana, parse_kana, KanaParseError};
pub use self::model::{AccentPhrase, AudioQuery, Mora};
pub(crate) use self::mora_list::mora2text;
pub use self::open_jtalk::FullcontextExtractor;
46 changes: 36 additions & 10 deletions crates/voicevox_core/src/engine/open_jtalk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub(crate) struct OpenjtalkFunctionError {
source: Option<Text2MecabError>,
}

pub trait FullcontextExtractor: Clone + Send + Sync + 'static {
pub(crate) trait FullcontextExtractor {
fn extract_fullcontext(&self, text: &str) -> anyhow::Result<Vec<String>>;
}

Expand All @@ -38,7 +38,10 @@ pub(crate) mod blocking {

use crate::error::ErrorRepr;

use super::{FullcontextExtractor, OpenjtalkFunctionError};
use super::{
super::{extract_full_context_label, AccentPhrase},
FullcontextExtractor, OpenjtalkFunctionError,
};

/// テキスト解析器としてのOpen JTalk。
#[derive(Clone)]
Expand Down Expand Up @@ -80,12 +83,19 @@ pub(crate) mod blocking {
}

impl FullcontextExtractor for self::OpenJtalk {
fn extract_fullcontext(&self, text: &str) -> anyhow::Result<Vec<String>> {
self.0.extract_fullcontext(text)
}
}

// TODO: このコードの移動
impl FullcontextExtractor for Inner {
fn extract_fullcontext(&self, text: &str) -> anyhow::Result<Vec<String>> {
let Resources {
mecab,
njd,
jpcommon,
} = &mut *self.0.resources.lock().unwrap();
} = &mut *self.resources.lock().unwrap();

jpcommon.refresh();
njd.refresh();
Expand Down Expand Up @@ -129,6 +139,15 @@ pub(crate) mod blocking {
}
}

impl crate::blocking::TextAnalyzer for self::OpenJtalk {
fn analyze(&self, text: &str) -> anyhow::Result<Vec<AccentPhrase>> {
if text.is_empty() {
return Ok(Vec::new());
}
Ok(extract_full_context_label(&*self.0, text)?)
}
}

pub(super) struct Inner {
resources: std::sync::Mutex<Resources>,
dict_dir: Utf8PathBuf,
Expand Down Expand Up @@ -196,7 +215,7 @@ pub(crate) mod blocking {
pub(crate) mod nonblocking {
use camino::Utf8Path;

use super::FullcontextExtractor;
use super::super::{extract_full_context_label, AccentPhrase};

/// テキスト解析器としてのOpen JTalk。
///
Expand All @@ -207,7 +226,7 @@ pub(crate) mod nonblocking {
/// [blocking]: https://docs.rs/crate/blocking
/// [`nonblocking`モジュールのドキュメント]: crate::nonblocking
#[derive(Clone)]
pub struct OpenJtalk(super::blocking::OpenJtalk);
pub struct OpenJtalk(pub(in super::super) super::blocking::OpenJtalk);

impl self::OpenJtalk {
pub async fn new(open_jtalk_dict_dir: impl AsRef<Utf8Path>) -> crate::result::Result<Self> {
Expand All @@ -231,9 +250,16 @@ pub(crate) mod nonblocking {
}
}

impl FullcontextExtractor for self::OpenJtalk {
fn extract_fullcontext(&self, text: &str) -> anyhow::Result<Vec<String>> {
self.0.extract_fullcontext(text)
impl crate::nonblocking::TextAnalyzer for self::OpenJtalk {
async fn analyze(&self, text: &str) -> anyhow::Result<Vec<AccentPhrase>> {
if text.is_empty() {
return Ok(Vec::new());
}
let inner = self.0 .0.clone();
let text = text.to_owned();
crate::task::asyncify(move || extract_full_context_label(&*inner, &text))
.await
.map_err(Into::into)
}
}
}
Expand Down Expand Up @@ -345,7 +371,7 @@ mod tests {
let open_jtalk = super::nonblocking::OpenJtalk::new(OPEN_JTALK_DIC_DIR)
.await
.unwrap();
let result = open_jtalk.extract_fullcontext(text);
let result = open_jtalk.0.extract_fullcontext(text);
assert_debug_fmt_eq!(expected, result);
}

Expand All @@ -360,7 +386,7 @@ mod tests {
.await
.unwrap();
for _ in 0..10 {
let result = open_jtalk.extract_fullcontext(text);
let result = open_jtalk.0.extract_fullcontext(text);
assert_debug_fmt_eq!(expected, result);
}
}
Expand Down
21 changes: 11 additions & 10 deletions crates/voicevox_core/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::{
devices::DeviceAvailabilities,
engine::{FullContextLabelError, KanaParseError},
user_dict::InvalidWordError,
StyleId, StyleType, VoiceModelId,
devices::DeviceAvailabilities, engine::KanaParseError, user_dict::InvalidWordError, StyleId,
StyleType, VoiceModelId,
};
//use engine::
use duplicate::duplicate_item;
Expand All @@ -19,7 +17,6 @@ pub struct Error(#[from] ErrorRepr);
#[duplicate_item(
E;
[ LoadModelError ];
[ FullContextLabelError ];
[ KanaParseError ];
[ InvalidWordError ];
)]
Expand Down Expand Up @@ -48,7 +45,7 @@ impl Error {
ErrorRepr::StyleNotFound { .. } => ErrorKind::StyleNotFound,
ErrorRepr::ModelNotFound { .. } => ErrorKind::ModelNotFound,
ErrorRepr::RunModel { .. } => ErrorKind::RunModel,
ErrorRepr::ExtractFullContextLabel(_) => ErrorKind::ExtractFullContextLabel,
ErrorRepr::AnalyzeText { .. } => ErrorKind::AnalyzeText,
ErrorRepr::ParseKana(_) => ErrorKind::ParseKana,
ErrorRepr::LoadUserDict(_) => ErrorKind::LoadUserDict,
ErrorRepr::SaveUserDict(_) => ErrorKind::SaveUserDict,
Expand Down Expand Up @@ -99,8 +96,12 @@ pub(crate) enum ErrorRepr {
#[error("推論に失敗しました")]
RunModel(#[source] anyhow::Error),

#[error(transparent)]
ExtractFullContextLabel(#[from] FullContextLabelError),
#[error("入力テキストの解析に失敗しました")]
AnalyzeText {
text: String,
#[source]
source: anyhow::Error,
},

#[error(transparent)]
ParseKana(#[from] KanaParseError),
Expand Down Expand Up @@ -150,8 +151,8 @@ pub enum ErrorKind {
ModelNotFound,
/// 推論に失敗した。
RunModel,
/// コンテキストラベル出力に失敗した
ExtractFullContextLabel,
/// 入力テキストの解析に失敗した
AnalyzeText,
/// AquesTalk風記法のテキストの解析に失敗した。
ParseKana,
/// ユーザー辞書を読み込めなかった。
Expand Down
2 changes: 1 addition & 1 deletion crates/voicevox_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ use rstest_reuse;

pub use self::{
devices::SupportedDevices,
engine::{wav_from_s16le, AccentPhrase, AudioQuery, FullcontextExtractor, Mora},
engine::{wav_from_s16le, AccentPhrase, AudioQuery, Mora},
error::{Error, ErrorKind},
metas::{
RawStyleId, RawStyleVersion, SpeakerMeta, StyleId, StyleMeta, StyleType, StyleVersion,
Expand Down
3 changes: 2 additions & 1 deletion crates/voicevox_core/src/nonblocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
pub use crate::{
engine::open_jtalk::nonblocking::OpenJtalk,
infer::runtimes::onnxruntime::nonblocking::Onnxruntime, synthesizer::nonblocking::Synthesizer,
user_dict::dict::nonblocking::UserDict, voice_model::nonblocking::VoiceModelFile,
text_analyzer::nonblocking::TextAnalyzer, user_dict::dict::nonblocking::UserDict,
voice_model::nonblocking::VoiceModelFile,
};

pub mod onnxruntime {
Expand Down
Loading

0 comments on commit 50645d8

Please sign in to comment.