Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java API:Android版の設計を色々修正 #612

Merged
merged 11 commits into from
Sep 18, 2023
8 changes: 6 additions & 2 deletions crates/voicevox_core_java_api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,29 @@ Java プロジェクトを動かすには、
- `lib/src/main/resources/dll/[target]/libvoicevox_core_java_api.so` を作成する(`libvoicevox_core_java_api.so`はプラットフォームによって異なります、詳細は後述)。

必要があります。
また、ハードウェアアクセラレーションを有効にする時は`TARGET`環境変数を`cuda`または`directml`にし、Android 版をビルドする時は`TARGET`環境変数を`android`にしてください。

```console
❯ cargo build
❯ LD_LIBRARY_PATH=$(realpath ../../target/debug) ./gradlew build
❯ LD_LIBRARY_PATH=$(realpath ../../target/debug) ./gradlew test

# または
❯ cp ../../target/debug/libvoicevox_core_java_api.so lib/src/main/resources/dll/[target]/libvoicevox_core_java_api.so
❯ ./gradlew build
❯ ./gradlew test
❯ TARGET=cuda ./gradlew test
```

## ビルド(リリース)

`cargo build --release` で Rust 側を、`./gradlew build` で Java 側をビルドできます。
パッケージ化する時は lib/src/main/resources/dll 内に dll をコピーしてください。
`TARGET`環境変数は開発時と同様に設定してください。

```console
❯ cargo build --release
❯ cp ../../target/release/libvoicevox_core_java_api.so lib/src/main/resources/dll/[target]/libvoicevox_core_java_api.so
❯ ./gradlew build
❯ TARGET=cuda ./gradlew build
```

## テスト
Expand Down
70 changes: 70 additions & 0 deletions crates/voicevox_core_java_api/lib/build-android.gradle
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java library project to get you started.
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.2.1/userguide/building_java_projects.html in the Gradle documentation.
*/

plugins {
id 'com.android.library' version '8.1.1'
id 'org.jetbrains.kotlin.android' version '1.9.10'
}

def String cargoToml = file('../../../Cargo.toml').text
def String cargoTomlVersion = (cargoToml =~ /version = "([0-9.]+)"/)[0][1]
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved

def String target = System.getenv('TARGET')?.toLowerCase() ?: "cpu"
def boolean isGpu = target.contains('cuda') || target.contains('directml')

version = cargoTomlVersion


repositories {
google()
mavenCentral()
}

dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'

testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:31.1-jre'

// https://mvnrepository.com/artifact/com.google.code.gson/gson
implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1'

// https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api
implementation group: 'jakarta.validation', name: 'jakarta.validation-api', version: '3.0.2'

implementation group: 'com.microsoft.onnxruntime', name: 'onnxruntime-android', version: '1.14.0'
}

// Apply a specific Java toolchain to ease working on different environments.
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}

android {
compileSdkVersion 26

defaultConfig {
minSdkVersion 26
targetSdkVersion 26
}
namespace "jp.hiroshiba.voicevoxcore"

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
jniLibs.srcDirs = ["./src/main/resources/jniLibs"]
}
}
}
20 changes: 13 additions & 7 deletions crates/voicevox_core_java_api/lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ plugins {
id "com.diffplug.spotless" version "6.20.0"
}

version = '0.0.0'
def String cargoToml = file('../../../Cargo.toml').text
def String cargoTomlVersion = (cargoToml =~ /version = "([0-9.]+)"/)[0][1]
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved

def String target = System.getenv('TARGET')?.toLowerCase() ?: "cpu"
def boolean isGpu = target.contains('cuda') || target.contains('directml')
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved

version = cargoTomlVersion

repositories {
// Use Maven Central for resolving dependencies.
Expand All @@ -24,9 +30,6 @@ dependencies {

testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'

// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:31.1-jre'

Expand All @@ -36,16 +39,19 @@ dependencies {
// https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api
implementation group: 'jakarta.validation', name: 'jakarta.validation-api', version: '3.0.2'

implementation group: 'com.microsoft.onnxruntime', name: 'onnxruntime', version: '1.14.0'
if (isGpu) {
implementation group: 'com.microsoft.onnxruntime', name: 'onnxruntime_gpu', version: '1.14.0'
} else {
implementation group: 'com.microsoft.onnxruntime', name: 'onnxruntime', version: '1.14.0'
}
}

// Apply a specific Java toolchain to ease working on different environments.
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
languageVersion = JavaLanguageVersion.of(8)
}
}

tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package jp.hiroshiba.voicevoxcore;

import java.lang.ref.Cleaner;

