From a4187c8840b92ad7243063ef5a8fbb3e715c51c4 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Thu, 3 Aug 2023 10:45:53 +0900 Subject: [PATCH] =?UTF-8?q?Add:=20=E3=83=89=E3=82=AD=E3=83=A5=E3=83=A1?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Hiroshiba/VoicevoxCore/AccentPhrase.java | 5 + .../jp/Hiroshiba/VoicevoxCore/AudioQuery.java | 17 ++- .../java/jp/Hiroshiba/VoicevoxCore/Mora.java | 11 +- .../jp/Hiroshiba/VoicevoxCore/OpenJtalk.java | 18 ++- .../Hiroshiba/VoicevoxCore/Synthesizer.java | 104 ++++++++++++++++++ .../jp/Hiroshiba/VoicevoxCore/VoiceModel.java | 18 ++- .../VoicevoxCore/VoicevoxException.java | 1 + 7 files changed, 165 insertions(+), 9 deletions(-) diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AccentPhrase.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AccentPhrase.java index 3f35d9f43..2f758d3f4 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AccentPhrase.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AccentPhrase.java @@ -10,24 +10,29 @@ import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; +/** AccentPhrase (アクセント句ごとの情報)。 */ public class AccentPhrase { + /** モーラの配列。 */ @JsonProperty("moras") @SerializedName("moras") @Expose @Nonnull public List moras; + /** アクセント箇所。 */ @JsonProperty("accent") @SerializedName("accent") @Expose public int accent; + /** 後ろに無音を付けるかどうか。 */ @JsonProperty("pause_mora") @SerializedName("pause_mora") @Expose @Nullable public Mora pauseMora; + /** 疑問系かどうか。 */ @JsonProperty("is_interrogative") @SerializedName("is_interrogative") @Expose diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AudioQuery.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AudioQuery.java index fa8ecc7a8..3b38ab728 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AudioQuery.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/AudioQuery.java @@ -9,58 +9,73 @@ import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; +/** AudioQuery (音声合成用のクエリ)。 */ public class AudioQuery { + /** アクセント句の配列。 */ @JsonProperty("accent_phrases") @SerializedName("accent_phrases") @Expose @Nonnull public List accentPhrases; + /** 全体の話速。 */ @JsonProperty("speed_scale") @SerializedName("speed_scale") @Expose public double speedScale; + /** 全体の音高。 */ @JsonProperty("pitch_scale") @SerializedName("pitch_scale") @Expose public double pitchScale; + /** 全体の抑揚。 */ @JsonProperty("intonation_scale") @SerializedName("intonation_scale") @Expose public double intonationScale; + /** 全体の音量。 */ @JsonProperty("volume_scale") @SerializedName("volume_scale") @Expose public double volumeScale; + /** 音声の前の無音時間。 */ @JsonProperty("pre_phoneme_length") @SerializedName("pre_phoneme_length") @Expose public double prePhonemeLength; + /** 音声の後の無音時間。 */ @JsonProperty("post_phoneme_length") @SerializedName("post_phoneme_length") @Expose public double postPhonemeLength; + /** 音声データの出力サンプリングレート。 */ @JsonProperty("output_sampling_rate") @SerializedName("output_sampling_rate") @Expose public int outputSamplingRate; + /** 音声データをステレオ出力するか否か。 */ @JsonProperty("output_stereo") @SerializedName("output_stereo") @Expose public boolean outputStereo; + /** + * [読み取り専用] AquesTalk風記法。 + * + * {@link Synthesizer#audioQuery} が返すもののみ ``str`` となる。入力としてのAudioQueryでは無視される。 + */ @JsonProperty("kana") @SerializedName("kana") @Expose @Nonnull - public String kana; + final public String kana; public AudioQuery() { this.accentPhrases = new ArrayList<>(); diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Mora.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Mora.java index 52ba99c0a..e1d26a30d 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Mora.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Mora.java @@ -7,7 +7,9 @@ import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; +/** モーラ(子音+母音)ごとの情報。 */ public class Mora { + /** 文字。 */ @JsonProperty("text") @SerializedName("text") @Expose @@ -15,17 +17,20 @@ public class Mora { @SuppressWarnings("NullableProblems") public String text; + /** 子音の音素。 */ @JsonProperty("consonant") @SerializedName("consonant") @Expose @Nullable public String consonant; + /** 子音の音長。 */ @JsonProperty("consonant_length") @SerializedName("consonant_length") @Expose public java.lang.Double consonantLength; + /** 母音の音素。 */ @JsonProperty("vowel") @SerializedName("vowel") @Expose @@ -33,11 +38,13 @@ public class Mora { @SuppressWarnings("NullableProblems") public String vowel; + /** 母音の音長。 */ @JsonProperty("vowel_length") @SerializedName("vowel_length") @Expose public double vowelLength; + /** 音高。 */ @JsonProperty("pitch") @SerializedName("pitch") @Expose @@ -45,8 +52,8 @@ public class Mora { public Mora() { this.text = ""; - this.consonant = ""; - this.consonantLength = 0.0; + this.consonant = null; + this.consonantLength = null; this.vowel = ""; this.vowelLength = 0.0; this.pitch = 0.0; diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/OpenJtalk.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/OpenJtalk.java index 3c5121775..71c66454d 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/OpenJtalk.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/OpenJtalk.java @@ -1,20 +1,30 @@ package jp.Hiroshiba.VoicevoxCore; +/** テキスト解析器としてのOpen JTalk。 */ public class OpenJtalk implements AutoCloseable { protected long internal; - public OpenJtalk() { - rsNewWithoutDic(); - } - + /** + * Open JTalkの辞書ディレクトリ。 + * + * @param openJtalkDictDir 辞書のディレクトリ。 + */ public OpenJtalk(String openJtalkDictDir) { rsNewWithInitialize(openJtalkDictDir); } + /** + * ユーザー辞書を設定する。 + * + * この関数を呼び出した後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。 + * + * @param userDict ユーザー辞書。 + */ public void useUserDict(UserDict userDict) { rsUseUserDict(userDict); } + /** Open JTalkを廃棄する。 */ public void close() { rsDrop(); } diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Synthesizer.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Synthesizer.java index 295f8b0ad..eefb06785 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Synthesizer.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/Synthesizer.java @@ -9,6 +9,11 @@ import com.google.gson.Gson; +/** + * 音声シンセサイザ。 + * + * @see Synthesizer#builder + */ public class Synthesizer implements AutoCloseable { protected long internal; @@ -16,18 +21,43 @@ private Synthesizer(OpenJtalk openJtalk, SynthesizerBuilder builder) { rsNewWithInitialize(openJtalk, builder); } + /** + * モデルを読み込む。 + * + * @param voiceModel 読み込むモデル。 + */ public void loadVoiceModel(VoiceModel voiceModel) { rsLoadVoiceModel(voiceModel); } + /** + * 音声モデルの読み込みを解除する。 + * + * @param voiceModelId 読み込みを解除する音声モデルのID。 + */ public void unloadVoiceModel(String voiceModelId) { rsUnloadVoiceModel(voiceModelId); } + /** + * 指定した音声モデルのIDが読み込まれているかどうかを返す。 + * + * @param voiceModelId 音声モデルのID。 + * @return 指定した音声モデルのIDが読み込まれているかどうか。 + */ public boolean isLoadedVoiceModel(String voiceModelId) { return rsIsLoadedVoiceModel(voiceModelId); } + /** + * {@link AudioQuery} を生成する。 + * + * @param text テキスト。 + * @param styleId スタイルID。 + * @param options {@link AudioQueryOption} のセット。 + * + * @return 話者とテキストから生成された {@link AudioQuery}。 + */ @Nonnull public AudioQuery audioQuery(String text, int styleId, EnumSet options) { boolean kana = options.contains(AudioQueryOption.KANA); @@ -41,6 +71,15 @@ public AudioQuery audioQuery(String text, int styleId, EnumSet return audioQuery; } + /** + * {@link AccentPhrase} の配列を生成する。 + * + * @param text テキスト。 + * @param styleId スタイルID。 + * @param options {@link AudioQueryOption} のセット。 + * + * @return 話者とテキストから生成された {@link AccentPhrase} の配列。 + */ @Nonnull public List createAccentPhrases(String text, int styleId, EnumSet options) { boolean kana = options.contains(AccentPhrasesOption.KANA); @@ -53,6 +92,14 @@ public List createAccentPhrases(String text, int styleId, EnumSet< return new ArrayList<>(Arrays.asList(rawAccentPhrases)); } + /** + * アクセント句の音高・音素長を変更する。 + * + * @param accentPhrases 変更元のアクセント句の配列。 + * @param styleId スタイルID。 + * + * @return 変更後のアクセント句の配列。 + */ @Nonnull public List replaceMoraData(List accentPhrases, int styleId) { String accentPhrasesJson = new Gson().toJson(accentPhrases); @@ -60,6 +107,14 @@ public List replaceMoraData(List accentPhrases, int return new ArrayList<>(Arrays.asList(new Gson().fromJson(replacedAccentPhrasesJson, AccentPhrase[].class))); } + /** + * アクセント句の音素長を変更する。 + * + * @param accentPhrases 変更元のアクセント句の配列。 + * @param styleId スタイルID。 + * + * @return 変更後のアクセント句の配列。 + */ @Nonnull public List replacePhonemeLength(List accentPhrases, int styleId) { String accentPhrasesJson = new Gson().toJson(accentPhrases); @@ -67,6 +122,14 @@ public List replacePhonemeLength(List accentPhrases, return new ArrayList<>(Arrays.asList(new Gson().fromJson(replacedAccentPhrasesJson, AccentPhrase[].class))); } + /** + * アクセント句の音高を変更する。 + * + * @param accentPhrases 変更元のアクセント句の配列。 + * @param styleId スタイルID。 + * + * @return 変更後のアクセント句の配列。 + */ @Nonnull public List replaceMoraPitch(List accentPhrases, int styleId) { String accentPhrasesJson = new Gson().toJson(accentPhrases); @@ -74,6 +137,15 @@ public List replaceMoraPitch(List accentPhrases, int return new ArrayList<>(Arrays.asList(new Gson().fromJson(replacedAccentPhrasesJson, AccentPhrase[].class))); } + /** + * {@link AudioQuery} から音声合成する。 + * + * @param audioQuery {@link AudioQuery}。 + * @param styleId スタイルID。 + * @param options {@link SynthesisOption} のセット。 + * + * @return WAVデータ。 + */ @Nonnull public byte[] synthesis(AudioQuery audioQuery, int styleId, EnumSet options) { boolean enableInterrogativeUpspeak = options.contains(SynthesisOption.ENABLE_INTERROGATIVE_UPSPEAK); @@ -82,6 +154,15 @@ public byte[] synthesis(AudioQuery audioQuery, int styleId, EnumSet options) { boolean kana = options.contains(TtsOption.KANA); @@ -89,6 +170,9 @@ public byte[] tts(String text, int styleId, EnumSet options) { return rsTts(text, styleId, kana, enableInterrogativeUpspeak); } + /** + * 音声シンセサイザを破棄する。 + */ public void close() { rsDrop(); } @@ -132,6 +216,9 @@ public static SynthesizerBuilder builder(OpenJtalk openJtalk) { return new SynthesizerBuilder(openJtalk); } + /** + * 音声シンセサイザのビルダー。 + */ public static class SynthesizerBuilder { private OpenJtalk openJtalk; @SuppressWarnings("unused") @@ -145,47 +232,64 @@ public SynthesizerBuilder(OpenJtalk openJtalk) { this.openJtalk = openJtalk; } + /** ハードウェアアクセラレーションモードを設定する。 */ public SynthesizerBuilder accelerationMode(AccelerationMode accelerationMode) { this.accelerationMode = accelerationMode; return this; } + /** CPU利用数を指定。0を指定すると環境に合わせたCPUが利用される。 */ public SynthesizerBuilder cpuNumThreads(int cpuNumThreads) { this.cpuNumThreads = cpuNumThreads; return this; } + /** 全てのモデルを読み込むかどうか。 */ public SynthesizerBuilder loadAllModels(boolean loadAllModels) { this.loadAllModels = loadAllModels; return this; } + /** {@link Synthesizer} を構築する。 */ public Synthesizer build() { Synthesizer synthesizer = new Synthesizer(openJtalk, this); return synthesizer; } } + /** ハードウェアアクセラレーションモード。 */ public static enum AccelerationMode { + /** 実行環境に合わせて自動的に選択する。 */ AUTO, + /** CPUに設定する。 */ CPU, + /** GPUに設定する。 */ GPU, } + /** {@link Synthesizer#audioQuery} のオプション。 */ public static enum AudioQueryOption { + /** 入力テキストをAquesTalk風記法として解釈するかどうか。 */ KANA, } + /** {@link Synthesizer#accentPhrases} のオプション。 */ public static enum AccentPhrasesOption { + /** 入力テキストをAquesTalk風記法として解釈するかどうか。 */ KANA, } + /** {@link Synthesizer#synthesis} のオプション。 */ public static enum SynthesisOption { + /** 疑問文の調整を有効にするかどうか。 */ ENABLE_INTERROGATIVE_UPSPEAK } + /** {@link Synthesizer#tts} のオプション。 */ public static enum TtsOption { + /** 入力テキストをAquesTalk風記法として解釈するかどうか。 */ KANA, + /** 疑問文の調整を有効にするかどうか。 */ ENABLE_INTERROGATIVE_UPSPEAK } } diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoiceModel.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoiceModel.java index 4c6f28e21..5f30eb5a2 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoiceModel.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoiceModel.java @@ -7,12 +7,15 @@ import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; +/** 音声モデル。 */ public class VoiceModel implements AutoCloseable { protected long internal; + /** ID。 */ @Nonnull final public String id; + /** メタ情報。 */ @Nonnull final public SpeakerMeta[] metas; @@ -29,6 +32,9 @@ public VoiceModel(String modelPath) { } + /** + * 音声モデルを廃棄する。 + */ public void close() { rsDrop(); } @@ -47,22 +53,27 @@ public void close() { System.loadLibrary("voicevox_core_java_api"); } + /** 話者(speaker)のメタ情報。 */ public static class SpeakerMeta { + /** 話者名。 */ @JsonProperty("name") @SerializedName("name") @Expose @Nonnull final String name; + /** 話者に属するスタイル。 */ @JsonProperty("styles") @SerializedName("styles") @Expose @Nonnull final StyleMeta[] styles; + /** 話者のUUID。 */ @JsonProperty("speaker_uuid") @SerializedName("speaker_uuid") @Expose @Nonnull final String speakerUuid; + /** 話者のバージョン。 */ @JsonProperty("version") @SerializedName("version") @Expose @@ -70,6 +81,8 @@ public static class SpeakerMeta { final String version; private SpeakerMeta() { + // GSONからコンストラクトするため、このメソッドは呼ばれることは無い。 + // このメソッドは@Nonnullを満たすために必要。 this.name = ""; this.styles = new StyleMeta[0]; this.speakerUuid = ""; @@ -77,20 +90,21 @@ private SpeakerMeta() { } } + /** スタイル(style)のメタ情報。 */ public static class StyleMeta { + /** スタイル名。 */ @JsonProperty("name") @SerializedName("name") @Expose @Nonnull final String name; + /** スタイルID。 */ @JsonProperty("id") @SerializedName("id") @Expose final int id; private StyleMeta() { - // GSONからコンストラクトするため、このメソッドは呼ばれることは無い。 - // このメソッドは@Nonnullを満たすために必要。 this.name = ""; this.id = 0; } diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoicevoxException.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoicevoxException.java index 8dfe8e8a7..c2049a822 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoicevoxException.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/Hiroshiba/VoicevoxCore/VoicevoxException.java @@ -1,5 +1,6 @@ package jp.Hiroshiba.VoicevoxCore; +/** VOICEVOX COREのエラー。 */ public class VoicevoxException extends RuntimeException { public VoicevoxException(String message) { super(message);