diff --git a/crates/voicevox_core/src/devices.rs b/crates/voicevox_core/src/devices.rs index d3141664c..b8ba51bf2 100644 --- a/crates/voicevox_core/src/devices.rs +++ b/crates/voicevox_core/src/devices.rs @@ -2,15 +2,45 @@ use serde::{Deserialize, Serialize}; use super::*; +/// このライブラリで利用可能なデバイスの情報。 +/// +/// あくまで本ライブラリが対応しているデバイスの情報であることに注意。GPUが使える環境ではなかったと +/// しても`cuda`や`dml`は`true`を示しうる。 #[derive(Getters, Debug, Serialize, Deserialize)] pub struct SupportedDevices { + /// CPUが利用可能。 + /// + /// 常に`true`。 cpu: bool, + /// CUDAが利用可能。 + /// + /// ONNX Runtimeの[CUDA Execution Provider] (`CUDAExecutionProvider`)に対応する。必要な環境につ + /// いてはそちらを参照。 + /// + /// [CUDA Execution Provider]: https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html cuda: bool, + /// DirectMLが利用可能。 + /// + /// ONNX Runtimeの[DirectML Execution Provider] (`DmlExecutionProvider`)に対応する。必要な環境に + /// ついてはそちらを参照。 + /// + /// [DirectML Execution Provider]: https://onnxruntime.ai/docs/execution-providers/DirectML-ExecutionProvider.html dml: bool, } impl SupportedDevices { - /// サポートされているデバイス情報を取得する + /// `SupportedDevices`をコンストラクトする。 + /// + /// # Example + /// + #[cfg_attr(windows, doc = "```no_run")] // https://github.com/VOICEVOX/voicevox_core/issues/537 + #[cfg_attr(not(windows), doc = "```")] + /// use voicevox_core::SupportedDevices; + /// + /// let supported_devices = SupportedDevices::create()?; + /// # + /// # Result::<_, anyhow::Error>::Ok(()) + /// ``` pub fn create() -> Result { let mut cuda_support = false; let mut dml_support = false; diff --git a/crates/voicevox_core/src/engine/model.rs b/crates/voicevox_core/src/engine/model.rs index ed55f3367..d403d60ec 100644 --- a/crates/voicevox_core/src/engine/model.rs +++ b/crates/voicevox_core/src/engine/model.rs @@ -4,21 +4,33 @@ use serde::{Deserialize, Serialize}; /* 各フィールドのjsonフィールド名はsnake_caseとする*/ +/// モーラ(子音+母音)ごとの情報。 #[derive(Clone, Debug, new, Getters, Deserialize, Serialize)] pub struct MoraModel { + /// 文字。 text: String, + /// 子音の音素。 consonant: Option, + /// 子音の音長。 consonant_length: Option, + /// 母音の音素。 vowel: String, + /// 母音の音長。 vowel_length: f32, + /// 音高。 pitch: f32, } +/// AccentPhrase (アクセント句ごとの情報)。 #[derive(Clone, Debug, new, Getters, Deserialize, Serialize)] pub struct AccentPhraseModel { + /// モーラの配列。 moras: Vec, + /// アクセント箇所。 accent: usize, + /// 後ろに無音を付けるかどうか。 pause_mora: Option, + /// 疑問系かどうか。 #[serde(default)] is_interrogative: bool, } @@ -33,18 +45,34 @@ impl AccentPhraseModel { } } +/// AudioQuery (音声合成用のクエリ)。 #[allow(clippy::too_many_arguments)] #[derive(Clone, new, Getters, Deserialize, Serialize)] pub struct AudioQueryModel { + /// アクセント句の配列。 accent_phrases: Vec, + /// 全体の話速。 speed_scale: f32, + /// 全体の音高。 pitch_scale: f32, + /// 全体の抑揚。 intonation_scale: f32, + /// 全体の音量。 volume_scale: f32, + /// 音声の前の無音時間。 pre_phoneme_length: f32, + /// 音声の後の無音時間。 post_phoneme_length: f32, + /// 音声データの出力サンプリングレート。 output_sampling_rate: u32, + /// 音声データをステレオ出力するか否か。 output_stereo: bool, + /// \[読み取り専用\] AquesTalk風記法。 + /// + /// [`Synthesizer::audio_query`]が返すもののみ`Some`となる。入力としてのAudioQueryでは無視され + /// る。 + /// + /// [`Synthesizer::audio_query`]: crate::Synthesizer::audio_query kana: Option, } diff --git a/crates/voicevox_core/src/engine/open_jtalk.rs b/crates/voicevox_core/src/engine/open_jtalk.rs index 79bfcc3de..4f8d6df00 100644 --- a/crates/voicevox_core/src/engine/open_jtalk.rs +++ b/crates/voicevox_core/src/engine/open_jtalk.rs @@ -23,6 +23,7 @@ pub enum OpenJtalkError { pub type Result = std::result::Result; +/// テキスト解析器としてのOpen JTalk。 pub struct OpenJtalk { resources: Mutex, dict_dir: Option, @@ -57,9 +58,10 @@ impl OpenJtalk { Ok(s) } + // 先に`load`を呼ぶ必要がある。 /// ユーザー辞書を設定する。 - /// 先に [`Self::load`] を呼ぶ必要がある。 - /// この関数を読んだ後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。 + /// + /// この関数を呼び出した後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。 pub fn use_user_dict(&self, user_dict: &UserDict) -> crate::result::Result<()> { let dict_dir = self .dict_dir diff --git a/crates/voicevox_core/src/error.rs b/crates/voicevox_core/src/error.rs index 9068d92e2..e37558d03 100644 --- a/crates/voicevox_core/src/error.rs +++ b/crates/voicevox_core/src/error.rs @@ -6,11 +6,7 @@ use std::path::PathBuf; use thiserror::Error; use uuid::Uuid; -/* - * 新しいエラーを定義したら、必ずresult_code.rsにあるVoicevoxResultCodeに対応するコードを定義し、 - * internal.rsにある変換関数に変換処理を加えること - */ - +/// VOICEVOX COREのエラー。 #[derive(Error, Debug)] pub enum Error { /* diff --git a/crates/voicevox_core/src/lib.rs b/crates/voicevox_core/src/lib.rs index 0175ca2a2..93553d376 100644 --- a/crates/voicevox_core/src/lib.rs +++ b/crates/voicevox_core/src/lib.rs @@ -1,3 +1,5 @@ +//! 無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのコア。 + #![deny(unsafe_code)] mod devices; diff --git a/crates/voicevox_core/src/metas.rs b/crates/voicevox_core/src/metas.rs index 7e157bd21..e39bca9c8 100644 --- a/crates/voicevox_core/src/metas.rs +++ b/crates/voicevox_core/src/metas.rs @@ -4,9 +4,17 @@ use super::*; use derive_getters::Getters; use serde::{Deserialize, Serialize}; -/// スタイルIdの実体 +/// [`StyleId`]の実体。 +/// +/// [`StyleId`]: StyleId pub type RawStyleId = u32; -/// スタイルId + +/// スタイルID。 +/// +/// VOICEVOXにおける、ある[**話者**(_speaker_)]のある[**スタイル**(_style_)]を指す。 +/// +/// [**話者**(_speaker_)]: SpeakerMeta +/// [**スタイル**(_style_)]: StyleMeta #[derive(PartialEq, Eq, Clone, Copy, Ord, PartialOrd, Deserialize, Serialize, new, Debug)] pub struct StyleId(RawStyleId); @@ -22,8 +30,12 @@ impl Display for StyleId { } } +/// [`StyleVersion`]の実体。 +/// +/// [`StyleVersion`]: StyleVersion pub type RawStyleVersion = String; +/// スタイルのバージョン。 #[derive(PartialEq, Eq, Clone, Ord, PartialOrd, Deserialize, Serialize, new, Debug)] pub struct StyleVersion(RawStyleVersion); @@ -39,21 +51,27 @@ impl Display for StyleVersion { } } -/// 音声モデルのメタ情報 +/// 音声モデルのメタ情報。 pub type VoiceModelMeta = Vec; -/// スピーカーのメタ情報 +/// **話者**(_speaker_)のメタ情報。 #[derive(Deserialize, Serialize, Getters, Clone)] pub struct SpeakerMeta { + /// 話者名。 name: String, + /// 話者に属するスタイル。 styles: Vec, + /// 話者のバージョン。 version: StyleVersion, + /// 話者のUUID。 speaker_uuid: String, } -/// スタイルのメタ情報 +/// **スタイル**(_style_)のメタ情報。 #[derive(Deserialize, Serialize, Getters, Clone)] pub struct StyleMeta { + /// スタイルID。 id: StyleId, + /// スタイル名。 name: String, } diff --git a/crates/voicevox_core/src/result_code.rs b/crates/voicevox_core/src/result_code.rs index 011df479d..faaaf8df2 100644 --- a/crates/voicevox_core/src/result_code.rs +++ b/crates/voicevox_core/src/result_code.rs @@ -1,6 +1,6 @@ use strum::EnumIter; -/// 処理結果を示す結果コード +/// 処理結果を示す結果コード。 #[repr(i32)] #[derive(Debug, PartialEq, Eq, Clone, Copy, EnumIter)] #[allow(non_camel_case_types)] @@ -29,7 +29,7 @@ pub enum VoicevoxResultCode { VOICEVOX_RESULT_EXTRACT_FULL_CONTEXT_LABEL_ERROR = 11, /// 無効なutf8文字列が入力された VOICEVOX_RESULT_INVALID_UTF8_INPUT_ERROR = 12, - /// aquestalk形式のテキストの解析に失敗した + /// AquesTalk風記法のテキストの解析に失敗した VOICEVOX_RESULT_PARSE_KANA_ERROR = 13, /// 無効なAudioQuery VOICEVOX_RESULT_INVALID_AUDIO_QUERY_ERROR = 14, @@ -81,7 +81,7 @@ pub const fn error_result_to_message(result_code: VoicevoxResultCode) -> &'stati } VOICEVOX_RESULT_INVALID_UTF8_INPUT_ERROR => "入力テキストが無効なUTF-8データでした\0", VOICEVOX_RESULT_PARSE_KANA_ERROR => { - "入力テキストをAquesTalkライクな読み仮名としてパースすることに失敗しました\0" + "入力テキストをAquesTalk風記法としてパースすることに失敗しました\0" } VOICEVOX_RESULT_INVALID_AUDIO_QUERY_ERROR => "無効なaudio_queryです\0", VOICEVOX_RESULT_INVALID_ACCENT_PHRASE_ERROR => "無効なaccent_phraseです\0", diff --git a/crates/voicevox_core/src/user_dict/dict.rs b/crates/voicevox_core/src/user_dict/dict.rs index 380a8ac24..c923db44f 100644 --- a/crates/voicevox_core/src/user_dict/dict.rs +++ b/crates/voicevox_core/src/user_dict/dict.rs @@ -22,6 +22,8 @@ impl UserDict { /// ユーザー辞書をファイルから読み込む。 /// + /// # Errors + /// /// ファイルが読めなかった、または内容が不正だった場合はエラーを返す。 pub fn load(&mut self, store_path: &str) -> Result<()> { let store_path = std::path::Path::new(store_path); diff --git a/crates/voicevox_core/src/user_dict/part_of_speech_data.rs b/crates/voicevox_core/src/user_dict/part_of_speech_data.rs index 712cef885..76e36e389 100644 --- a/crates/voicevox_core/src/user_dict/part_of_speech_data.rs +++ b/crates/voicevox_core/src/user_dict/part_of_speech_data.rs @@ -4,29 +4,29 @@ use std::collections::HashMap; use crate::UserDictWordType; -/// 最小の優先度 +/// 最小の優先度。 pub static MIN_PRIORITY: u32 = 0; -/// 最大の優先度 +/// 最大の優先度。 pub static MAX_PRIORITY: u32 = 10; -/// 品詞ごとの情報 +/// 品詞ごとの情報。 #[derive(Debug, Getters)] pub struct PartOfSpeechDetail { - /// 品詞 + /// 品詞。 pub part_of_speech: &'static str, - /// 品詞細分類1 + /// 品詞細分類1。 pub part_of_speech_detail_1: &'static str, - /// 品詞細分類2 + /// 品詞細分類2。 pub part_of_speech_detail_2: &'static str, - /// 品詞細分類3 + /// 品詞細分類3。 pub part_of_speech_detail_3: &'static str, - /// 文脈IDは辞書の左・右文脈IDのこと + /// 文脈IDは辞書の左・右文脈IDのこと。 /// /// 参考: pub context_id: i32, - /// コストのパーセンタイル + /// コストのパーセンタイル。 pub cost_candidates: Vec, - /// アクセント結合規則の一覧 + /// アクセント結合規則の一覧。 pub accent_associative_rules: Vec<&'static str>, } diff --git a/crates/voicevox_core/src/voice_model.rs b/crates/voicevox_core/src/voice_model.rs index dc2c02d32..fc20c652e 100644 --- a/crates/voicevox_core/src/voice_model.rs +++ b/crates/voicevox_core/src/voice_model.rs @@ -9,20 +9,26 @@ use std::{ path::{Path, PathBuf}, }; -/// 音声モデルIdの実体 +/// [`VoiceModelId`]の実体。 +/// +/// [`VoiceModelId`]: VoiceModelId pub type RawVoiceModelId = String; -/// 音声モデルId (型を強く分けるためにこうしている) +/// 音声モデルID。 #[derive(PartialEq, Eq, Clone, Ord, PartialOrd, Deserialize, new, Getters, Debug)] pub struct VoiceModelId { raw_voice_model_id: RawVoiceModelId, } -/// 音声モデル +/// 音声モデル。 +/// +/// VVMファイルと対応する。 #[derive(Getters, Clone)] pub struct VoiceModel { + /// ID。 id: VoiceModelId, manifest: Manifest, + /// メタ情報。 metas: VoiceModelMeta, path: PathBuf, } @@ -51,7 +57,7 @@ impl VoiceModel { decode_model: decode_model_result?, }) } - /// 与えられたパスからモデルを取得する + /// VVMファイルから`VoiceModel`をコンストラクトする。 pub async fn from_path(path: impl AsRef) -> Result { let reader = VvmEntryReader::open(&path).await?; let manifest = reader.read_vvm_json::("manifest.json").await?; diff --git a/crates/voicevox_core/src/voice_synthesizer.rs b/crates/voicevox_core/src/voice_synthesizer.rs index 86b91ce83..5c975c0a6 100644 --- a/crates/voicevox_core/src/voice_synthesizer.rs +++ b/crates/voicevox_core/src/voice_synthesizer.rs @@ -7,6 +7,9 @@ use crate::engine::{create_kana, parse_kana, AccentPhraseModel, OpenJtalk, Synth use super::*; +/// [`Synthesizer::synthesis`]のオプション。 +/// +/// [`Synthesizer::synthesis`]: Synthesizer::synthesis pub struct SynthesisOptions { pub enable_interrogative_upspeak: bool, } @@ -25,13 +28,21 @@ impl From<&TtsOptions> for SynthesisOptions { } } +/// [`Synthesizer::create_accent_phrases`]のオプション。 +/// +/// [`Synthesizer::create_accent_phrases`]: Synthesizer::create_accent_phrases #[derive(ConstDefault)] pub struct AccentPhrasesOptions { + /// AquesTalk風記法としてテキストを解釈する。 pub kana: bool, } +/// [`Synthesizer::audio_query`]のオプション。 +/// +/// [`Synthesizer::audio_query`]: Synthesizer::audio_query #[derive(ConstDefault)] pub struct AudioQueryOptions { + /// AquesTalk風記法としてテキストを解釈する。 pub kana: bool, } @@ -41,7 +52,11 @@ impl From<&TtsOptions> for AudioQueryOptions { } } +/// [`Synthesizer::tts`]のオプション。 +/// +/// [`Synthesizer::tts`]: Synthesizer::tts pub struct TtsOptions { + /// AquesTalk風記法としてテキストを解釈する。 pub kana: bool, pub enable_interrogative_upspeak: bool, } @@ -59,10 +74,14 @@ impl ConstDefault for TtsOptions { }; } +/// ハードウェアアクセラレーションモードを設定する設定値。 #[derive(Debug, PartialEq, Eq)] pub enum AccelerationMode { + /// 実行環境に合った適切なハードウェアアクセラレーションモードを選択する。 Auto, + /// ハードウェアアクセラレーションモードを"CPU"に設定する。 Cpu, + /// ハードウェアアクセラレーションモードを"GPU"に設定する。 Gpu, } @@ -70,6 +89,9 @@ impl ConstDefault for AccelerationMode { const DEFAULT: Self = Self::Auto; } +/// [`Synthesizer::new_with_initialize`]のオプション。 +/// +/// [`Synthesizer::new_with_initialize`]: Synthesizer::new_with_initialize #[derive(ConstDefault)] pub struct InitializeOptions { pub acceleration_mode: AccelerationMode, @@ -91,14 +113,41 @@ impl Default for T { } } -/// 音声シンセサイザ +/// 音声シンセサイザ。 pub struct Synthesizer { synthesis_engine: SynthesisEngine, use_gpu: bool, } impl Synthesizer { - /// コンストラクタ兼初期化 + /// `Synthesizer`をコンストラクトする。 + /// + /// # Example + /// + #[cfg_attr(windows, doc = "```no_run")] // https://github.com/VOICEVOX/voicevox_core/issues/537 + #[cfg_attr(not(windows), doc = "```")] + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # use test_util::OPEN_JTALK_DIC_DIR; + /// # + /// # const ACCELERATION_MODE: AccelerationMode = AccelerationMode::Cpu; + /// # + /// use std::sync::Arc; + /// + /// use voicevox_core::{AccelerationMode, InitializeOptions, OpenJtalk, Synthesizer}; + /// + /// let mut syntesizer = Synthesizer::new_with_initialize( + /// Arc::new(OpenJtalk::new_with_initialize(OPEN_JTALK_DIC_DIR).unwrap()), + /// &InitializeOptions { + /// acceleration_mode: ACCELERATION_MODE, + /// ..Default::default() + /// }, + /// ) + /// .await?; + /// # + /// # Ok(()) + /// # } + /// ``` pub async fn new_with_initialize( open_jtalk: Arc, options: &InitializeOptions, @@ -136,11 +185,12 @@ impl Synthesizer { }) } + /// ハードウェアアクセラレーションがGPUモードか判定する。 pub fn is_gpu_mode(&self) -> bool { self.use_gpu } - /// 音声モデルを読み込む + /// 音声モデルを読み込む。 pub async fn load_voice_model(&mut self, model: &VoiceModel) -> Result<()> { self.synthesis_engine .inference_core_mut() @@ -149,14 +199,14 @@ impl Synthesizer { Ok(()) } - /// 指定したモデルIdの音声モデルを開放する + /// 音声モデルの読み込みを解除する。 pub fn unload_voice_model(&mut self, voice_model_id: &VoiceModelId) -> Result<()> { self.synthesis_engine .inference_core_mut() .unload_model(voice_model_id) } - /// 指定したモデルIdの音声モデルが読み込まれているか判定する + /// 指定したIDの音声モデルが読み込まれているか判定する。 pub fn is_loaded_voice_model(&self, voice_model_id: &VoiceModelId) -> bool { self.synthesis_engine .inference_core() @@ -170,12 +220,12 @@ impl Synthesizer { .is_model_loaded_by_style_id(style_id) } - /// 今読み込んでいる音声モデルのメタ情報を返す + /// 今読み込んでいる音声モデルのメタ情報を返す。 pub fn metas(&self) -> &VoiceModelMeta { self.synthesis_engine.inference_core().metas() } - /// 音声合成を行う + /// AudioQueryから音声合成を行う。 pub async fn synthesis( &self, audio_query: &AudioQueryModel, @@ -241,6 +291,104 @@ impl Synthesizer { .await } + /// AccentPhrase (アクセント句)の配列を生成する。 + /// + /// `text`は[`options.kana`]が有効化されているときにはAquesTalk風記法として、そうでないときには + /// 日本語のテキストとして解釈される。 + /// + /// # Examples + /// + #[cfg_attr(windows, doc = "```no_run")] // https://github.com/VOICEVOX/voicevox_core/issues/537 + #[cfg_attr(not(windows), doc = "```")] + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let syntesizer = { + /// # use std::sync::Arc; + /// # + /// # use test_util::OPEN_JTALK_DIC_DIR; + /// # use voicevox_core::{ + /// # AccelerationMode, InitializeOptions, OpenJtalk, Synthesizer, VoiceModel, + /// # }; + /// # + /// # let mut syntesizer = Synthesizer::new_with_initialize( + /// # Arc::new(OpenJtalk::new_with_initialize(OPEN_JTALK_DIC_DIR).unwrap()), + /// # &InitializeOptions { + /// # acceleration_mode: AccelerationMode::Cpu, + /// # ..Default::default() + /// # }, + /// # ) + /// # .await?; + /// # + /// # let model = &VoiceModel::from_path(concat!( + /// # env!("CARGO_MANIFEST_DIR"), + /// # "/../../model/sample.vvm", + /// # )) + /// # .await?; + /// # syntesizer.load_voice_model(model).await?; + /// # + /// # syntesizer + /// # }; + /// # + /// use voicevox_core::StyleId; + /// + /// let accent_phrases = syntesizer + /// .create_accent_phrases( + /// "こんにちは", // 日本語のテキスト + /// StyleId::new(2), // "四国めたん (ノーマル)", + /// &Default::default(), + /// ) + /// .await?; + /// # + /// # Ok(()) + /// # } + /// ``` + /// + #[cfg_attr(windows, doc = "```no_run")] // https://github.com/VOICEVOX/voicevox_core/issues/537 + #[cfg_attr(not(windows), doc = "```")] + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let syntesizer = { + /// # use std::sync::Arc; + /// # + /// # use test_util::OPEN_JTALK_DIC_DIR; + /// # use voicevox_core::{ + /// # AccelerationMode, InitializeOptions, OpenJtalk, Synthesizer, VoiceModel, + /// # }; + /// # + /// # let mut syntesizer = Synthesizer::new_with_initialize( + /// # Arc::new(OpenJtalk::new_with_initialize(OPEN_JTALK_DIC_DIR).unwrap()), + /// # &InitializeOptions { + /// # acceleration_mode: AccelerationMode::Cpu, + /// # ..Default::default() + /// # }, + /// # ) + /// # .await?; + /// # + /// # let model = &VoiceModel::from_path(concat!( + /// # env!("CARGO_MANIFEST_DIR"), + /// # "/../../model/sample.vvm", + /// # )) + /// # .await?; + /// # syntesizer.load_voice_model(model).await?; + /// # + /// # syntesizer + /// # }; + /// # + /// use voicevox_core::{AccentPhrasesOptions, StyleId}; + /// + /// let accent_phrases = syntesizer + /// .create_accent_phrases( + /// "コンニチワ'", // AquesTalk風記法 + /// StyleId::new(2), // "四国めたん (ノーマル)", + /// &AccentPhrasesOptions { kana: true }, + /// ) + /// .await?; + /// # + /// # Ok(()) + /// # } + /// ``` + /// + /// [`options.kana`]: crate::AccentPhrasesOptions::kana pub async fn create_accent_phrases( &self, text: &str, @@ -261,6 +409,7 @@ impl Synthesizer { } } + /// AccentPhraseの配列の音高・音素長を、特定の声で生成しなおす。 pub async fn replace_mora_data( &self, accent_phrases: &[AccentPhraseModel], @@ -271,6 +420,7 @@ impl Synthesizer { .await } + /// AccentPhraseの配列の音素長を、特定の声で生成しなおす。 pub async fn replace_phoneme_length( &self, accent_phrases: &[AccentPhraseModel], @@ -281,6 +431,7 @@ impl Synthesizer { .await } + /// AccentPhraseの配列の音高を、特定の声で生成しなおす。 pub async fn replace_mora_pitch( &self, accent_phrases: &[AccentPhraseModel], @@ -291,6 +442,105 @@ impl Synthesizer { .await } + /// [AudioQuery]を生成する。 + /// + /// `text`は[`options.kana`]が有効化されているときにはAquesTalk風記法として、そうでないときには + /// 日本語のテキストとして解釈される。 + /// + /// # Examples + /// + #[cfg_attr(windows, doc = "```no_run")] // https://github.com/VOICEVOX/voicevox_core/issues/537 + #[cfg_attr(not(windows), doc = "```")] + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let syntesizer = { + /// # use std::sync::Arc; + /// # + /// # use test_util::OPEN_JTALK_DIC_DIR; + /// # use voicevox_core::{ + /// # AccelerationMode, InitializeOptions, OpenJtalk, Synthesizer, VoiceModel, + /// # }; + /// # + /// # let mut syntesizer = Synthesizer::new_with_initialize( + /// # Arc::new(OpenJtalk::new_with_initialize(OPEN_JTALK_DIC_DIR).unwrap()), + /// # &InitializeOptions { + /// # acceleration_mode: AccelerationMode::Cpu, + /// # ..Default::default() + /// # }, + /// # ) + /// # .await?; + /// # + /// # let model = &VoiceModel::from_path(concat!( + /// # env!("CARGO_MANIFEST_DIR"), + /// # "/../../model/sample.vvm", + /// # )) + /// # .await?; + /// # syntesizer.load_voice_model(model).await?; + /// # + /// # syntesizer + /// # }; + /// # + /// use voicevox_core::StyleId; + /// + /// let audio_query = syntesizer + /// .audio_query( + /// "こんにちは", // 日本語のテキスト + /// StyleId::new(2), // "四国めたん (ノーマル)", + /// &Default::default(), + /// ) + /// .await?; + /// # + /// # Ok(()) + /// # } + /// ``` + /// + #[cfg_attr(windows, doc = "```no_run")] // https://github.com/VOICEVOX/voicevox_core/issues/537 + #[cfg_attr(not(windows), doc = "```")] + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let syntesizer = { + /// # use std::sync::Arc; + /// # + /// # use test_util::OPEN_JTALK_DIC_DIR; + /// # use voicevox_core::{ + /// # AccelerationMode, InitializeOptions, OpenJtalk, Synthesizer, VoiceModel, + /// # }; + /// # + /// # let mut syntesizer = Synthesizer::new_with_initialize( + /// # Arc::new(OpenJtalk::new_with_initialize(OPEN_JTALK_DIC_DIR).unwrap()), + /// # &InitializeOptions { + /// # acceleration_mode: AccelerationMode::Cpu, + /// # ..Default::default() + /// # }, + /// # ) + /// # .await?; + /// # + /// # let model = &VoiceModel::from_path(concat!( + /// # env!("CARGO_MANIFEST_DIR"), + /// # "/../../model/sample.vvm", + /// # )) + /// # .await?; + /// # syntesizer.load_voice_model(model).await?; + /// # + /// # syntesizer + /// # }; + /// # + /// use voicevox_core::{AudioQueryOptions, StyleId}; + /// + /// let audio_query = syntesizer + /// .audio_query( + /// "コンニチワ'", // AquesTalk風記法 + /// StyleId::new(2), // "四国めたん (ノーマル)", + /// &AudioQueryOptions { kana: true }, + /// ) + /// .await?; + /// # + /// # Ok(()) + /// # } + /// ``` + /// + /// [AudioQuery]: crate::AudioQueryModel + /// [`options.kana`]: crate::AudioQueryOptions::kana pub async fn audio_query( &self, text: &str, @@ -315,6 +565,12 @@ impl Synthesizer { )) } + /// テキスト音声合成を行う。 + /// + /// `text`は[`options.kana`]が有効化されているときにはAquesTalk風記法として、そうでないときには + /// 日本語のテキストとして解釈される。 + /// + /// [`options.kana`]: crate::TtsOptions::kana pub async fn tts( &self, text: &str, diff --git a/crates/voicevox_core_c_api/cbindgen.toml b/crates/voicevox_core_c_api/cbindgen.toml index d038d038d..7615280f6 100644 --- a/crates/voicevox_core_c_api/cbindgen.toml +++ b/crates/voicevox_core_c_api/cbindgen.toml @@ -2,7 +2,49 @@ language = "C" # Options for wrapping the contents of the header: -header = "/// @file" +header = """ +/** + * @file voicevox_core.h + * + * 無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのコア。 + * + *
+ *
+ * ⚠️ Safety + *
+ * + *
+ * このライブラリの利用にあたっては、いくつかの不変条件が守られている必要がある。本ドキュメントではこの不変条件を安全性要件(_safety + * requirements_)と呼び、"Safety"というセクションの下に安全性要件を示す。 + * + * 安全性要件の違反は[Rust言語における未定義動作(_undefined behavior_; 通称UB)]( + * https://doc.rust-lang.org/reference/behavior-considered-undefined.html)を引き起こす。Rustの未定義動作は、Cのそれや[C++のそれ]( + * https://cpprefjp.github.io/implementation-compliance.html#nasal-demon)や[Zigのそれ]( + * https://ziglang.org/documentation/0.10.1/#Undefined-Behavior)などとおおよそ同じであり、引き起こしてはならないものとされる。プログラム全体のどこかに未定義動作が含まれるなら、一般的に、処理系はそれについて何をしてもよい。[変数は同時にtrueでもfalseでもあってもよいし]( + * https://markshroyer.com/2012/06/c-both-true-and-false/)、あなたの鼻から悪魔が飛び出してもよい。このことは通称鼻から悪魔(_nasal + * demons_)と呼ばれる。 + * + * 未定義動作はプログラム全体に影響する。運が良ければセグメンテーション違反などで異常終了するだけだが、ライブラリを呼び出している部分から離れた所で「鼻から悪魔」が起こることもある。そうなったら挙動の予測もデバッグも困難である。これが未定義動作が禁忌とされる所以である。 + * + * `voicevox_core`全体における安全性要件は以下の通りである。 + * + * - 「読み込みについて有効」と説明されているポインタは次の条件を満たしていなければならない。 + * - 間接参照可能(_dereferenceable_)である。 + * - 参照先のメモリは他スレッドから書き込み中ではない。 + * - 「書き込みについて有効」と説明されているポインタは次の条件を満たしていなければならない。 + * - 参照先のメモリは有効である (ただしメモリアラインメントに沿っている必要は無い)。 + * - 参照先のメモリは他スレッドからアクセス中ではない。 + * - このライブラリで生成したオブジェクトの解放は、このライブラリが提供するAPIで行わなくてはならない(freeHeapFreeで行ってはならない)。 + * + * 次のことに注意すること。 + * + * - 次のポインタは読み込みにおいても書き込みにおいても有効ではない。 + * - ヌルポインタ。 + * - 解放されたポインタ。 + * - voicevox_coreをアンロードする場合、voicevox_coreが生成したポインタが有効であり続けることは保証されない。 + *
+ *
+ */""" include_guard = "VOICEVOX_CORE_INCLUDE_GUARD" no_includes = true include_version = true diff --git a/crates/voicevox_core_c_api/include/voicevox_core.h b/crates/voicevox_core_c_api/include/voicevox_core.h index ecb358846..d5564616c 100644 --- a/crates/voicevox_core_c_api/include/voicevox_core.h +++ b/crates/voicevox_core_c_api/include/voicevox_core.h @@ -1,4 +1,45 @@ -/// @file +/** + * @file voicevox_core.h + * + * 無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのコア。 + * + *
+ *
+ * ⚠️ Safety + *
+ * + *
+ * このライブラリの利用にあたっては、いくつかの不変条件が守られている必要がある。本ドキュメントではこの不変条件を安全性要件(_safety + * requirements_)と呼び、"Safety"というセクションの下に安全性要件を示す。 + * + * 安全性要件の違反は[Rust言語における未定義動作(_undefined behavior_; 通称UB)]( + * https://doc.rust-lang.org/reference/behavior-considered-undefined.html)を引き起こす。Rustの未定義動作は、Cのそれや[C++のそれ]( + * https://cpprefjp.github.io/implementation-compliance.html#nasal-demon)や[Zigのそれ]( + * https://ziglang.org/documentation/0.10.1/#Undefined-Behavior)などとおおよそ同じであり、引き起こしてはならないものとされる。プログラム全体のどこかに未定義動作が含まれるなら、一般的に、処理系はそれについて何をしてもよい。[変数は同時にtrueでもfalseでもあってもよいし]( + * https://markshroyer.com/2012/06/c-both-true-and-false/)、あなたの鼻から悪魔が飛び出してもよい。このことは通称鼻から悪魔(_nasal + * demons_)と呼ばれる。 + * + * 未定義動作はプログラム全体に影響する。運が良ければセグメンテーション違反などで異常終了するだけだが、ライブラリを呼び出している部分から離れた所で「鼻から悪魔」が起こることもある。そうなったら挙動の予測もデバッグも困難である。これが未定義動作が禁忌とされる所以である。 + * + * `voicevox_core`全体における安全性要件は以下の通りである。 + * + * - 「読み込みについて有効」と説明されているポインタは次の条件を満たしていなければならない。 + * - 間接参照可能(_dereferenceable_)である。 + * - 参照先のメモリは他スレッドから書き込み中ではない。 + * - 「書き込みについて有効」と説明されているポインタは次の条件を満たしていなければならない。 + * - 参照先のメモリは有効である (ただしメモリアラインメントに沿っている必要は無い)。 + * - 参照先のメモリは他スレッドからアクセス中ではない。 + * - このライブラリで生成したオブジェクトの解放は、このライブラリが提供するAPIで行わなくてはならない(freeHeapFreeで行ってはならない)。 + * + * 次のことに注意すること。 + * + * - 次のポインタは読み込みにおいても書き込みにおいても有効ではない。 + * - ヌルポインタ。 + * - 解放されたポインタ。 + * - voicevox_coreをアンロードする場合、voicevox_coreが生成したポインタが有効であり続けることは保証されない。 + *
+ *
+ */ #ifndef VOICEVOX_CORE_INCLUDE_GUARD #define VOICEVOX_CORE_INCLUDE_GUARD @@ -13,7 +54,7 @@ #endif // __cplusplus /** - * ハードウェアアクセラレーションモードを設定する設定値 + * ハードウェアアクセラレーションモードを設定する設定値。 */ enum VoicevoxAccelerationMode #ifdef __cplusplus @@ -38,7 +79,7 @@ typedef int32_t VoicevoxAccelerationMode; #endif // __cplusplus /** - * 処理結果を示す結果コード + * 処理結果を示す結果コード。 */ enum VoicevoxResultCode #ifdef __cplusplus @@ -90,7 +131,7 @@ enum VoicevoxResultCode */ VOICEVOX_RESULT_INVALID_UTF8_INPUT_ERROR = 12, /** - * aquestalk形式のテキストの解析に失敗した + * AquesTalk風記法のテキストの解析に失敗した */ VOICEVOX_RESULT_PARSE_KANA_ERROR = 13, /** @@ -147,7 +188,7 @@ typedef int32_t VoicevoxResultCode; #endif // __cplusplus /** - * ユーザー辞書の単語の種類 + * ユーザー辞書の単語の種類。 */ enum VoicevoxUserDictWordType #ifdef __cplusplus @@ -180,29 +221,51 @@ typedef int32_t VoicevoxUserDictWordType; #endif // __cplusplus /** - * 参照カウントで管理されたOpenJtalk + * テキスト解析器としてのOpen JTalk。 + * + * 構築(_construction_)は ::voicevox_open_jtalk_rc_new で行い、破棄(_destruction_)は ::voicevox_open_jtalk_rc_delete で行う。 + * + * 参照カウント方式のスマートポインタ(reference-counted smart pointer)であり、 + * ::voicevox_synthesizer_new_with_initialize に渡されるときには参照カウンタがインクリメントされる形でオブジェクトの共有が行われる。 + * + * \example{ + * ```c + * OpenJtalkRc *open_jtalk; + * voicevox_open_jtalk_rc_new("./open_jtalk_dic_utf_8-1.11", &open_jtalk); + * // ⋮ + * voicevox_open_jtalk_rc_delete(open_jtalk); + * ``` + * } */ typedef struct OpenJtalkRc OpenJtalkRc; +/** + * 音声シンセサイザ。 + * + * 構築(_construction_)は ::voicevox_synthesizer_new_with_initialize で行い、破棄(_destruction_)は ::voicevox_synthesizer_delete で行う。 + */ typedef struct VoicevoxSynthesizer VoicevoxSynthesizer; /** - * ユーザー辞書 + * ユーザー辞書。 */ typedef struct VoicevoxUserDict VoicevoxUserDict; /** - * 音声モデル + * 音声モデル。 + * + * VVMファイルと対応する。 + * 構築(_construction_)は ::voicevox_voice_model_new_from_path で行い、破棄(_destruction_)は ::voicevox_voice_model_delete で行う。 */ typedef struct VoicevoxVoiceModel VoicevoxVoiceModel; /** - * 音声モデルID + * 音声モデルID。 */ typedef const char *VoicevoxVoiceModelId; /** - * 初期化オプション + * ::voicevox_synthesizer_new_with_initialize のオプション。 */ typedef struct VoicevoxInitializeOptions { /** @@ -221,32 +284,34 @@ typedef struct VoicevoxInitializeOptions { } VoicevoxInitializeOptions; /** - * スタイルID + * スタイルID。 + * + * VOICEVOXにおける、ある話者(_speaker_)のあるスタイル(_style_)を指す。 */ typedef uint32_t VoicevoxStyleId; /** - * Audio query のオプション + * ::voicevox_synthesizer_audio_query のオプション。 */ typedef struct VoicevoxAudioQueryOptions { /** - * aquestalk形式のkanaとしてテキストを解釈する + * AquesTalk風記法としてテキストを解釈する */ bool kana; } VoicevoxAudioQueryOptions; /** - * `accent_phrases` のオプション + * ::voicevox_synthesizer_create_accent_phrases のオプション。 */ typedef struct VoicevoxAccentPhrasesOptions { /** - * aquestalk形式のkanaとしてテキストを解釈する + * AquesTalk風記法としてテキストを解釈する */ bool kana; } VoicevoxAccentPhrasesOptions; /** - * `voicevox_synthesizer_synthesis` のオプション + * ::voicevox_synthesizer_synthesis のオプション。 */ typedef struct VoicevoxSynthesisOptions { /** @@ -256,11 +321,11 @@ typedef struct VoicevoxSynthesisOptions { } VoicevoxSynthesisOptions; /** - * テキスト音声合成オプション + * ::voicevox_synthesizer_tts のオプション。 */ typedef struct VoicevoxTtsOptions { /** - * aquestalk形式のkanaとしてテキストを解釈する + * AquesTalk風記法としてテキストを解釈する */ bool kana; /** @@ -270,7 +335,7 @@ typedef struct VoicevoxTtsOptions { } VoicevoxTtsOptions; /** - * ユーザー辞書の単語 + * ユーザー辞書の単語。 */ typedef struct VoicevoxUserDictWord { /** @@ -312,10 +377,26 @@ extern const struct VoicevoxSynthesisOptions voicevox_default_synthesis_options; extern const struct VoicevoxTtsOptions voicevox_default_tts_options; /** - * 参照カウントで管理されたOpenJtalkを生成する + * ::OpenJtalkRc を構築(_construct_)する。 * - * # Safety - * @out_open_jtalk 自動でheap領域が割り当てられるため :voicevox_open_jtalk_rc_delete で解放する必要がある + * 解放は ::voicevox_open_jtalk_rc_delete で行う。 + * + * @param [in] open_jtalk_dic_dir 辞書ディレクトリを指すUTF-8のパス + * @param [out] out_open_jtalk 構築先 + * + * @returns 結果コード + * + * \example{ + * ```c + * OpenJtalkRc *open_jtalk; + * voicevox_open_jtalk_rc_new("./open_jtalk_dic_utf_8-1.11", &open_jtalk); + * ``` + * } + * + * \safety{ + * - `open_jtalk_dic_dir`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `out_open_jtalk`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -324,14 +405,17 @@ VoicevoxResultCode voicevox_open_jtalk_rc_new(const char *open_jtalk_dic_dir, struct OpenJtalkRc **out_open_jtalk); /** - * OpenJtalkの使うユーザー辞書を設定する + * OpenJtalkの使うユーザー辞書を設定する。 + * * この関数を呼び出した後にユーザー辞書を変更した場合、再度この関数を呼び出す必要がある。 - * @param [in] open_jtalk 参照カウントで管理されたOpenJtalk + * + * @param [in] open_jtalk Open JTalkのオブジェクト * @param [in] user_dict ユーザー辞書 * - * # Safety - * @open_jtalk 有効な :OpenJtalkRc のポインタであること - * @user_dict 有効な :VoicevoxUserDict のポインタであること + * \safety{ + * - `open_jtalk`は ::voicevox_open_jtalk_rc_new で得たものでなければならず、また ::voicevox_open_jtalk_rc_delete で解放されていてはいけない。 + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -340,11 +424,20 @@ VoicevoxResultCode voicevox_open_jtalk_rc_use_user_dict(const struct OpenJtalkRc const struct VoicevoxUserDict *user_dict); /** - * 参照カウントで管理されたOpenJtalkを削除する - * @param [in] open_jtalk 参照カウントで管理されたOpenJtalk + * ::OpenJtalkRc を破棄(_destruct_)する。 * - * # Safety - * @open_jtalk 有効な :OpenJtalkRc のポインタであること + * @param [in] open_jtalk 破棄対象 + * + * \example{ + * ```c + * voicevox_open_jtalk_rc_delete(open_jtalk); + * ``` + * } + * + * \safety{ + * - `open_jtalk`は ::voicevox_open_jtalk_rc_new で得たものでなければならず、また既にこの関数で解放されていてはいけない。 + * - `open_jtalk`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -352,14 +445,17 @@ __declspec(dllimport) void voicevox_open_jtalk_rc_delete(struct OpenJtalkRc *open_jtalk); /** - * vvmファイルパスから音声モデルを生成する - * @param [in] path vvmファイルパス - * @param [out] out_model 新しく生成された音声モデルの出力先 - * @return 結果コード #VoicevoxResultCode + * VVMファイルから ::VoicevoxVoiceModel を構築(_construct_)する。 * - * # Safety - * @param path null終端文字列であること - * @param out_model 自動でheapメモリが割り当てられるので ::voicevox_voice_model_delete で解放する必要がある + * @param [in] path vvmファイルへのUTF-8のファイルパス + * @param [out] out_model 構築先 + * + * @returns 結果コード + * + * \safety{ + * - `path`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `out_model`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -368,12 +464,15 @@ VoicevoxResultCode voicevox_voice_model_new_from_path(const char *path, struct VoicevoxVoiceModel **out_model); /** - * 音声モデルのIDを取得する - * @param [in] model 音声モデル #VoicevoxVoiceModel - * @return 音声モデルID #VoicevoxVoiceModelId + * ::VoicevoxVoiceModel からIDを取得する。 * - * # Safety - * @param model 有効な #VoicevoxVoiceModel へのポインタであること + * @param [in] model 音声モデル + * + * @returns 音声モデルID + * + * \safety{ + * - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_voice_model_delete で解放されていてはいけない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -381,12 +480,16 @@ __declspec(dllimport) VoicevoxVoiceModelId voicevox_voice_model_id(const struct VoicevoxVoiceModel *model); /** - * 音声モデルのメタ情報を取得する - * @param [in] model 音声モデル #VoicevoxVoiceModel - * @return メタ情報のjson文字列 + * ::VoicevoxVoiceModel からメタ情報を取得する。 * - * # Safety - * @param model 有効な #VoicevoxVoiceModel へのポインタであること + * @param [in] model 音声モデル + * + * @returns メタ情報のJSON文字列 + * + * \safety{ + * - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_voice_model_delete で解放されていてはいけない。 + * - 戻り値の文字列の生存期間(_lifetime_)は次にこの関数が呼ばれるか、`model`が破棄されるまでである。この生存期間を越えて文字列にアクセスしてはならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -394,11 +497,14 @@ __declspec(dllimport) const char *voicevox_voice_model_get_metas_json(const struct VoicevoxVoiceModel *model); /** - * 音声モデルを破棄する - * @param [in] model 破棄する音声モデル #VoicevoxVoiceModel + * ::VoicevoxVoiceModel を破棄(_destruct_)する。 * - * # Safety - * @param model 有効な #VoicevoxVoiceModel へのポインタであること + * @param [in] model 破棄対象 + * + * \safety{ + * - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また既にこの関数で解放されていてはいけない。 + * - `model`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -406,14 +512,18 @@ __declspec(dllimport) void voicevox_voice_model_delete(struct VoicevoxVoiceModel *model); /** - * 音声シンセサイザを生成して初期化する - * @param [in] open_jtalk 参照カウントで管理されたOpenJtalk - * @param [in] options 初期化オプション #VoicevoxInitializeOptions - * @param [out] out_synthesizer 新しく生成された音声シンセサイザの出力先 #VoicevoxSynthesizer - * @return 結果コード #VoicevoxResultCode + * ::VoicevoxSynthesizer を構築(_construct_)する。 * - * # Safety - * @param out_synthesizer 自動でheapメモリが割り当てられるので ::voicevox_synthesizer_delete で解放する必要がある + * @param [in] open_jtalk Open JTalkのオブジェクト + * @param [in] options オプション + * @param [out] out_synthesizer 構築先 + * + * @returns 結果コード + * + * \safety{ + * - `open_jtalk`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_open_jtalk_rc_new で解放されていてはいけない。 + * - `out_synthesizer`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -423,11 +533,14 @@ VoicevoxResultCode voicevox_synthesizer_new_with_initialize(const struct OpenJta struct VoicevoxSynthesizer **out_synthesizer); /** - * 音声シンセサイザを破棄する - * @param [in] synthesizer 破棄する音声シンセサイザ #VoicevoxSynthesizer + * ::VoicevoxSynthesizer を破棄(_destruct_)する。 * - * # Safety - * @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること + * @param [in] synthesizer 破棄対象 + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また既にこの関数で解放されていてはいけない。 + * - `synthesizer`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -435,14 +548,17 @@ __declspec(dllimport) void voicevox_synthesizer_delete(struct VoicevoxSynthesizer *synthesizer); /** - * モデルを読み込む + * 音声モデルを読み込む。 + * * @param [in] synthesizer 音声シンセサイザ * @param [in] model 音声モデル - * @return 結果コード #VoicevoxResultCode * - * # Safety - * @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること - * @param model 有効な #VoicevoxVoiceModel へのポインタであること + * @returns 結果コード + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_voice_model_delete で解放されていてはいけない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -451,14 +567,17 @@ VoicevoxResultCode voicevox_synthesizer_load_voice_model(struct VoicevoxSynthesi const struct VoicevoxVoiceModel *model); /** - * モデルの読み込みを解除する + * 音声モデルの読み込みを解除する。 + * * @param [in] synthesizer 音声シンセサイザ * @param [in] model_id 音声モデルID - * @return 結果コード #VoicevoxResultCode * - * # Safety - * @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること - * @param model_id NULL終端文字列であること + * @returns 結果コード + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `model_id`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -467,12 +586,15 @@ VoicevoxResultCode voicevox_synthesizer_unload_voice_model(struct VoicevoxSynthe VoicevoxVoiceModelId model_id); /** - * ハードウェアアクセラレーションがGPUモードか判定する + * ハードウェアアクセラレーションがGPUモードか判定する。 + * * @param [in] synthesizer 音声シンセサイザ - * @return GPUモードならtrue、そうでないならfalse * - * # Safety - * @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること + * @returns GPUモードかどうか + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -480,14 +602,17 @@ __declspec(dllimport) bool voicevox_synthesizer_is_gpu_mode(const struct VoicevoxSynthesizer *synthesizer); /** - * 指定したspeaker_idのモデルが読み込まれているか判定する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] model_id 音声モデルのID #VoicevoxVoiceModelId - * @return モデルが読み込まれているのであればtrue、そうでないならfalse + * 指定したIDの音声モデルが読み込まれているか判定する。 * - * # Safety - * @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること - * @param model_id NULL終端文字列 + * @param [in] synthesizer 音声シンセサイザ + * @param [in] model_id 音声モデルID + * + * @returns モデルが読み込まれているかどうか + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `model_id`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -496,12 +621,16 @@ bool voicevox_synthesizer_is_loaded_voice_model(const struct VoicevoxSynthesizer VoicevoxVoiceModelId model_id); /** - * メタ情報をjsonで取得する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @return メタ情報のjson文字列 + * 今読み込んでいる音声モデルのメタ情報を、JSONで取得する。 * - * # Safety - * @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること + * @param [in] synthesizer 音声シンセサイザ + * + * @return メタ情報のJSON文字列 + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - 戻り値の文字列の生存期間(_lifetime_)は次にこの関数が呼ばれるか、`synthesizer`が破棄されるまでである。この生存期間を越えて文字列にアクセスしてはならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -509,12 +638,26 @@ __declspec(dllimport) const char *voicevox_synthesizer_get_metas_json(const struct VoicevoxSynthesizer *synthesizer); /** - * サポートデバイス情報をjsonで取得する - * @param [out] output_supported_devices_json サポートデバイス情報のjson文字列 - * @return 結果コード #VoicevoxResultCode + * このライブラリで利用可能なデバイスの情報を、JSONで取得する。 * - * # Safety - * @param output_supported_devices_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある + * JSONの解放は ::voicevox_json_free で行う。 + * + * あくまで本ライブラリが対応しているデバイスの情報であることに注意。GPUが使える環境ではなかったとしても`cuda`や`dml`は`true`を示しうる。 + * + * @param [out] output_supported_devices_json サポートデバイス情報のJSON文字列 + * + * @returns 結果コード + * + * \example{ + * ```c + * char *supported_devices; + * VoicevoxResultCode result = voicevox_create_supported_devices_json(&supported_devices); + * ``` + * } + * + * \safety{ + * - `output_supported_devices_json`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -522,17 +665,44 @@ __declspec(dllimport) VoicevoxResultCode voicevox_create_supported_devices_json(char **output_supported_devices_json); /** - * AudioQuery を実行する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] text テキスト。文字コードはUTF-8 - * @param [in] style_id スタイルID #VoicevoxStyleId - * @param [in] options AudioQueryのオプション #VoicevoxAudioQueryOptions - * @param [out] output_audio_query_json AudioQuery を json でフォーマットしたもの - * @return 結果コード #VoicevoxResultCode + * AudioQueryをJSONとして生成する。 * - * # Safety - * @param text null終端文字列であること - * @param output_audio_query_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある + * 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 + * + * @param [in] synthesizer 音声シンセサイザ + * @param [in] text UTF-8の日本語テキストまたはAquesTalk風記法 + * @param [in] style_id スタイルID + * @param [in] options オプション + * @param [out] output_audio_query_json 生成先 + * + * @returns 結果コード + * + * \examples{ + * ```c + * char *audio_query; + * voicevox_synthesizer_audio_query(synthesizer, + * "こんにちは", // 日本語テキスト + * 2, // "四国めたん (ノーマル)" + * (VoicevoxAudioQueryOptions){.kana = false}, + * &audio_query); + * ``` + * + * ```c + * char *audio_query; + * voicevox_synthesizer_audio_query(synthesizer, + * "コンニチワ'", // AquesTalk風記法 + * 2, // "四国めたん (ノーマル)" + * (VoicevoxAudioQueryOptions){.kana = true}, + * &audio_query); + * ``` + * } + * + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `text`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_audio_query_json`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -544,15 +714,43 @@ VoicevoxResultCode voicevox_synthesizer_audio_query(const struct VoicevoxSynthes char **output_audio_query_json); /** - * create_accent_phrases を実行する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] text テキスト - * @param [in] style_id スタイルID #VoicevoxStyleId - * @param [in] output_accent_phrases_json アクセントフレーズのjson文字列 + * AccentPhrase (アクセント句)の配列をJSON形式で生成する。 * - * # Safety - * @param text null終端文字列であること - * @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある + * 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 + * + * @param [in] synthesizer 音声シンセサイザ + * @param [in] text UTF-8の日本語テキストまたはAquesTalk風記法 + * @param [in] style_id スタイルID + * @param [in] options オプション + * @param [out] output_accent_phrases_json 生成先 + * + * @returns 結果コード + * + * \examples{ + * ```c + * char *accent_phrases; + * voicevox_synthesizer_create_accent_phrases( + * synthesizer, + * "こんにちは", // 日本語テキスト + * 2, // "四国めたん (ノーマル)" + * voicevox_default_accent_phrases_options, &accent_phrases); + * ``` + * + * ```c + * char *accent_phrases; + * voicevox_synthesizer_create_accent_phrases( + * synthesizer, + * "コンニチワ'", // AquesTalk風記法 + * 2, // "四国めたん (ノーマル)" + * (VoicevoxAccentPhrasesOptions){.kana = true}, &accent_phrases); + * ``` + * } + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `text`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_audio_query_json`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -564,15 +762,22 @@ VoicevoxResultCode voicevox_synthesizer_create_accent_phrases(const struct Voice char **output_accent_phrases_json); /** - * replace_mora_data を実行する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] accent_phrases_json 変換前のアクセントフレーズのjson文字列 - * @param [in] style_id スタイルID #VoicevoxStyleId - * @param [in] output_accent_phrases_json 変換後のアクセントフレーズのjson文字列 + * AccentPhraseの配列の音高・音素長を、特定の声で生成しなおす。 * - * # Safety - * @param accent_phrases_json null終端文字列であること - * @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある + * 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 + * + * @param [in] synthesizer 音声シンセサイザ + * @param [in] accent_phrases_json AccentPhraseの配列のJSON文字列 + * @param [in] style_id スタイルID + * @param [out] output_accent_phrases_json 生成先 + * + * @returns 結果コード + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `accent_phrases_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_audio_query_json`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -583,15 +788,22 @@ VoicevoxResultCode voicevox_synthesizer_replace_mora_data(const struct VoicevoxS char **output_accent_phrases_json); /** - * replace_phoneme_length を実行する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] accent_phrases_json 変換前のアクセントフレーズのjson文字列 - * @param [in] style_id スタイルID #VoicevoxStyleId - * @param [in] output_accent_phrases_json 変換後のアクセントフレーズのjson文字列 + * AccentPhraseの配列の音素長を、特定の声で生成しなおす。 * - * # Safety - * @param accent_phrases_json null終端文字列であること - * @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある + * 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 + * + * @param [in] synthesizer 音声シンセサイザ + * @param [in] accent_phrases_json AccentPhraseの配列のJSON文字列 + * @param [in] style_id スタイルID + * @param [out] output_accent_phrases_json 生成先 + * + * @returns 結果コード + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `accent_phrases_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_audio_query_json`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -602,15 +814,22 @@ VoicevoxResultCode voicevox_synthesizer_replace_phoneme_length(const struct Voic char **output_accent_phrases_json); /** - * replace_mora_pitch を実行する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] accent_phrases_json 変換前のアクセントフレーズのjson文字列 - * @param [in] style_id スタイルID #VoicevoxStyleId - * @param [in] output_accent_phrases_json 変換後のアクセントフレーズのjson文字列 + * AccentPhraseの配列の音高を、特定の声で生成しなおす。 * - * # Safety - * @param accent_phrases_json null終端文字列であること - * @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある + * 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 + * + * @param [in] synthesizer 音声シンセサイザ + * @param [in] accent_phrases_json AccentPhraseの配列のJSON文字列 + * @param [in] style_id スタイルID + * @param [out] output_accent_phrases_json 生成先 + * + * @returns 結果コード + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `accent_phrases_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_audio_query_json`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -621,18 +840,25 @@ VoicevoxResultCode voicevox_synthesizer_replace_mora_pitch(const struct Voicevox char **output_accent_phrases_json); /** - * AudioQuery から音声合成する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] audio_query_json jsonフォーマットされた AudioQuery - * @param [in] style_id スタイルID #VoicevoxStyleId - * @param [in] options AudioQueryから音声合成オプション - * @param [out] output_wav_length 出力する wav データのサイズ - * @param [out] output_wav wav データの出力先 - * @return 結果コード #VoicevoxResultCode + * AudioQueryから音声合成を行う。 * - * # Safety - * @param output_wav_length 出力先の領域が確保された状態でpointerに渡されていること - * @param output_wav 自動で output_wav_length 分のデータが割り当てられるので ::voicevox_wav_free で解放する必要がある + * 生成したWAVデータを解放するには ::voicevox_wav_free を使う。 + * + * @param [in] synthesizer 音声シンセサイザ + * @param [in] audio_query_json AudioQueryのJSON文字列 + * @param [in] style_id スタイルID + * @param [in] options オプション + * @param [out] output_wav_length 出力のバイト長 + * @param [out] output_wav 出力先 + * + * @returns 結果コード + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `audio_query_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_wav_length`は書き込みについて有効でなければならない。 + * - `output_wav`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -645,18 +871,25 @@ VoicevoxResultCode voicevox_synthesizer_synthesis(const struct VoicevoxSynthesiz uint8_t **output_wav); /** - * テキスト音声合成を実行する - * @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer - * @param [in] text テキスト。文字コードはUTF-8 - * @param [in] style_id スタイルID #VoicevoxStyleId - * @param [in] options テキスト音声合成オプション - * @param [out] output_wav_length 出力する wav データのサイズ - * @param [out] output_wav wav データの出力先 - * @return 結果コード #VoicevoxResultCode + * テキスト音声合成を行う。 * - * # Safety - * @param output_wav_length 出力先の領域が確保された状態でpointerに渡されていること - * @param output_wav は自動で output_wav_length 分のデータが割り当てられるので ::voicevox_wav_free で解放する必要がある + * 生成したWAVデータを解放するには ::voicevox_wav_free を使う。 + * + * @param [in] synthesizer + * @param [in] text UTF-8の日本語テキストまたはAquesTalk風記法 + * @param [in] style_id スタイルID + * @param [in] options オプション + * @param [out] output_wav_length 出力のバイト長 + * @param [out] output_wav 出力先 + * + * @returns 結果コード + * + * \safety{ + * - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 + * - `text`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_wav_length`は書き込みについて有効でなければならない。 + * - `output_wav`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -669,11 +902,22 @@ VoicevoxResultCode voicevox_synthesizer_tts(const struct VoicevoxSynthesizer *sy uint8_t **output_wav); /** - * jsonフォーマットされたデータのメモリを解放する - * @param [in] json 解放する json データ + * JSON文字列を解放する。 * - * # Safety - * @param voicevox_audio_query で確保されたポインタであり、かつ呼び出し側でバッファの変更を行われていないこと + * @param [in] json 解放するJSON文字列 + * + * \safety{ + * - `json`は以下のAPIで得られたポインタでなくてはいけない。 + * - ::voicevox_create_supported_devices_json + * - ::voicevox_synthesizer_audio_query + * - ::voicevox_synthesizer_create_accent_phrases + * - ::voicevox_synthesizer_replace_mora_data + * - ::voicevox_synthesizer_replace_phoneme_length + * - ::voicevox_synthesizer_replace_mora_pitch + * - 文字列の長さは生成時より変更されていてはならない。 + * - `json`は読み込みと書き込みについて有効でなければならない。 + * - `json`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -681,11 +925,17 @@ __declspec(dllimport) void voicevox_json_free(char *json); /** - * wav データのメモリを解放する - * @param [in] wav 解放する wav データ + * WAVデータを解放する。 * - * # Safety - * @param wav voicevox_tts,voicevox_synthesis で確保されたポインタであり、かつ呼び出し側でバッファの変更を行われていないこと + * @param [in] wav 解放するWAVデータ + * + * \safety{ + * - `wav`は以下のAPIで得られたポインタでなくてはいけない。 + * - ::voicevox_synthesizer_synthesis + * - ::voicevox_synthesizer_tts + * - `wav`は読み込みと書き込みについて有効でなければならない。 + * - `wav`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -693,9 +943,26 @@ __declspec(dllimport) void voicevox_wav_free(uint8_t *wav); /** - * エラー結果をメッセージに変換する - * @param [in] result_code メッセージに変換する result_code - * @return 結果コードを元に変換されたメッセージ文字列 + * 結果コードに対応したメッセージ文字列を取得する。 + * + * @param [in] result_code 結果コード + * + * @returns 結果コードに対応したメッセージ文字列 + * + * \examples{ + * ```c + * const char *actual = voicevox_error_result_to_message(VOICEVOX_RESULT_OK); + * const char *EXPECTED = "エラーが発生しませんでした"; + * assert(strcmp(actual, EXPECTED) == 0); + * ``` + * + * ```c + * const char *actual = + * voicevox_error_result_to_message(VOICEVOX_RESULT_LOAD_MODEL_ERROR); + * const char *EXPECTED = "modelデータ読み込みに失敗しました"; + * assert(strcmp(actual, EXPECTED) == 0); + * ``` + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -703,13 +970,11 @@ __declspec(dllimport) const char *voicevox_error_result_to_message(VoicevoxResultCode result_code); /** - * VoicevoxUserDictWordを最低限のパラメータで作成する。 + * ::VoicevoxUserDictWord を最低限のパラメータで作成する。 + * * @param [in] surface 表記 * @param [in] pronunciation 読み - * @return VoicevoxUserDictWord - * - * # Safety - * @param surface, pronunciation は有効な文字列へのポインタであること + * @returns ::VoicevoxUserDictWord */ #ifdef _WIN32 __declspec(dllimport) @@ -718,11 +983,9 @@ struct VoicevoxUserDictWord voicevox_user_dict_word_make(const char *surface, const char *pronunciation); /** - * ユーザー辞書を作成する - * @return VoicevoxUserDict + * ユーザー辞書をb>構築(_construct_)する。 * - * # Safety - * @return 自動で解放されることはないので、呼び出し側で :voicevox_user_dict_delete で解放する必要がある + * @returns ::VoicevoxUserDict */ #ifdef _WIN32 __declspec(dllimport) @@ -730,14 +993,16 @@ __declspec(dllimport) struct VoicevoxUserDict *voicevox_user_dict_new(void); /** - * ユーザー辞書にファイルを読み込ませる - * @param [in] user_dict VoicevoxUserDictのポインタ + * ユーザー辞書にファイルを読み込ませる。 + * + * @param [in] user_dict ユーザー辞書 * @param [in] dict_path 読み込む辞書ファイルのパス - * @return 結果コード #VoicevoxResultCode + * @returns 結果コード * - * # Safety - * @param user_dict は有効な :VoicevoxUserDict のポインタであること - * @param dict_path パスが有効な文字列を指していること + * \safety{ + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * - `dict_path`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -746,15 +1011,21 @@ VoicevoxResultCode voicevox_user_dict_load(const struct VoicevoxUserDict *user_d const char *dict_path); /** - * ユーザー辞書に単語を追加する - * @param [in] user_dict VoicevoxUserDictのポインタ + * ユーザー辞書に単語を追加する。 + * + * @param [in] ユーザー辞書 * @param [in] word 追加する単語 * @param [out] output_word_uuid 追加した単語のUUID - * @return 結果コード #VoicevoxResultCode + * @returns 結果コード * * # Safety * @param user_dict は有効な :VoicevoxUserDict のポインタであること * + * \safety{ + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * - `word->surface`と`word->pronunciation`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * - `output_word_uuid`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -764,14 +1035,18 @@ VoicevoxResultCode voicevox_user_dict_add_word(const struct VoicevoxUserDict *us uint8_t (*output_word_uuid)[16]); /** - * ユーザー辞書の単語を更新する - * @param [in] user_dict VoicevoxUserDictのポインタ + * ユーザー辞書の単語を更新する。 + * + * @param [in] user_dict ユーザー辞書 * @param [in] word_uuid 更新する単語のUUID * @param [in] word 新しい単語のデータ - * @return 結果コード #VoicevoxResultCode + * @returns 結果コード * - * # Safety - * @param user_dict は有効な :VoicevoxUserDict のポインタであること + * \safety{ + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * - `word_uuid`は読み込みについて有効でなければならない。 + * - `word->surface`と`word->pronunciation`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -781,10 +1056,16 @@ VoicevoxResultCode voicevox_user_dict_update_word(const struct VoicevoxUserDict const struct VoicevoxUserDictWord *word); /** - * ユーザー辞書から単語を削除する - * @param [in] user_dict VoicevoxUserDictのポインタ + * ユーザー辞書から単語を削除する。 + * + * @param [in] user_dict ユーザー辞書 * @param [in] word_uuid 削除する単語のUUID - * @return 結果コード #VoicevoxResultCode + * @returns 結果コード + * + * \safety{ + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * - `word_uuid`は読み込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -793,14 +1074,16 @@ VoicevoxResultCode voicevox_user_dict_remove_word(const struct VoicevoxUserDict const uint8_t (*word_uuid)[16]); /** - * ユーザー辞書の単語をJSON形式で出力する - * @param [in] user_dict VoicevoxUserDictのポインタ - * @param [out] output_json JSON形式の文字列 - * @return 結果コード #VoicevoxResultCode + * ユーザー辞書の単語をJSON形式で出力する。 * - * # Safety - * @param user_dict は有効な :VoicevoxUserDict のポインタであること - * @param output_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある + * @param [in] user_dict ユーザー辞書 + * @param [out] output_json 出力先 + * @returns 結果コード + * + * \safety{ + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * - `output_json`は書き込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -809,10 +1092,15 @@ VoicevoxResultCode voicevox_user_dict_to_json(const struct VoicevoxUserDict *use char **output_json); /** - * 他のユーザー辞書をインポートする - * @param [in] user_dict VoicevoxUserDictのポインタ + * 他のユーザー辞書をインポートする。 + * + * @param [in] user_dict ユーザー辞書 * @param [in] other_dict インポートするユーザー辞書 - * @return 結果コード #VoicevoxResultCode + * @returns 結果コード + * + * \safety{ + * - `user_dict`と`other_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -821,13 +1109,15 @@ VoicevoxResultCode voicevox_user_dict_import(const struct VoicevoxUserDict *user const struct VoicevoxUserDict *other_dict); /** - * ユーザー辞書をファイルに保存する - * @param [in] user_dict VoicevoxUserDictのポインタ + * ユーザー辞書をファイルに保存する。 + * + * @param [in] user_dict ユーザー辞書 * @param [in] path 保存先のファイルパス * - * # Safety - * @param user_dict は有効な :VoicevoxUserDict のポインタであること - * @param path は有効なUTF-8文字列であること + * \safety{ + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 + * - `path`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 + * } */ #ifdef _WIN32 __declspec(dllimport) @@ -836,11 +1126,13 @@ VoicevoxResultCode voicevox_user_dict_save(const struct VoicevoxUserDict *user_d const char *path); /** - * ユーザー辞書を廃棄する。 - * @param [in] user_dict VoicevoxUserDictのポインタ + * ユーザー辞書を破棄(_destruct_)する。 * - * # Safety - * @param user_dict は有効な :VoicevoxUserDict のポインタであること + * @param [in] user_dict 破棄対象 + * + * \safety{ + * - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また既にこの関数で解放されていてはいけない。 + * } */ #ifdef _WIN32 __declspec(dllimport) diff --git a/crates/voicevox_core_c_api/src/lib.rs b/crates/voicevox_core_c_api/src/lib.rs index ef141b4ae..827654da5 100644 --- a/crates/voicevox_core_c_api/src/lib.rs +++ b/crates/voicevox_core_c_api/src/lib.rs @@ -1,3 +1,7 @@ +// ここにあるRustdocはcbindgen向けのものである。safety documentation自体は書くが、Doxygenの慣習に従 +// い`
`で書く。 +#![allow(clippy::missing_safety_doc)] + mod c_impls; /// cbindgen:ignore mod compatible_engine; @@ -77,15 +81,45 @@ static RUNTIME: Lazy = Lazy::new(|| { * voicevox_core/publish.rsにある対応する関数とはこのファイルに定義してある公開関数からvoicevoxプレフィックスを取り除いた名前の関数である */ -/// 参照カウントで管理されたOpenJtalk +/// テキスト解析器としてのOpen JTalk。 +/// +/// 構築(_construction_)は ::voicevox_open_jtalk_rc_new で行い、破棄(_destruction_)は ::voicevox_open_jtalk_rc_delete で行う。 +/// +/// 参照カウント方式のスマートポインタ(reference-counted smart pointer)であり、 +/// ::voicevox_synthesizer_new_with_initialize に渡されるときには参照カウンタがインクリメントされる形でオブジェクトの共有が行われる。 +/// +/// \example{ +/// ```c +/// OpenJtalkRc *open_jtalk; +/// voicevox_open_jtalk_rc_new("./open_jtalk_dic_utf_8-1.11", &open_jtalk); +/// // ⋮ +/// voicevox_open_jtalk_rc_delete(open_jtalk); +/// ``` +/// } pub struct OpenJtalkRc { open_jtalk: Arc, } -/// 参照カウントで管理されたOpenJtalkを生成する +/// ::OpenJtalkRc を構築(_construct_)する。 /// -/// # Safety -/// @out_open_jtalk 自動でheap領域が割り当てられるため :voicevox_open_jtalk_rc_delete で解放する必要がある +/// 解放は ::voicevox_open_jtalk_rc_delete で行う。 +/// +/// @param [in] open_jtalk_dic_dir 辞書ディレクトリを指すUTF-8のパス +/// @param [out] out_open_jtalk 構築先 +/// +/// @returns 結果コード +/// +/// \example{ +/// ```c +/// OpenJtalkRc *open_jtalk; +/// voicevox_open_jtalk_rc_new("./open_jtalk_dic_utf_8-1.11", &open_jtalk); +/// ``` +/// } +/// +/// \safety{ +/// - `open_jtalk_dic_dir`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `out_open_jtalk`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_open_jtalk_rc_new( open_jtalk_dic_dir: *const c_char, @@ -99,14 +133,17 @@ pub unsafe extern "C" fn voicevox_open_jtalk_rc_new( })()) } -/// OpenJtalkの使うユーザー辞書を設定する +/// OpenJtalkの使うユーザー辞書を設定する。 +/// /// この関数を呼び出した後にユーザー辞書を変更した場合、再度この関数を呼び出す必要がある。 -/// @param [in] open_jtalk 参照カウントで管理されたOpenJtalk +/// +/// @param [in] open_jtalk Open JTalkのオブジェクト /// @param [in] user_dict ユーザー辞書 /// -/// # Safety -/// @open_jtalk 有効な :OpenJtalkRc のポインタであること -/// @user_dict 有効な :VoicevoxUserDict のポインタであること +/// \safety{ +/// - `open_jtalk`は ::voicevox_open_jtalk_rc_new で得たものでなければならず、また ::voicevox_open_jtalk_rc_delete で解放されていてはいけない。 +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// } #[no_mangle] pub extern "C" fn voicevox_open_jtalk_rc_use_user_dict( open_jtalk: &OpenJtalkRc, @@ -122,11 +159,20 @@ pub extern "C" fn voicevox_open_jtalk_rc_use_user_dict( })()) } -/// 参照カウントで管理されたOpenJtalkを削除する -/// @param [in] open_jtalk 参照カウントで管理されたOpenJtalk +/// ::OpenJtalkRc を破棄(_destruct_)する。 /// -/// # Safety -/// @open_jtalk 有効な :OpenJtalkRc のポインタであること +/// @param [in] open_jtalk 破棄対象 +/// +/// \example{ +/// ```c +/// voicevox_open_jtalk_rc_delete(open_jtalk); +/// ``` +/// } +/// +/// \safety{ +/// - `open_jtalk`は ::voicevox_open_jtalk_rc_new で得たものでなければならず、また既にこの関数で解放されていてはいけない。 +/// - `open_jtalk`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 +/// } #[no_mangle] pub extern "C" fn voicevox_open_jtalk_rc_delete(open_jtalk: Box) { drop(open_jtalk); @@ -134,7 +180,7 @@ pub extern "C" fn voicevox_open_jtalk_rc_delete(open_jtalk: Box) { pub use voicevox_core::result_code::VoicevoxResultCode; -/// ハードウェアアクセラレーションモードを設定する設定値 +/// ハードウェアアクセラレーションモードを設定する設定値。 #[repr(i32)] #[derive(Debug, PartialEq, Eq)] #[allow(non_camel_case_types)] @@ -147,7 +193,7 @@ pub enum VoicevoxAccelerationMode { VOICEVOX_ACCELERATION_MODE_GPU = 2, } -/// 初期化オプション +/// ::voicevox_synthesizer_new_with_initialize のオプション。 #[repr(C)] pub struct VoicevoxInitializeOptions { /// ハードウェアアクセラレーションモード @@ -163,7 +209,7 @@ pub struct VoicevoxInitializeOptions { #[no_mangle] pub static voicevox_default_initialize_options: VoicevoxInitializeOptions = ConstDefault::DEFAULT; -/// voicevoxのバージョン +/// voicevoxのバージョン。 #[no_mangle] pub static voicevox_version: &c_char = { const VOICEVOX_VERSION: &CStr = unsafe { @@ -175,7 +221,10 @@ pub static voicevox_version: &c_char = { unsafe { &*VOICEVOX_VERSION.as_ptr() } }; -/// 音声モデル +/// 音声モデル。 +/// +/// VVMファイルと対応する。 +/// 構築(_construction_)は ::voicevox_voice_model_new_from_path で行い、破棄(_destruction_)は ::voicevox_voice_model_delete で行う。 #[derive(Getters)] pub struct VoicevoxVoiceModel { model: VoiceModel, @@ -183,20 +232,25 @@ pub struct VoicevoxVoiceModel { metas: CString, } -/// 音声モデルID +/// 音声モデルID。 pub type VoicevoxVoiceModelId = *const c_char; -/// スタイルID +/// スタイルID。 +/// +/// VOICEVOXにおける、ある話者(_speaker_)のあるスタイル(_style_)を指す。 pub type VoicevoxStyleId = u32; -/// vvmファイルパスから音声モデルを生成する -/// @param [in] path vvmファイルパス -/// @param [out] out_model 新しく生成された音声モデルの出力先 -/// @return 結果コード #VoicevoxResultCode +/// VVMファイルから ::VoicevoxVoiceModel を構築(_construct_)する。 /// -/// # Safety -/// @param path null終端文字列であること -/// @param out_model 自動でheapメモリが割り当てられるので ::voicevox_voice_model_delete で解放する必要がある +/// @param [in] path vvmファイルへのUTF-8のファイルパス +/// @param [out] out_model 構築先 +/// +/// @returns 結果コード +/// +/// \safety{ +/// - `path`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `out_model`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_voice_model_new_from_path( path: *const c_char, @@ -212,52 +266,69 @@ pub unsafe extern "C" fn voicevox_voice_model_new_from_path( })()) } -/// 音声モデルのIDを取得する -/// @param [in] model 音声モデル #VoicevoxVoiceModel -/// @return 音声モデルID #VoicevoxVoiceModelId +/// ::VoicevoxVoiceModel からIDを取得する。 /// -/// # Safety -/// @param model 有効な #VoicevoxVoiceModel へのポインタであること +/// @param [in] model 音声モデル +/// +/// @returns 音声モデルID +/// +/// \safety{ +/// - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_voice_model_delete で解放されていてはいけない。 +/// } #[no_mangle] pub extern "C" fn voicevox_voice_model_id(model: &VoicevoxVoiceModel) -> VoicevoxVoiceModelId { model.id().as_ptr() } -/// 音声モデルのメタ情報を取得する -/// @param [in] model 音声モデル #VoicevoxVoiceModel -/// @return メタ情報のjson文字列 +/// ::VoicevoxVoiceModel からメタ情報を取得する。 /// -/// # Safety -/// @param model 有効な #VoicevoxVoiceModel へのポインタであること +/// @param [in] model 音声モデル +/// +/// @returns メタ情報のJSON文字列 +/// +/// \safety{ +/// - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_voice_model_delete で解放されていてはいけない。 +/// - 戻り値の文字列の生存期間(_lifetime_)は次にこの関数が呼ばれるか、`model`が破棄されるまでである。この生存期間を越えて文字列にアクセスしてはならない。 +/// } #[no_mangle] pub extern "C" fn voicevox_voice_model_get_metas_json(model: &VoicevoxVoiceModel) -> *const c_char { model.metas().as_ptr() } -/// 音声モデルを破棄する -/// @param [in] model 破棄する音声モデル #VoicevoxVoiceModel +/// ::VoicevoxVoiceModel を破棄(_destruct_)する。 /// -/// # Safety -/// @param model 有効な #VoicevoxVoiceModel へのポインタであること +/// @param [in] model 破棄対象 +/// +/// \safety{ +/// - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また既にこの関数で解放されていてはいけない。 +/// - `model`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 +/// } #[no_mangle] pub extern "C" fn voicevox_voice_model_delete(model: Box) { drop(model); } +/// 音声シンセサイザ。 +/// +/// 構築(_construction_)は ::voicevox_synthesizer_new_with_initialize で行い、破棄(_destruction_)は ::voicevox_synthesizer_delete で行う。 #[derive(Getters)] pub struct VoicevoxSynthesizer { synthesizer: Synthesizer, metas_cstring: CString, } -/// 音声シンセサイザを生成して初期化する -/// @param [in] open_jtalk 参照カウントで管理されたOpenJtalk -/// @param [in] options 初期化オプション #VoicevoxInitializeOptions -/// @param [out] out_synthesizer 新しく生成された音声シンセサイザの出力先 #VoicevoxSynthesizer -/// @return 結果コード #VoicevoxResultCode +/// ::VoicevoxSynthesizer を構築(_construct_)する。 /// -/// # Safety -/// @param out_synthesizer 自動でheapメモリが割り当てられるので ::voicevox_synthesizer_delete で解放する必要がある +/// @param [in] open_jtalk Open JTalkのオブジェクト +/// @param [in] options オプション +/// @param [out] out_synthesizer 構築先 +/// +/// @returns 結果コード +/// +/// \safety{ +/// - `open_jtalk`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_open_jtalk_rc_new で解放されていてはいけない。 +/// - `out_synthesizer`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_new_with_initialize( open_jtalk: &OpenJtalkRc, @@ -277,24 +348,30 @@ pub unsafe extern "C" fn voicevox_synthesizer_new_with_initialize( })()) } -/// 音声シンセサイザを破棄する -/// @param [in] synthesizer 破棄する音声シンセサイザ #VoicevoxSynthesizer +/// ::VoicevoxSynthesizer を破棄(_destruct_)する。 /// -/// # Safety -/// @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること +/// @param [in] synthesizer 破棄対象 +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また既にこの関数で解放されていてはいけない。 +/// - `synthesizer`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 +/// } #[no_mangle] pub extern "C" fn voicevox_synthesizer_delete(synthesizer: Box) { drop(synthesizer); } -/// モデルを読み込む +/// 音声モデルを読み込む。 +/// /// @param [in] synthesizer 音声シンセサイザ /// @param [in] model 音声モデル -/// @return 結果コード #VoicevoxResultCode /// -/// # Safety -/// @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること -/// @param model 有効な #VoicevoxVoiceModel へのポインタであること +/// @returns 結果コード +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `model`は ::voicevox_voice_model_new_from_path で得たものでなければならず、また ::voicevox_voice_model_delete で解放されていてはいけない。 +/// } #[no_mangle] pub extern "C" fn voicevox_synthesizer_load_voice_model( synthesizer: &mut VoicevoxSynthesizer, @@ -307,14 +384,17 @@ pub extern "C" fn voicevox_synthesizer_load_voice_model( ) } -/// モデルの読み込みを解除する +/// 音声モデルの読み込みを解除する。 +/// /// @param [in] synthesizer 音声シンセサイザ /// @param [in] model_id 音声モデルID -/// @return 結果コード #VoicevoxResultCode /// -/// # Safety -/// @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること -/// @param model_id NULL終端文字列であること +/// @returns 結果コード +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `model_id`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_unload_voice_model( synthesizer: &mut VoicevoxSynthesizer, @@ -328,25 +408,31 @@ pub unsafe extern "C" fn voicevox_synthesizer_unload_voice_model( })()) } -/// ハードウェアアクセラレーションがGPUモードか判定する +/// ハードウェアアクセラレーションがGPUモードか判定する。 +/// /// @param [in] synthesizer 音声シンセサイザ -/// @return GPUモードならtrue、そうでないならfalse /// -/// # Safety -/// @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること +/// @returns GPUモードかどうか +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// } #[no_mangle] pub extern "C" fn voicevox_synthesizer_is_gpu_mode(synthesizer: &VoicevoxSynthesizer) -> bool { synthesizer.synthesizer().is_gpu_mode() } -/// 指定したspeaker_idのモデルが読み込まれているか判定する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] model_id 音声モデルのID #VoicevoxVoiceModelId -/// @return モデルが読み込まれているのであればtrue、そうでないならfalse +/// 指定したIDの音声モデルが読み込まれているか判定する。 /// -/// # Safety -/// @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること -/// @param model_id NULL終端文字列 +/// @param [in] synthesizer 音声シンセサイザ +/// @param [in] model_id 音声モデルID +/// +/// @returns モデルが読み込まれているかどうか +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `model_id`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_is_loaded_voice_model( synthesizer: &VoicevoxSynthesizer, @@ -358,12 +444,16 @@ pub unsafe extern "C" fn voicevox_synthesizer_is_loaded_voice_model( .is_loaded_voice_model(&VoiceModelId::new(raw_model_id.into())) } -/// メタ情報をjsonで取得する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @return メタ情報のjson文字列 +/// 今読み込んでいる音声モデルのメタ情報を、JSONで取得する。 /// -/// # Safety -/// @param synthesizer 有効な #VoicevoxSynthesizer へのポインタであること +/// @param [in] synthesizer 音声シンセサイザ +/// +/// @return メタ情報のJSON文字列 +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - 戻り値の文字列の生存期間(_lifetime_)は次にこの関数が呼ばれるか、`synthesizer`が破棄されるまでである。この生存期間を越えて文字列にアクセスしてはならない。 +/// } #[no_mangle] pub extern "C" fn voicevox_synthesizer_get_metas_json( synthesizer: &VoicevoxSynthesizer, @@ -371,12 +461,26 @@ pub extern "C" fn voicevox_synthesizer_get_metas_json( synthesizer.metas().as_ptr() } -/// サポートデバイス情報をjsonで取得する -/// @param [out] output_supported_devices_json サポートデバイス情報のjson文字列 -/// @return 結果コード #VoicevoxResultCode +/// このライブラリで利用可能なデバイスの情報を、JSONで取得する。 /// -/// # Safety -/// @param output_supported_devices_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある +/// JSONの解放は ::voicevox_json_free で行う。 +/// +/// あくまで本ライブラリが対応しているデバイスの情報であることに注意。GPUが使える環境ではなかったとしても`cuda`や`dml`は`true`を示しうる。 +/// +/// @param [out] output_supported_devices_json サポートデバイス情報のJSON文字列 +/// +/// @returns 結果コード +/// +/// \example{ +/// ```c +/// char *supported_devices; +/// VoicevoxResultCode result = voicevox_create_supported_devices_json(&supported_devices); +/// ``` +/// } +/// +/// \safety{ +/// - `output_supported_devices_json`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_create_supported_devices_json( output_supported_devices_json: NonNull<*mut c_char>, @@ -393,10 +497,10 @@ pub unsafe extern "C" fn voicevox_create_supported_devices_json( })()) } -/// Audio query のオプション +/// ::voicevox_synthesizer_audio_query のオプション。 #[repr(C)] pub struct VoicevoxAudioQueryOptions { - /// aquestalk形式のkanaとしてテキストを解釈する + /// AquesTalk風記法としてテキストを解釈する kana: bool, } @@ -404,17 +508,44 @@ pub struct VoicevoxAudioQueryOptions { #[no_mangle] pub static voicevox_default_audio_query_options: VoicevoxAudioQueryOptions = ConstDefault::DEFAULT; -/// AudioQuery を実行する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] text テキスト。文字コードはUTF-8 -/// @param [in] style_id スタイルID #VoicevoxStyleId -/// @param [in] options AudioQueryのオプション #VoicevoxAudioQueryOptions -/// @param [out] output_audio_query_json AudioQuery を json でフォーマットしたもの -/// @return 結果コード #VoicevoxResultCode +/// AudioQueryをJSONとして生成する。 /// -/// # Safety -/// @param text null終端文字列であること -/// @param output_audio_query_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある +/// 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 +/// +/// @param [in] synthesizer 音声シンセサイザ +/// @param [in] text UTF-8の日本語テキストまたはAquesTalk風記法 +/// @param [in] style_id スタイルID +/// @param [in] options オプション +/// @param [out] output_audio_query_json 生成先 +/// +/// @returns 結果コード +/// +/// \examples{ +/// ```c +/// char *audio_query; +/// voicevox_synthesizer_audio_query(synthesizer, +/// "こんにちは", // 日本語テキスト +/// 2, // "四国めたん (ノーマル)" +/// (VoicevoxAudioQueryOptions){.kana = false}, +/// &audio_query); +/// ``` +/// +/// ```c +/// char *audio_query; +/// voicevox_synthesizer_audio_query(synthesizer, +/// "コンニチワ'", // AquesTalk風記法 +/// 2, // "四国めたん (ノーマル)" +/// (VoicevoxAudioQueryOptions){.kana = true}, +/// &audio_query); +/// ``` +/// } +/// +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `text`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_audio_query_json`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_audio_query( synthesizer: &VoicevoxSynthesizer, @@ -440,10 +571,10 @@ pub unsafe extern "C" fn voicevox_synthesizer_audio_query( })()) } -/// `accent_phrases` のオプション +/// ::voicevox_synthesizer_create_accent_phrases のオプション。 #[repr(C)] pub struct VoicevoxAccentPhrasesOptions { - /// aquestalk形式のkanaとしてテキストを解釈する + /// AquesTalk風記法としてテキストを解釈する kana: bool, } @@ -452,15 +583,43 @@ pub struct VoicevoxAccentPhrasesOptions { pub static voicevox_default_accent_phrases_options: VoicevoxAccentPhrasesOptions = ConstDefault::DEFAULT; -/// create_accent_phrases を実行する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] text テキスト -/// @param [in] style_id スタイルID #VoicevoxStyleId -/// @param [in] output_accent_phrases_json アクセントフレーズのjson文字列 +/// AccentPhrase (アクセント句)の配列をJSON形式で生成する。 /// -/// # Safety -/// @param text null終端文字列であること -/// @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある +/// 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 +/// +/// @param [in] synthesizer 音声シンセサイザ +/// @param [in] text UTF-8の日本語テキストまたはAquesTalk風記法 +/// @param [in] style_id スタイルID +/// @param [in] options オプション +/// @param [out] output_accent_phrases_json 生成先 +/// +/// @returns 結果コード +/// +/// \examples{ +/// ```c +/// char *accent_phrases; +/// voicevox_synthesizer_create_accent_phrases( +/// synthesizer, +/// "こんにちは", // 日本語テキスト +/// 2, // "四国めたん (ノーマル)" +/// voicevox_default_accent_phrases_options, &accent_phrases); +/// ``` +/// +/// ```c +/// char *accent_phrases; +/// voicevox_synthesizer_create_accent_phrases( +/// synthesizer, +/// "コンニチワ'", // AquesTalk風記法 +/// 2, // "四国めたん (ノーマル)" +/// (VoicevoxAccentPhrasesOptions){.kana = true}, &accent_phrases); +/// ``` +/// } +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `text`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_audio_query_json`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_create_accent_phrases( synthesizer: &VoicevoxSynthesizer, @@ -485,15 +644,22 @@ pub unsafe extern "C" fn voicevox_synthesizer_create_accent_phrases( })()) } -/// replace_mora_data を実行する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] accent_phrases_json 変換前のアクセントフレーズのjson文字列 -/// @param [in] style_id スタイルID #VoicevoxStyleId -/// @param [in] output_accent_phrases_json 変換後のアクセントフレーズのjson文字列 +/// AccentPhraseの配列の音高・音素長を、特定の声で生成しなおす。 /// -/// # Safety -/// @param accent_phrases_json null終端文字列であること -/// @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある +/// 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 +/// +/// @param [in] synthesizer 音声シンセサイザ +/// @param [in] accent_phrases_json AccentPhraseの配列のJSON文字列 +/// @param [in] style_id スタイルID +/// @param [out] output_accent_phrases_json 生成先 +/// +/// @returns 結果コード +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `accent_phrases_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_audio_query_json`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_replace_mora_data( synthesizer: &VoicevoxSynthesizer, @@ -519,15 +685,22 @@ pub unsafe extern "C" fn voicevox_synthesizer_replace_mora_data( })()) } -/// replace_phoneme_length を実行する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] accent_phrases_json 変換前のアクセントフレーズのjson文字列 -/// @param [in] style_id スタイルID #VoicevoxStyleId -/// @param [in] output_accent_phrases_json 変換後のアクセントフレーズのjson文字列 +/// AccentPhraseの配列の音素長を、特定の声で生成しなおす。 /// -/// # Safety -/// @param accent_phrases_json null終端文字列であること -/// @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある +/// 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 +/// +/// @param [in] synthesizer 音声シンセサイザ +/// @param [in] accent_phrases_json AccentPhraseの配列のJSON文字列 +/// @param [in] style_id スタイルID +/// @param [out] output_accent_phrases_json 生成先 +/// +/// @returns 結果コード +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `accent_phrases_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_audio_query_json`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_replace_phoneme_length( synthesizer: &VoicevoxSynthesizer, @@ -553,15 +726,22 @@ pub unsafe extern "C" fn voicevox_synthesizer_replace_phoneme_length( })()) } -/// replace_mora_pitch を実行する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] accent_phrases_json 変換前のアクセントフレーズのjson文字列 -/// @param [in] style_id スタイルID #VoicevoxStyleId -/// @param [in] output_accent_phrases_json 変換後のアクセントフレーズのjson文字列 +/// AccentPhraseの配列の音高を、特定の声で生成しなおす。 /// -/// # Safety -/// @param accent_phrases_json null終端文字列であること -/// @param output_accent_phrases_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある +/// 生成したJSON文字列を解放するには ::voicevox_json_free を使う。 +/// +/// @param [in] synthesizer 音声シンセサイザ +/// @param [in] accent_phrases_json AccentPhraseの配列のJSON文字列 +/// @param [in] style_id スタイルID +/// @param [out] output_accent_phrases_json 生成先 +/// +/// @returns 結果コード +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `accent_phrases_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_audio_query_json`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_replace_mora_pitch( synthesizer: &VoicevoxSynthesizer, @@ -587,7 +767,7 @@ pub unsafe extern "C" fn voicevox_synthesizer_replace_mora_pitch( })()) } -/// `voicevox_synthesizer_synthesis` のオプション +/// ::voicevox_synthesizer_synthesis のオプション。 #[repr(C)] pub struct VoicevoxSynthesisOptions { /// 疑問文の調整を有効にする @@ -598,18 +778,25 @@ pub struct VoicevoxSynthesisOptions { #[no_mangle] pub static voicevox_default_synthesis_options: VoicevoxSynthesisOptions = ConstDefault::DEFAULT; -/// AudioQuery から音声合成する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] audio_query_json jsonフォーマットされた AudioQuery -/// @param [in] style_id スタイルID #VoicevoxStyleId -/// @param [in] options AudioQueryから音声合成オプション -/// @param [out] output_wav_length 出力する wav データのサイズ -/// @param [out] output_wav wav データの出力先 -/// @return 結果コード #VoicevoxResultCode +/// AudioQueryから音声合成を行う。 /// -/// # Safety -/// @param output_wav_length 出力先の領域が確保された状態でpointerに渡されていること -/// @param output_wav 自動で output_wav_length 分のデータが割り当てられるので ::voicevox_wav_free で解放する必要がある +/// 生成したWAVデータを解放するには ::voicevox_wav_free を使う。 +/// +/// @param [in] synthesizer 音声シンセサイザ +/// @param [in] audio_query_json AudioQueryのJSON文字列 +/// @param [in] style_id スタイルID +/// @param [in] options オプション +/// @param [out] output_wav_length 出力のバイト長 +/// @param [out] output_wav 出力先 +/// +/// @returns 結果コード +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `audio_query_json`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_wav_length`は書き込みについて有効でなければならない。 +/// - `output_wav`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_synthesis( synthesizer: &VoicevoxSynthesizer, @@ -635,10 +822,10 @@ pub unsafe extern "C" fn voicevox_synthesizer_synthesis( })()) } -/// テキスト音声合成オプション +/// ::voicevox_synthesizer_tts のオプション。 #[repr(C)] pub struct VoicevoxTtsOptions { - /// aquestalk形式のkanaとしてテキストを解釈する + /// AquesTalk風記法としてテキストを解釈する kana: bool, /// 疑問文の調整を有効にする enable_interrogative_upspeak: bool, @@ -648,18 +835,25 @@ pub struct VoicevoxTtsOptions { #[no_mangle] pub static voicevox_default_tts_options: VoicevoxTtsOptions = ConstDefault::DEFAULT; -/// テキスト音声合成を実行する -/// @param [in] synthesizer 音声シンセサイザ #VoicevoxSynthesizer -/// @param [in] text テキスト。文字コードはUTF-8 -/// @param [in] style_id スタイルID #VoicevoxStyleId -/// @param [in] options テキスト音声合成オプション -/// @param [out] output_wav_length 出力する wav データのサイズ -/// @param [out] output_wav wav データの出力先 -/// @return 結果コード #VoicevoxResultCode +/// テキスト音声合成を行う。 /// -/// # Safety -/// @param output_wav_length 出力先の領域が確保された状態でpointerに渡されていること -/// @param output_wav は自動で output_wav_length 分のデータが割り当てられるので ::voicevox_wav_free で解放する必要がある +/// 生成したWAVデータを解放するには ::voicevox_wav_free を使う。 +/// +/// @param [in] synthesizer +/// @param [in] text UTF-8の日本語テキストまたはAquesTalk風記法 +/// @param [in] style_id スタイルID +/// @param [in] options オプション +/// @param [out] output_wav_length 出力のバイト長 +/// @param [out] output_wav 出力先 +/// +/// @returns 結果コード +/// +/// \safety{ +/// - `synthesizer`は ::voicevox_synthesizer_new_with_initialize で得たものでなければならず、また ::voicevox_synthesizer_delete で解放されていてはいけない。 +/// - `text`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_wav_length`は書き込みについて有効でなければならない。 +/// - `output_wav`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_synthesizer_tts( synthesizer: &VoicevoxSynthesizer, @@ -681,29 +875,63 @@ pub unsafe extern "C" fn voicevox_synthesizer_tts( })()) } -/// jsonフォーマットされたデータのメモリを解放する -/// @param [in] json 解放する json データ +/// JSON文字列を解放する。 /// -/// # Safety -/// @param voicevox_audio_query で確保されたポインタであり、かつ呼び出し側でバッファの変更を行われていないこと +/// @param [in] json 解放するJSON文字列 +/// +/// \safety{ +/// - `json`は以下のAPIで得られたポインタでなくてはいけない。 +/// - ::voicevox_create_supported_devices_json +/// - ::voicevox_synthesizer_audio_query +/// - ::voicevox_synthesizer_create_accent_phrases +/// - ::voicevox_synthesizer_replace_mora_data +/// - ::voicevox_synthesizer_replace_phoneme_length +/// - ::voicevox_synthesizer_replace_mora_pitch +/// - 文字列の長さは生成時より変更されていてはならない。 +/// - `json`は読み込みと書き込みについて有効でなければならない。 +/// - `json`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_json_free(json: *mut c_char) { drop(CString::from_raw(C_STRING_DROP_CHECKER.check(json))); } -/// wav データのメモリを解放する -/// @param [in] wav 解放する wav データ +/// WAVデータを解放する。 /// -/// # Safety -/// @param wav voicevox_tts,voicevox_synthesis で確保されたポインタであり、かつ呼び出し側でバッファの変更を行われていないこと +/// @param [in] wav 解放するWAVデータ +/// +/// \safety{ +/// - `wav`は以下のAPIで得られたポインタでなくてはいけない。 +/// - ::voicevox_synthesizer_synthesis +/// - ::voicevox_synthesizer_tts +/// - `wav`は読み込みと書き込みについて有効でなければならない。 +/// - `wav`は以後ダングリングポインタ(_dangling pointer_)として扱われなくてはならない。 +/// } #[no_mangle] pub extern "C" fn voicevox_wav_free(wav: *mut u8) { U8_SLICE_OWNER.drop_for(wav); } -/// エラー結果をメッセージに変換する -/// @param [in] result_code メッセージに変換する result_code -/// @return 結果コードを元に変換されたメッセージ文字列 +/// 結果コードに対応したメッセージ文字列を取得する。 +/// +/// @param [in] result_code 結果コード +/// +/// @returns 結果コードに対応したメッセージ文字列 +/// +/// \examples{ +/// ```c +/// const char *actual = voicevox_error_result_to_message(VOICEVOX_RESULT_OK); +/// const char *EXPECTED = "エラーが発生しませんでした"; +/// assert(strcmp(actual, EXPECTED) == 0); +/// ``` +/// +/// ```c +/// const char *actual = +/// voicevox_error_result_to_message(VOICEVOX_RESULT_LOAD_MODEL_ERROR); +/// const char *EXPECTED = "modelデータ読み込みに失敗しました"; +/// assert(strcmp(actual, EXPECTED) == 0); +/// ``` +/// } #[no_mangle] pub extern "C" fn voicevox_error_result_to_message( result_code: VoicevoxResultCode, @@ -716,13 +944,13 @@ pub extern "C" fn voicevox_error_result_to_message( C_STRING_DROP_CHECKER.blacklist(message).as_ptr() } -/// ユーザー辞書 +/// ユーザー辞書。 #[derive(Default)] pub struct VoicevoxUserDict { dict: Arc>, } -/// ユーザー辞書の単語 +/// ユーザー辞書の単語。 #[repr(C)] pub struct VoicevoxUserDictWord { /// 表記 @@ -737,7 +965,7 @@ pub struct VoicevoxUserDictWord { priority: u32, } -/// ユーザー辞書の単語の種類 +/// ユーザー辞書の単語の種類。 #[repr(i32)] #[allow(non_camel_case_types)] #[derive(Copy, Clone)] @@ -754,13 +982,11 @@ pub enum VoicevoxUserDictWordType { VOICEVOX_USER_DICT_WORD_TYPE_SUFFIX = 4, } -/// VoicevoxUserDictWordを最低限のパラメータで作成する。 +/// ::VoicevoxUserDictWord を最低限のパラメータで作成する。 +/// /// @param [in] surface 表記 /// @param [in] pronunciation 読み -/// @return VoicevoxUserDictWord -/// -/// # Safety -/// @param surface, pronunciation は有効な文字列へのポインタであること +/// @returns ::VoicevoxUserDictWord #[no_mangle] pub extern "C" fn voicevox_user_dict_word_make( surface: *const c_char, @@ -775,24 +1001,24 @@ pub extern "C" fn voicevox_user_dict_word_make( } } -/// ユーザー辞書を作成する -/// @return VoicevoxUserDict +/// ユーザー辞書をb>構築(_construct_)する。 /// -/// # Safety -/// @return 自動で解放されることはないので、呼び出し側で :voicevox_user_dict_delete で解放する必要がある +/// @returns ::VoicevoxUserDict #[no_mangle] pub extern "C" fn voicevox_user_dict_new() -> Box { Default::default() } -/// ユーザー辞書にファイルを読み込ませる -/// @param [in] user_dict VoicevoxUserDictのポインタ +/// ユーザー辞書にファイルを読み込ませる。 +/// +/// @param [in] user_dict ユーザー辞書 /// @param [in] dict_path 読み込む辞書ファイルのパス -/// @return 結果コード #VoicevoxResultCode +/// @returns 結果コード /// -/// # Safety -/// @param user_dict は有効な :VoicevoxUserDict のポインタであること -/// @param dict_path パスが有効な文字列を指していること +/// \safety{ +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// - `dict_path`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_user_dict_load( user_dict: &VoicevoxUserDict, @@ -807,19 +1033,25 @@ pub unsafe extern "C" fn voicevox_user_dict_load( })()) } -/// ユーザー辞書に単語を追加する -/// @param [in] user_dict VoicevoxUserDictのポインタ +/// ユーザー辞書に単語を追加する。 +/// +/// @param [in] ユーザー辞書 /// @param [in] word 追加する単語 /// @param [out] output_word_uuid 追加した単語のUUID -/// @return 結果コード #VoicevoxResultCode +/// @returns 結果コード /// /// # Safety /// @param user_dict は有効な :VoicevoxUserDict のポインタであること /// +/// \safety{ +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// - `word->surface`と`word->pronunciation`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// - `output_word_uuid`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_user_dict_add_word( user_dict: &VoicevoxUserDict, - word: &VoicevoxUserDictWord, + word: &VoicevoxUserDictWord, // FIXME: に従う output_word_uuid: NonNull<[u8; 16]>, ) -> VoicevoxResultCode { into_result_code_with_error((|| { @@ -834,19 +1066,23 @@ pub unsafe extern "C" fn voicevox_user_dict_add_word( })()) } -/// ユーザー辞書の単語を更新する -/// @param [in] user_dict VoicevoxUserDictのポインタ +/// ユーザー辞書の単語を更新する。 +/// +/// @param [in] user_dict ユーザー辞書 /// @param [in] word_uuid 更新する単語のUUID /// @param [in] word 新しい単語のデータ -/// @return 結果コード #VoicevoxResultCode +/// @returns 結果コード /// -/// # Safety -/// @param user_dict は有効な :VoicevoxUserDict のポインタであること +/// \safety{ +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// - `word_uuid`は読み込みについて有効でなければならない。 +/// - `word->surface`と`word->pronunciation`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_user_dict_update_word( user_dict: &VoicevoxUserDict, word_uuid: &[u8; 16], - word: &VoicevoxUserDictWord, + word: &VoicevoxUserDictWord, // FIXME: に従う ) -> VoicevoxResultCode { into_result_code_with_error((|| { let word_uuid = Uuid::from_slice(word_uuid).map_err(CApiError::InvalidUuid)?; @@ -860,10 +1096,16 @@ pub unsafe extern "C" fn voicevox_user_dict_update_word( })()) } -/// ユーザー辞書から単語を削除する -/// @param [in] user_dict VoicevoxUserDictのポインタ +/// ユーザー辞書から単語を削除する。 +/// +/// @param [in] user_dict ユーザー辞書 /// @param [in] word_uuid 削除する単語のUUID -/// @return 結果コード #VoicevoxResultCode +/// @returns 結果コード +/// +/// \safety{ +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// - `word_uuid`は読み込みについて有効でなければならない。 +/// } #[no_mangle] pub extern "C" fn voicevox_user_dict_remove_word( user_dict: &VoicevoxUserDict, @@ -880,14 +1122,16 @@ pub extern "C" fn voicevox_user_dict_remove_word( })()) } -/// ユーザー辞書の単語をJSON形式で出力する -/// @param [in] user_dict VoicevoxUserDictのポインタ -/// @param [out] output_json JSON形式の文字列 -/// @return 結果コード #VoicevoxResultCode +/// ユーザー辞書の単語をJSON形式で出力する。 /// -/// # Safety -/// @param user_dict は有効な :VoicevoxUserDict のポインタであること -/// @param output_json 自動でheapメモリが割り当てられるので ::voicevox_json_free で解放する必要がある +/// @param [in] user_dict ユーザー辞書 +/// @param [out] output_json 出力先 +/// @returns 結果コード +/// +/// \safety{ +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// - `output_json`は書き込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_user_dict_to_json( user_dict: &VoicevoxUserDict, @@ -902,10 +1146,15 @@ pub unsafe extern "C" fn voicevox_user_dict_to_json( VoicevoxResultCode::VOICEVOX_RESULT_OK } -/// 他のユーザー辞書をインポートする -/// @param [in] user_dict VoicevoxUserDictのポインタ +/// 他のユーザー辞書をインポートする。 +/// +/// @param [in] user_dict ユーザー辞書 /// @param [in] other_dict インポートするユーザー辞書 -/// @return 結果コード #VoicevoxResultCode +/// @returns 結果コード +/// +/// \safety{ +/// - `user_dict`と`other_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// } #[no_mangle] pub extern "C" fn voicevox_user_dict_import( user_dict: &VoicevoxUserDict, @@ -922,13 +1171,15 @@ pub extern "C" fn voicevox_user_dict_import( })()) } -/// ユーザー辞書をファイルに保存する -/// @param [in] user_dict VoicevoxUserDictのポインタ +/// ユーザー辞書をファイルに保存する。 +/// +/// @param [in] user_dict ユーザー辞書 /// @param [in] path 保存先のファイルパス /// -/// # Safety -/// @param user_dict は有効な :VoicevoxUserDict のポインタであること -/// @param path は有効なUTF-8文字列であること +/// \safety{ +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 +/// - `path`はヌル終端文字列を指し、かつ読み込みについて有効でなければならない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_user_dict_save( user_dict: &VoicevoxUserDict, @@ -945,11 +1196,13 @@ pub unsafe extern "C" fn voicevox_user_dict_save( })()) } -/// ユーザー辞書を廃棄する。 -/// @param [in] user_dict VoicevoxUserDictのポインタ +/// ユーザー辞書を破棄(_destruct_)する。 /// -/// # Safety -/// @param user_dict は有効な :VoicevoxUserDict のポインタであること +/// @param [in] user_dict 破棄対象 +/// +/// \safety{ +/// - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また既にこの関数で解放されていてはいけない。 +/// } #[no_mangle] pub unsafe extern "C" fn voicevox_user_dict_delete(user_dict: Box) { drop(user_dict); diff --git a/crates/voicevox_core_python_api/python/voicevox_core/__init__.py b/crates/voicevox_core_python_api/python/voicevox_core/__init__.py index 5214b1187..232220785 100644 --- a/crates/voicevox_core_python_api/python/voicevox_core/__init__.py +++ b/crates/voicevox_core_python_api/python/voicevox_core/__init__.py @@ -1,3 +1,5 @@ +"""無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのコア。""" + from . import _load_dlls # noqa: F401 from ._models import ( # noqa: F401 AccelerationMode, 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 859959b3d..6dfd1aa37 100644 --- a/crates/voicevox_core_python_api/python/voicevox_core/_models.py +++ b/crates/voicevox_core_python_api/python/voicevox_core/_models.py @@ -9,27 +9,63 @@ @pydantic.dataclasses.dataclass class StyleMeta: + """**スタイル** (_style_)のメタ情報。""" + name: str + """スタイル名。""" + id: int + """スタイルID。""" @pydantic.dataclasses.dataclass class SpeakerMeta: - """メタ情報。""" + """**話者** (*speaker*)のメタ情報。""" name: str + """話者名。""" + styles: List[StyleMeta] + """話者に属するスタイル。""" + speaker_uuid: str + """話者のバージョン。""" + version: str + """話者のUUID。""" @pydantic.dataclasses.dataclass class SupportedDevices: - """サポートデバイス情報。""" + """ + このライブラリで利用可能なデバイスの情報。 + + あくまで本ライブラリが対応しているデバイスの情報であることに注意。GPUが使える環境ではなかったとしても + ``cuda`` や ``dml`` は ``True`` を示しうる。 + """ cpu: bool + """ + CPUが利用可能。 + + 常に ``True`` 。 + """ + cuda: bool + """ + CUDAが利用可能。 + + ONNX Runtimeの `CUDA Execution Provider `_ + (``CUDAExecutionProvider``)に対応する。必要な環境についてはそちらを参照。 + """ + dml: bool + """ + DirectMLが利用可能。 + + ONNX Runtimeの `DirectML Execution Provider `_ + (``DmlExecutionProvider``)に対応する。必要な環境についてはそちらを参照。 + """ class AccelerationMode(str, Enum): @@ -38,40 +74,95 @@ class AccelerationMode(str, Enum): """ AUTO = "AUTO" + """ + 実行環境に合った適切なハードウェアアクセラレーションモードを選択する。 + """ + CPU = "CPU" + """ハードウェアアクセラレーションモードを"CPU"に設定する。""" + GPU = "GPU" + """ハードウェアアクセラレーションモードを"GPU"に設定する。""" @pydantic.dataclasses.dataclass class Mora: + """モーラ(子音+母音)ごとの情報。""" + text: str + """文字。""" + consonant: Optional[str] + """子音の音素。""" + consonant_length: Optional[float] + """子音の音長。""" + vowel: str + """母音の音素。""" + vowel_length: float + """母音の音長。""" + pitch: float + """音高。""" @pydantic.dataclasses.dataclass class AccentPhrase: + """AccentPhrase (アクセント句ごとの情報)。""" + moras: List[Mora] + """モーラの配列。""" + accent: int + """アクセント箇所。""" + pause_mora: Optional[Mora] + """後ろに無音を付けるかどうか。""" + is_interrogative: bool + """疑問系かどうか。""" @pydantic.dataclasses.dataclass class AudioQuery: + """AudioQuery (音声合成用のクエリ)。""" + accent_phrases: List[AccentPhrase] + """アクセント句の配列。""" + speed_scale: float + """全体の話速。""" + pitch_scale: float + """全体の音高。""" + intonation_scale: float + """全体の抑揚。""" + volume_scale: float + """全体の音量。""" + pre_phoneme_length: float + """音声の前の無音時間。""" + post_phoneme_length: float + """音声の後の無音時間。""" + output_sampling_rate: int + """音声データの出力サンプリングレート。""" + output_stereo: bool + """音声データをステレオ出力するか否か。""" + kana: Optional[str] + """ + [読み取り専用] AquesTalk風記法。 + + :func:`Synthesizer.audio_query` が返すもののみ ``str`` となる。入力としてのAudioQueryでは無視さ + れる。 + """ class UserDictWordType(str, Enum): diff --git a/crates/voicevox_core_python_api/python/voicevox_core/_rust.pyi b/crates/voicevox_core_python_api/python/voicevox_core/_rust.pyi index 0a444036c..345f483be 100644 --- a/crates/voicevox_core_python_api/python/voicevox_core/_rust.pyi +++ b/crates/voicevox_core_python_api/python/voicevox_core/_rust.pyi @@ -16,36 +16,50 @@ from voicevox_core import ( __version__: str -def supported_devices() -> SupportedDevices: ... +def supported_devices() -> SupportedDevices: + """ + このライブラリで利用可能なデバイスの情報を取得する。 + + .. code-block:: + + import voicevox_core + + supported_devices = voicevox_core.supported_devices() + """ + ... class VoiceModel: + """音声モデル。""" + @staticmethod async def from_path(path: Union[Path, str]) -> "VoiceModel": """ - Parameters - ---------- - path - vvmファイルへのパス + VVMファイルから ``VoiceModel`` を生成する。 + + :param path: VVMファイルへのパス。 """ ... @property - def id(self) -> str: ... + def id(self) -> str: + """ID。""" + ... @property - def metas(self) -> List[SpeakerMeta]: ... + def metas(self) -> List[SpeakerMeta]: + """メタ情報。""" + ... class OpenJtalk: - def __init__(self, open_jtalk_dict_dir: Union[Path, str]) -> None: - """ - Parameters - ---------- - open_jtalk_dict_dir - open_jtalkの辞書ディレクトリ。 - """ - ... + """ + テキスト解析器としてのOpen JTalk。 + + :param open_jtalk_dict_dir: open_jtalkの辞書ディレクトリ。 + """ + + def __init__(self, open_jtalk_dict_dir: Union[Path, str]) -> None: ... def use_user_dict(self, user_dict: UserDict) -> None: """ユーザー辞書を設定する。 - この関数を読んだ後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。 + この関数を呼び出した後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。 Parameters ---------- @@ -55,6 +69,8 @@ class OpenJtalk: ... class Synthesizer: + """音声シンセサイザ。""" + @staticmethod async def new_with_initialize( open_jtalk: OpenJtalk, @@ -65,55 +81,41 @@ class Synthesizer: load_all_models: bool = False, ) -> "Synthesizer": """ - Parameters - ---------- - open_jtalk - acceleration_mode - ハードウェアアクセラレーションモード。 - cpu_num_threads - CPU利用数を指定。0を指定すると環境に合わせたCPUが利用される。 - load_all_models - 全てのモデルを読み込む。 + :class:`Synthesizer` を生成する。 + + :param open_jtalk: Open JTalk。 + :param acceleration_mode: ハードウェアアクセラレーションモード。 + :param cpu_num_threads: CPU利用数を指定。0を指定すると環境に合わせたCPUが利用される。 + :param load_all_models: 全てのモデルを読み込む。 """ ... def __repr__(self) -> str: ... @property def is_gpu_mode(self) -> bool: - """ハードウェアアクセラレーションがGPUモードか判定する。 - - Returns - ------- - GPUモードならtrue、そうでないならfalse - """ + """ハードウェアアクセラレーションがGPUモードかどうか。""" ... @property def metas(self) -> SpeakerMeta: - """メタ情報を取得する。""" + """メタ情報。""" ... async def load_voice_model(self, model: VoiceModel) -> None: - """モデルを読み込む。 + """ + モデルを読み込む。 - Parameters - ---------- - style_id - 読み込むモデルの話者ID。 + :param style_id: 読み込むモデルのスタイルID。 """ ... def unload_voice_model(self, voice_model_id: str) -> None: - """モデルの読み込みを解除する。 + """音声モデルの読み込みを解除する。 - Parameters - ---------- - voice_model_id - 音声モデルID。 + :param voice_model_id: 音声モデルID。 """ ... def is_loaded_voice_model(self, voice_model_id: str) -> bool: - """指定したvoice_model_idのモデルが読み込まれているか判定する。 + """ + 指定したvoice_model_idのモデルが読み込まれているか判定する。 - Returns - ------- - モデルが読み込まれているのであればtrue、そうでないならfalse + :returns: モデルが読み込まれているかどうか。 """ ... async def audio_query( @@ -122,20 +124,14 @@ class Synthesizer: style_id: int, kana: bool = False, ) -> AudioQuery: - """AudioQuery を実行する。 + """ + :class:`AudioQuery` を生成する。 - Parameters - ---------- - text - テキスト。文字コードはUTF-8。 - style_id - 話者ID。 - kana - aquestalk形式のkanaとしてテキストを解釈する。 + :param text: テキスト。文字コードはUTF-8。 + :param style_id: スタイルID。 + :param kana: ``text`` をAquesTalk風記法として解釈する。 - Returns - ------- - :class:`AudioQuery` + :returns: 話者とテキストから生成された :class:`AudioQuery` 。 """ ... async def create_accent_phrases( @@ -144,20 +140,14 @@ class Synthesizer: style_id: int, kana: bool = False, ) -> List[AccentPhrase]: - """create_accent_phrases を実行する。 + """ + AccentPhrase (アクセント句)の配列を生成する。 - Parameters - ---------- - text - テキスト。文字コードはUTF-8。 - style_id - 話者ID。 - kana - aquestalk形式のkanaとしてテキストを解釈する。 + :param text: UTF-8の日本語テキストまたはAquesTalk風記法。 + :param style_id: スタイルID。 + :param kana: ``text`` をAquesTalk風記法として解釈する。 - Returns - ------- - :class:`List` [:class:`AccentPhrase`] + :returns: :class:`AccentPhrase` の配列。 """ ... async def replace_mora_data( @@ -167,15 +157,8 @@ class Synthesizer: ) -> List[AccentPhrase]: """アクセント句の音高・音素長を変更する。 - Parameters - ---------- - accent_phrases - 変更元のアクセント句。 - style_id - 話者ID。 - Returns - ------- - :class:`List` [:class:`AccentPhrase`] + :param accent_phrases: 変更元のアクセント句。 + :param style_id: スタイルID。 """ ... async def replace_phoneme_length( @@ -183,17 +166,11 @@ class Synthesizer: accent_phrases: List[AccentPhrase], style_id: int, ) -> List[AccentPhrase]: - """アクセント句の音素長を変更する。 + """ + アクセント句の音素長を変更する。 - Parameters - ---------- - accent_phrases - 変更元のアクセント句。 - style_id - 話者ID。 - Returns - ------- - :class:`List` [:class:`AccentPhrase`] + :param accent_phrases: 変更元のアクセント句。 + :param style_id: スタイルID。 """ ... async def replace_mora_pitch( @@ -201,17 +178,11 @@ class Synthesizer: accent_phrases: List[AccentPhrase], style_id: int, ) -> List[AccentPhrase]: - """アクセント句の音高を変更する。 + """ + アクセント句の音高を変更する。 - Parameters - ---------- - accent_phrases - 変更元のアクセント句。 - style_id - 話者ID。 - Returns - ------- - :class:`List` [:class:`AccentPhrase`] + :param accent_phrases: 変更元のアクセント句。 + :param style_id: スタイルID。 """ ... async def synthesis( @@ -220,20 +191,14 @@ class Synthesizer: style_id: int, enable_interrogative_upspeak: bool = True, ) -> bytes: - """AudioQuery から音声合成する。 + """ + :class:`AudioQuery` から音声合成する。 - Parameters - ---------- - audio_query - AudioQuery。 - style_id - 話者ID。 - enable_interrogative_upspeak - 疑問文の調整を有効にする。 + :param audio_query: :class:`AudioQuery` 。 + :param style_id: スタイルID。 + :param enable_interrogative_upspeak: 疑問文の調整を有効にする。 - Returns - ------- - wavデータ + :returns: WAVデータ。 """ ... async def tts( @@ -243,18 +208,15 @@ class Synthesizer: kana: bool = False, enable_interrogative_upspeak: bool = True, ) -> bytes: - """テキスト音声合成を実行する。 + """ + テキスト音声合成を実行する。 - Parameters - ---------- - text - テキスト。文字コードはUTF-8。 - style_id - 話者ID。 - kana - aquestalk形式のkanaとしてテキストを解釈する。 - enable_interrogative_upspeak - 疑問文の調整を有効にする。 + :param text: UTF-8の日本語テキストまたはAquesTalk風記法。 + :param style_id: スタイルID。 + :param kana: ``text`` をAquesTalk風記法として解釈する。 + :param enable_interrogative_upspeak: 疑問文の調整を有効にする。 + + :returns: WAVデータ。 """ ... @@ -333,7 +295,7 @@ class UserDict: ... class VoicevoxError(Exception): - """VOICEVOXで発生したエラー。""" + """VOICEVOX COREのエラー。""" ... diff --git a/docs/apis/c_api/doxygen/Doxyfile b/docs/apis/c_api/doxygen/Doxyfile index 62e4aafbc..c319ae7d8 100644 --- a/docs/apis/c_api/doxygen/Doxyfile +++ b/docs/apis/c_api/doxygen/Doxyfile @@ -2657,3 +2657,9 @@ GENERATE_LEGEND = YES # The default value is: YES. DOT_CLEANUP = YES + +ALIASES += example{1}="
Example
\1
" +ALIASES += examples{1}="
Examples
\1
" + +# 中身は箇条書きで、素の文章からは始まらない想定 +ALIASES += safety{1}="
Safety
⚠️安全性要件安全性要件は以下の通りである。\1
"