/** テキスト解析器としてのOpen JTalk。 */
public class OpenJtalk extends Dll {
private long handle;
private static final Cleaner cleaner = Cleaner.create();

/**
* Open JTalkの辞書ディレクトリ。
Expand All @@ -14,14 +10,18 @@ public class OpenJtalk extends Dll {
*/
public OpenJtalk(String openJtalkDictDir) {
rsNewWithInitialize(openJtalkDictDir);
}

cleaner.register(this, () -> rsDrop());
protected void finalize() throws Throwable {
rsDrop();
super.finalize();
}

/**
* ユーザー辞書を設定する。
*
* <p>この関数を呼び出した後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。
* <p>
* この関数を呼び出した後にユーザー辞書を変更した場合は、再度この関数を呼ぶ必要がある。
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ビルドのためにgradlew spotlessApplyしたら色々と変わりました。

*
* @param userDict ユーザー辞書。
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package jp.hiroshiba.voicevoxcore;

import com.google.gson.Gson;
import java.lang.ref.Cleaner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand All @@ -14,11 +13,14 @@
*/
public class Synthesizer extends Dll {
private long handle;
private static final Cleaner cleaner = Cleaner.create();

private Synthesizer(OpenJtalk openJtalk, Builder builder) {
rsNewWithInitialize(openJtalk, builder);
cleaner.register(this, () -> rsDrop());
}

protected void finalize() throws Throwable {
rsDrop();
super.finalize();
}

/**
Expand Down Expand Up @@ -52,10 +54,9 @@ public boolean isLoadedVoiceModel(String voiceModelId) {
/**
* {@link AudioQuery} を生成するためのオブジェクトを生成する。
*
* @param text テキスト。
* @param text テキスト。
* @param styleId スタイルID。
* @return {@link CreateAudioQueryConfigurator}。
*
* @see CreateAudioQueryConfigurator#execute
*/
@Nonnull
Expand All @@ -66,10 +67,9 @@ public CreateAudioQueryConfigurator createAudioQuery(String text, int styleId) {
/**
* {@link AccentPhrase} のリストを生成するためのオブジェクトを生成する。
*
* @param text テキスト。
* @param text テキスト。
* @param styleId スタイルID。
* @return {@link CreateAccentPhrasesConfigurator}。
*
* @see CreateAccentPhrasesConfigurator#execute
*/
@Nonnull
Expand All @@ -81,7 +81,7 @@ public CreateAccentPhrasesConfigurator createAccentPhrases(String text, int styl
* アクセント句の音高・音素長を変更する。
*
* @param accentPhrases 変更元のアクセント句の配列。
* @param styleId スタイルID。
* @param styleId スタイルID。
* @return 変更後のアクセント句の配列。
*/
@Nonnull
Expand All @@ -99,7 +99,7 @@ public List<AccentPhrase> replaceMoraData(List<AccentPhrase> accentPhrases, int
* アクセント句の音素長を変更する。
*
* @param accentPhrases 変更元のアクセント句の配列。
* @param styleId スタイルID。
* @param styleId スタイルID。
* @return 変更後のアクセント句の配列。
*/
@Nonnull
Expand All @@ -117,7 +117,7 @@ public List<AccentPhrase> replacePhonemeLength(List<AccentPhrase> accentPhrases,
* アクセント句の音高を変更する。
*
* @param accentPhrases 変更元のアクセント句の配列。
* @param styleId スタイルID。
* @param styleId スタイルID。
* @return 変更後のアクセント句の配列。
*/
@Nonnull
Expand All @@ -135,9 +135,8 @@ public List<AccentPhrase> replaceMoraPitch(List<AccentPhrase> accentPhrases, int
* {@link AudioQuery} から音声合成するためのオブジェクトを生成する。
*
* @param audioQuery {@link AudioQuery}。
* @param styleId スタイルID。
* @param styleId スタイルID。
* @return {@link SynthesisConfigurator}。
*
* @see SynthesisConfigurator#execute
*/
@Nonnull
Expand All @@ -148,10 +147,9 @@ public SynthesisConfigurator synthesis(AudioQuery audioQuery, int styleId) {
/**
* テキスト音声合成を実行するためのオブジェクトを生成する。
*
* @param text テキスト。
* @param text テキスト。
* @param styleId スタイルID。
* @return {@link TtsConfigurator}。
*
* @see TtsConfigurator#execute
*/
@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
import com.google.gson.internal.LinkedTreeMap;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;

import java.lang.ref.Cleaner;
import java.util.HashMap;
import javax.annotation.Nonnull;

/** ユーザー辞書。 */
public class UserDict extends Dll {
private long handle;
private static final Cleaner cleaner = Cleaner.create();

/** ユーザー辞書を作成する。 */
public UserDict() {
rsNew();
}

cleaner.register(this, () -> rsDrop());
protected void finalize() throws Throwable {
rsDrop();
super.finalize();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.lang.ref.Cleaner;
import javax.annotation.Nonnull;

/** 音声モデル。 */
public class VoiceModel extends Dll {
private long handle;
private static final Cleaner cleaner = Cleaner.create();

/** ID。 */
@Nonnull public final String id;
Expand All @@ -27,8 +25,11 @@ public VoiceModel(String modelPath) {
throw new RuntimeException("Failed to parse metasJson");
}
metas = rawMetas;
}

cleaner.register(this, () -> rsDrop());
protected void finalize() throws Throwable {
rsDrop();
super.finalize();
}

private native void rsFromPath(String modelPath);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
このディレクトリに Android での JNI 用に読み込まれる DLL を配置します。
ディレクトリ名は以下のうちのいずれかになります。

- `arm64-v8a`
- `x86_64`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#558 (comment)
これで消えてなかったので消しました。

Empty file.
22 changes: 22 additions & 0 deletions crates/voicevox_core_java_api/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}

resolutionStrategy {
eachPlugin {
if(requested.id.namespace == "com.android") {
useModule("com.android.tools.build:gradle:${requested.version}")
}
}
}
}
plugins {
// Apply the foojay-resolver plugin to allow automatic download of JDKs
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0'
}

rootProject.name = 'jp.hiroshiba.voicevoxcore'
def String target = System.getenv('TARGET')?.toLowerCase() ?: "cpu"
def boolean isAndroid = target == 'android'
include('lib')
if (isAndroid) {
project(':lib').buildFileName = 'build-android.gradle'
} else {
project(':lib').buildFileName = 'build.gradle'
}
Loading