Skip to content

Commit

Permalink
feat!: VoiceModelFile::close後もidmetasへのアクセスを保証 (#937)
Browse files Browse the repository at this point in the history
1. Rust APIでは、`VoiceModelFile::close`の返り値を`()`から
   `(VoiceModelId, Vec<SpeakerMeta>)`に
2. C APIでは、 `voicevox_voice_model_file_close`を
   `voicevox_voice_model_file_delete`に改名
3. Python APIとJava APIでは、`__(a)exit__`後も`id`と`metas`にアクセス可
   能であることをドキュメント上で約束

BREAKING-CHANGE: 上記の1.と2.。
  • Loading branch information
qryxip authored Jan 25, 2025
1 parent 0cfbf94 commit 9431e00
Show file tree
Hide file tree
Showing 13 changed files with 49 additions and 20 deletions.
12 changes: 10 additions & 2 deletions crates/voicevox_core/src/voice_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,12 @@ pub(crate) mod blocking {
Inner::open(path).block_on().map(Self)
}

/// VVMファイルを閉じる。
pub fn close(self) -> (VoiceModelId, VoiceModelMeta) {
let heads = self.0.into_heads();
(*heads.header.manifest.id(), heads.header.metas.clone())
}

pub(crate) fn inner(&self) -> &Inner<SingleTasked> {
&self.0
}
Expand Down Expand Up @@ -642,8 +648,10 @@ pub(crate) mod nonblocking {
}

/// VVMファイルを閉じる。
pub async fn close(self) {
self.0.into_heads().zip.into_inner().close().await;
pub async fn close(self) -> (VoiceModelId, VoiceModelMeta) {
let heads = self.0.into_heads();
heads.zip.into_inner().close().await;
(*heads.header.manifest.id(), heads.header.metas.clone())
}

pub(crate) fn inner(&self) -> &Inner<BlockingThreadPool> {
Expand Down
6 changes: 3 additions & 3 deletions crates/voicevox_core_c_api/include/voicevox_core.h

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

6 changes: 3 additions & 3 deletions crates/voicevox_core_c_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ pub extern "C" fn voicevox_get_version() -> *const c_char {
/// 音声モデルファイル。
///
/// VVMファイルと対応する。
/// <b>構築</b>(_construction_)は ::voicevox_voice_model_file_open で行い、<b>破棄</b>(_destruction_)は ::voicevox_voice_model_file_close で行う。
/// <b>構築</b>(_construction_)は ::voicevox_voice_model_file_open で行い、<b>破棄</b>(_destruction_)は ::voicevox_voice_model_file_delete で行う。
#[derive(Debug, Educe)]
#[educe(Default(expression = "Self { _padding: MaybeUninit::uninit() }"))]
pub struct VoicevoxVoiceModelFile {
Expand Down Expand Up @@ -497,15 +497,15 @@ pub extern "C" fn voicevox_voice_model_file_create_metas_json(

// TODO: cbindgenが`#[unsafe(no_mangle)]`に対応したら`#[no_mangle]`を置き換える
// SAFETY: voicevox_core_c_apiを構成するライブラリの中に、これと同名のシンボルは存在しない
/// ::VoicevoxVoiceModelFile を、所有しているファイルディスクリプタを閉じた上で<b>破棄</b>(_destruct_)する。
/// ::VoicevoxVoiceModelFile を、所有しているファイルディスクリプタを閉じた上で<b>破棄</b>(_destruct_)する。ファイルの削除(_delete_)<b>ではない</b>。
///
/// 破棄対象への他スレッドでのアクセスが存在する場合、それらがすべて終わるのを待ってから破棄する。
///
/// この関数の呼び出し後に破棄し終えた対象にアクセスすると、プロセスを異常終了する。
///
/// @param [in] model 破棄対象
#[no_mangle]
pub extern "C" fn voicevox_voice_model_file_close(model: *mut VoicevoxVoiceModelFile) {
pub extern "C" fn voicevox_voice_model_file_delete(model: *mut VoicevoxVoiceModelFile) {
init_logger_once();
model.drop_body();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! `voicevox_voice_model_file_close`を二度呼ぶとクラッシュすることを確認する。
//! `voicevox_voice_model_file_delete`を二度呼ぶとクラッシュすることを確認する。
use std::{mem::MaybeUninit, sync::LazyLock};

Expand Down Expand Up @@ -32,8 +32,8 @@ impl assert_cdylib::TestCase for TestCase {
model.assume_init()
};

lib.voicevox_voice_model_file_close(model);
lib.voicevox_voice_model_file_close(model);
lib.voicevox_voice_model_file_delete(model);
lib.voicevox_voice_model_file_delete(model);
unreachable!();

fn assert_ok(result_code: VoicevoxResultCode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl assert_cdylib::TestCase for TestCase {

std::assert_eq!(SNAPSHOTS.output[&self.text].wav_length, wav_length);

lib.voicevox_voice_model_file_close(model);
lib.voicevox_voice_model_file_delete(model);
lib.voicevox_open_jtalk_rc_delete(openjtalk);
lib.voicevox_synthesizer_delete(synthesizer);
lib.voicevox_wav_free(wav);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl assert_cdylib::TestCase for TestCase {

std::assert_eq!(SNAPSHOTS.output[&self.text].wav_length, wav_length);

lib.voicevox_voice_model_file_close(model);
lib.voicevox_voice_model_file_delete(model);
lib.voicevox_open_jtalk_rc_delete(openjtalk);
lib.voicevox_synthesizer_delete(synthesizer);
lib.voicevox_json_free(audio_query);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl assert_cdylib::TestCase for TestCase {
audio_query_with_dict.get("kana")
);

lib.voicevox_voice_model_file_close(model);
lib.voicevox_voice_model_file_delete(model);
lib.voicevox_open_jtalk_rc_delete(openjtalk);
lib.voicevox_synthesizer_delete(synthesizer);
lib.voicevox_user_dict_delete(dict);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@ public class VoiceModelFile implements Closeable {

private long handle;

/** ID。 */
/**
* ID。
*
* <p>{@link #close}の後でも利用可能。
*/
@Nonnull public final UUID id;

/** メタ情報。 */
/**
* メタ情報。
*
* <p>{@link #close}の後でも利用可能。
*/
@Nonnull public final SpeakerMeta[] metas;

public VoiceModelFile(String modelPath) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,20 @@ class VoiceModelFile:
...
@property
def id(self) -> VoiceModelId:
"""ID。"""
"""
ID。
:attr:`close` および :attr:`__aexit__` の後でも利用可能。
"""
...
@property
def metas(self) -> list[SpeakerMeta]:
"""
メタ情報。
この中身を書き換えても、 ``VoiceModelFile`` としての動作には影響しない。
:attr:`close` および :attr:`__aexit__` の後でも利用可能。
"""
...
async def __aenter__(self) -> "VoiceModelFile": ...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,20 @@ class VoiceModelFile:
...
@property
def id(self) -> VoiceModelId:
"""ID。"""
"""
ID。
:attr:`close` および :attr:`__exit__` の後でも利用可能。
"""
...
@property
def metas(self) -> list[SpeakerMeta]:
"""
メタ情報。
この中身を書き換えても、 ``VoiceModelFile`` としての動作には影響しない。
:attr:`close` および :attr:`__exit__` の後でも利用可能。
"""
...
def __enter__(self) -> "VoiceModelFile": ...
Expand Down
1 change: 1 addition & 0 deletions docs/guide/dev/api-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ VOICEVOX CORE の主要機能は Rust で実装されることを前提として
* [`StyleId`](https://voicevox.github.io/voicevox_core/apis/rust_api/voicevox_core/struct.StyleId.html)といった[newtype](https://rust-unofficial.github.io/patterns/patterns/behavioural/newtype.html)は、そのままnewtypeとして表現するべきです。
* 例えばPythonなら[`typing.NewType`](https://docs.python.org/ja/3/library/typing.html#newtype)で表現します。
* オプショナルな引数は、キーワード引数がある言語であればキーワード引数で、ビルダースタイルが一般的な言語であればビルダースタイルで表現すべきです。
* [`VoiceModelFile`](https://voicevox.github.io/voicevox_core/apis/rust_api/voicevox_core/nonblocking/struct.VoiceModelFile.html)の"close"後でも`id``metas`は利用可能であるべきです。ただしRustにおける"close"だけは、`VoiceModelFile``id``metas`に分解するような形にします。
* `Synthesizer::render``range: std::ops::Range<usize>`を引数に取っています。`Range<usize>`にあたる型が標準で存在し、かつそれが配列の範囲指定として用いられるようなものであれば、それを使うべきです。
* ただし例えばPythonでは、`slice`を引数に取るのは慣習にそぐわないため`start: int, stop: int`のようにすべきです。
* もし`Range<usize>`にあたる型が標準で無く、かつRustの"start"/"end"やPythonの"start"/"stop"にあたる明確な言葉が無いのであれば、誤解が生じないよう"end_exclusive"のように命名するべきです。
2 changes: 1 addition & 1 deletion example/cpp/unix/simple_tts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
std::cerr << voicevox_error_result_to_message(result) << std::endl;
return 0;
}
voicevox_voice_model_file_close(model);
voicevox_voice_model_file_delete(model);
}

std::cout << "音声生成中..." << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion example/cpp/windows/simple_tts/simple_tts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ int main() {
OutErrorMessage(result);
return 0;
}
voicevox_voice_model_file_close(model);
voicevox_voice_model_file_delete(model);
}

std::wcout << L"音声生成中" << std::endl;
Expand Down

0 comments on commit 9431e00

Please sign in to comment.