Skip to content

Commit

Permalink
open_jtalk-rsを更新し、caminoを利用 (#745)
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip authored Feb 11, 2024
1 parent 0f2c3b2 commit 9d1151f
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 62 deletions.
42 changes: 16 additions & 26 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ async-std = "1.12.0"
async_zip = "0.0.11"
binstall-tar = "0.4.39"
bytes = "1.1.0"
camino = "1.1.6"
cbindgen = "0.24.3"
chrono = { version = "0.4.26", default-features = false }
clap = "4.0.10"
Expand Down Expand Up @@ -87,7 +88,7 @@ rev = "ebb9dcb9b26ee681889b52b6db3b4f642b04a250"

[workspace.dependencies.open_jtalk]
git = "https://github.com/VOICEVOX/open_jtalk-rs.git"
rev = "a16714ce16dec76fd0e3041a7acfa484921db3b5"
rev = "70c76bb54522830e92803038191bf533ba68ce85"

# FIXME: iOS対応のpull request(https://github.com/wesleywiser/process_path/pull/16)がマージされる見込みが無いため
[workspace.dependencies.process_path]
Expand Down
1 change: 1 addition & 0 deletions crates/voicevox_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ directml = ["onnxruntime/directml"]
[dependencies]
anyhow.workspace = true
async_zip = { workspace = true, features = ["full"] }
camino.workspace = true
derive-getters.workspace = true
derive-new.workspace = true
derive_more.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions crates/voicevox_core/src/__internal/doctest_fixtures.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::path::Path;
use camino::Utf8Path;

use crate::{AccelerationMode, InitializeOptions};

pub async fn synthesizer_with_sample_voice_model(
open_jtalk_dic_dir: impl AsRef<Path>,
open_jtalk_dic_dir: impl AsRef<Utf8Path>,
) -> anyhow::Result<crate::tokio::Synthesizer<crate::tokio::OpenJtalk>> {
let syntesizer = crate::tokio::Synthesizer::new(
crate::tokio::OpenJtalk::new(open_jtalk_dic_dir).await?,
Expand Down
54 changes: 27 additions & 27 deletions crates/voicevox_core/src/engine/open_jtalk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ pub trait FullcontextExtractor: Clone + Send + Sync + 'static {
pub(crate) mod blocking {
use std::{
io::Write as _,
path::Path,
sync::{Arc, Mutex},
};

use anyhow::anyhow;
use anyhow::Context as _;
use camino::{Utf8Path, Utf8PathBuf};
use open_jtalk::{mecab_dict_index, text2mecab, JpCommon, ManagedResource, Mecab, Njd};
use tempfile::NamedTempFile;

Expand All @@ -32,12 +32,8 @@ pub(crate) mod blocking {
pub struct OpenJtalk(pub(super) Arc<Inner>);

impl self::OpenJtalk {
pub fn new(open_jtalk_dict_dir: impl AsRef<Path>) -> crate::result::Result<Self> {
let dict_dir = open_jtalk_dict_dir
.as_ref()
.to_str()
.unwrap_or_else(|| todo!()) // FIXME: `camino::Utf8Path`を要求するようにする
.to_owned();
pub fn new(open_jtalk_dict_dir: impl AsRef<Utf8Path>) -> crate::result::Result<Self> {
let dict_dir = open_jtalk_dict_dir.as_ref().to_owned();

// FIXME: この`{}`はGitのdiffを抑えるためだけに存在
{
Expand All @@ -47,11 +43,12 @@ pub(crate) mod blocking {
jpcommon: ManagedResource::initialize(),
};

let result = resources.mecab.load(&*dict_dir);
if !result {
// FIXME: 「システム辞書を読もうとしたけど読めなかった」というエラーをちゃんと用意する
return Err(ErrorRepr::NotLoadedOpenjtalkDict.into());
}
// FIXME: 「システム辞書を読もうとしたけど読めなかった」というエラーをちゃんと用意する
resources
.mecab
.load(&*dict_dir)
.inspect_err(|e| tracing::error!("{e:?}"))
.map_err(|_| ErrorRepr::NotLoadedOpenjtalkDict)?;

Ok(Self(Arc::new(Inner {
resources: Mutex::new(resources),
Expand Down Expand Up @@ -124,7 +121,7 @@ pub(crate) mod blocking {

pub(super) struct Inner {
resources: std::sync::Mutex<Resources>,
dict_dir: String, // FIXME: `camino::Utf8PathBuf`にする
dict_dir: Utf8PathBuf,
}

impl Inner {
Expand All @@ -145,34 +142,37 @@ pub(crate) mod blocking {
NamedTempFile::new().map_err(|e| ErrorRepr::UseUserDict(e.into()))?;
let temp_dict_path = temp_dict.into_temp_path();

// FIXME: `.unwrap()`ではなく、エラーとして回収する
let temp_csv_path = Utf8Path::from_path(temp_csv_path.as_ref()).unwrap();
let temp_dict_path = Utf8Path::from_path(temp_dict_path.as_ref()).unwrap();

// Mecabでユーザー辞書をコンパイル
// TODO: エラー(SEGV)が出るパターンを把握し、それをRust側で防ぐ。
mecab_dict_index(&[
"mecab-dict-index",
"-d",
&self.dict_dir,
self.dict_dir.as_ref(),
"-u",
temp_dict_path.to_str().unwrap(),
temp_dict_path.as_ref(),
"-f",
"utf-8",
"-t",
"utf-8",
temp_csv_path.to_str().unwrap(),
temp_csv_path.as_ref(),
"-q",
]);

self.load_with_userdic(Some(temp_dict_path.as_ref()))
self.load_with_userdic(Some(temp_dict_path))
}
}
fn load_with_userdic(&self, dict_path: Option<&Path>) -> crate::result::Result<()> {
fn load_with_userdic(&self, dict_path: Option<&Utf8Path>) -> crate::result::Result<()> {
let Resources { mecab, .. } = &mut *self.resources.lock().unwrap();

let result = mecab.load_with_userdic(self.dict_dir.as_ref(), dict_path);

if !result {
return Err(ErrorRepr::UseUserDict(anyhow!("辞書を読み込めませんでした。")).into());
}
Ok(())
mecab
.load_with_userdic(self.dict_dir.as_ref(), dict_path)
.context("辞書を読み込めませんでした。")
.map_err(ErrorRepr::UseUserDict)
.map_err(Into::into)
}
}

Expand All @@ -188,7 +188,7 @@ pub(crate) mod blocking {
}

pub(crate) mod tokio {
use std::path::Path;
use camino::Utf8Path;

use super::FullcontextExtractor;

Expand All @@ -197,7 +197,7 @@ pub(crate) mod tokio {
pub struct OpenJtalk(super::blocking::OpenJtalk);

impl self::OpenJtalk {
pub async fn new(open_jtalk_dict_dir: impl AsRef<Path>) -> crate::result::Result<Self> {
pub async fn new(open_jtalk_dict_dir: impl AsRef<Utf8Path>) -> crate::result::Result<Self> {
let open_jtalk_dict_dir = open_jtalk_dict_dir.as_ref().to_owned();
let blocking =
crate::task::asyncify(|| super::blocking::OpenJtalk::new(open_jtalk_dict_dir))
Expand Down
1 change: 1 addition & 0 deletions crates/voicevox_core_c_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ directml = ["voicevox_core/directml"]
[dependencies]
anstream = { workspace = true, default-features = false, features = ["auto"] }
anstyle-query.workspace = true
camino.workspace = true
chrono = { workspace = true, default-features = false, features = ["clock"] }
colorchoice.workspace = true
cstr.workspace = true
Expand Down
3 changes: 2 additions & 1 deletion crates/voicevox_core_c_api/src/c_impls.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::{ffi::CString, path::Path};

use camino::Utf8Path;
use voicevox_core::{InitializeOptions, Result, VoiceModelId};

use crate::{helpers::CApiResult, OpenJtalkRc, VoicevoxSynthesizer, VoicevoxVoiceModel};

impl OpenJtalkRc {
pub(crate) fn new(open_jtalk_dic_dir: impl AsRef<Path>) -> Result<Self> {
pub(crate) fn new(open_jtalk_dic_dir: impl AsRef<Utf8Path>) -> Result<Self> {
Ok(Self {
open_jtalk: voicevox_core::blocking::OpenJtalk::new(open_jtalk_dic_dir)?,
})
Expand Down
1 change: 1 addition & 0 deletions crates/voicevox_core_python_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ crate-type = ["cdylib"]
directml = ["voicevox_core/directml"]

[dependencies]
camino.workspace = true
easy-ext.workspace = true
log.workspace = true
pyo3 = { workspace = true, features = ["abi3-py38", "extension-module"] }
Expand Down
5 changes: 4 additions & 1 deletion crates/voicevox_core_python_api/src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{error::Error as _, future::Future, iter, path::PathBuf};

use camino::Utf8PathBuf;
use easy_ext::ext;
use pyo3::{
exceptions::{PyException, PyValueError},
Expand Down Expand Up @@ -38,10 +39,12 @@ pub fn from_acceleration_mode(ob: &PyAny) -> PyResult<AccelerationMode> {
}
}

pub fn from_utf8_path(ob: &PyAny) -> PyResult<String> {
// FIXME: `VoiceModel`や`UserDict`についてはこれではなく、`PathBuf::extract`を直接使うようにする
pub fn from_utf8_path(ob: &PyAny) -> PyResult<Utf8PathBuf> {
PathBuf::extract(ob)?
.into_os_string()
.into_string()
.map(Utf8PathBuf::from)
.map_err(|s| PyValueError::new_err(format!("{s:?} cannot be encoded to UTF-8")))
}

Expand Down
10 changes: 6 additions & 4 deletions crates/voicevox_core_python_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use self::convert::{
to_py_user_dict_word, to_py_uuid, to_pydantic_dataclass, to_pydantic_voice_model_meta,
to_rust_user_dict_word, to_rust_uuid, VoicevoxCoreResultExt as _,
};
use camino::Utf8PathBuf;
use easy_ext::ext;
use log::debug;
use pyo3::{
Expand Down Expand Up @@ -115,7 +116,7 @@ impl VoiceModel {
#[staticmethod]
fn from_path(
py: Python<'_>,
#[pyo3(from_py_with = "from_utf8_path")] path: String,
#[pyo3(from_py_with = "from_utf8_path")] path: Utf8PathBuf,
) -> PyResult<&PyAny> {
pyo3_asyncio::tokio::future_into_py(py, async move {
let model = voicevox_core::tokio::VoiceModel::from_path(path).await;
Expand Down Expand Up @@ -146,7 +147,7 @@ impl OpenJtalk {
#[allow(clippy::new_ret_no_self)]
#[staticmethod]
fn new(
#[pyo3(from_py_with = "from_utf8_path")] open_jtalk_dict_dir: String,
#[pyo3(from_py_with = "from_utf8_path")] open_jtalk_dict_dir: Utf8PathBuf,
py: Python<'_>,
) -> PyResult<&PyAny> {
pyo3_asyncio::tokio::future_into_py(py, async move {
Expand Down Expand Up @@ -637,6 +638,7 @@ impl UserDict {
mod blocking {
use std::sync::Arc;

use camino::Utf8PathBuf;
use pyo3::{
pyclass, pymethods,
types::{IntoPyDict as _, PyBytes, PyDict, PyList},
Expand All @@ -661,7 +663,7 @@ mod blocking {
#[staticmethod]
fn from_path(
py: Python<'_>,
#[pyo3(from_py_with = "crate::convert::from_utf8_path")] path: String,
#[pyo3(from_py_with = "crate::convert::from_utf8_path")] path: Utf8PathBuf,
) -> PyResult<Self> {
let model = voicevox_core::blocking::VoiceModel::from_path(path).into_py_result(py)?;
Ok(Self { model })
Expand All @@ -688,7 +690,7 @@ mod blocking {
impl OpenJtalk {
#[new]
fn new(
#[pyo3(from_py_with = "super::from_utf8_path")] open_jtalk_dict_dir: String,
#[pyo3(from_py_with = "super::from_utf8_path")] open_jtalk_dict_dir: Utf8PathBuf,
py: Python<'_>,
) -> PyResult<Self> {
let open_jtalk =
Expand Down

0 comments on commit 9d1151f

Please sign in to comment.