Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,43 @@ An easy-to-use local text to speech library for Java.

It can produce reasonable quality audio using low-specced hardware.

It provides four main components
It provides several components

* Code to retrieve and run the voice models from the [piper](https://github.com/rhasspy/piper) project
* Code to run the voice models from the [piper](https://github.com/rhasspy/piper) project
* A piper-compatible pure Java phonemizer for English partially ported from [phonemize](https://github.com/hans00/phonemize)
* Compatible phoneme dictionaries for uk and us English
* A multi-lingual phonemizer using the [onnx model](https://huggingface.co/OpenVoiceOS/g2p-mbyt5-12l-ipa-childes-espeak-onnx) from OpenVoiceOs
* A small number of piper models available as dependencies on maven central
* Code to download other models not uploaded to central

The models are run using the onnxruntime library, so can utilise both CPU and GPU.

## Releases

See [Releases](https://github.com/hcoles/voices/releases)

## English-Only Usage
## English-Only Usage With Rules Based Phonemizer

Using Voices requires three dependencies
Using Voices requires three code dependencies and one or more models.

```xml
<!-- main dependency -->
<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>chorus</artifactId>
<version>0.0.4</version>
<version>0.0.5</version>
</dependency>
<!-- a prepackaged model -->
<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>alba</artifactId>
<version>0.0.5</version>
</dependency>
<!-- dictionary of pronunciations -->
<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>en_uk</artifactId> <!-- or en_us -->
<version>0.0.4</version>
<version>0.0.5</version>
</dependency>
<!-- runtime for onnx models -->
<dependency>
Expand All @@ -50,25 +58,41 @@ Using Voices requires three dependencies
</dependency>
```

Technically, Voices can be used without a dictionary, but the quality of the speech would be poor.
Technically, the rules based phonemizer can be used without a dictionary, but the quality of the speech would be poor.

The `Chorus` class acts as a manager for voice models, handling loading and freeing of resources. Loading is an expensive
operation, so it is recommended to keep a single instance of `Chorus` for the lifetime of your application.

```java
ChorusConfig config = chorusConfig(EnUkDictionary.en_uk());
try (Chorus chorus = new Chorus(config)) {
Voice alba = chorus.voice(Models.albaMedium());
Voice jenny = chorus.voice(Models.jennyDiocoMedium());

Audio audio = alba.say("Hello there, I'm vaguely Scottish");
audio = audio.append(jenny.say("I'm not."));
audio = audio.append(alba.withGain(0.5f).say("I am much quieter"));

Voice alba = chorus.voice(Alba.albaMedium());

Audio audio = alba.say("Hello there, I'm vaguely Scottish.");
audio.save(some path);
}
```

The example above uses a model retrieved at build time as a normal maven dependency.

A wider range of models can be retrieved at runtime by adding the model downloader dependency.

```xml
<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>model-downloader</artifactId>
<version>0.0.5</version>
</dependency>
```

Models can be retrieved using the factory methods on the

* org.pitest.voices.download.Models
* org.pitest.voices.download.UsModels
* org.pitest.voices.download.NonEnglishModels

Classes.

By default, voice models are downloaded to `~/.cache/voices/`, but this can be configured in ChorusConfig.

## Multi-lingual Usage
Expand Down
67 changes: 67 additions & 0 deletions alba/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.pitest.voices</groupId>
<artifactId>voices-parent</artifactId>
<version>${revision}</version>
</parent>

<artifactId>alba</artifactId>
<name>alba</name>

<packaging>jar</packaging>

<licenses>
<license>
<name>Apache 2</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<dependencies>

<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>alba-model</artifactId>
<version>${models.version}</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>

</build>


</project>
14 changes: 14 additions & 0 deletions alba/src/main/java/org/pitest/voices/alba/Alba.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.pitest.voices.alba;

import org.pitest.voices.ClassPathModel;
import org.pitest.voices.Language;
import org.pitest.voices.Model;

public class Alba {

public static Model albaMedium() {
return new ClassPathModel("/models/vits-piper-en_GB-alba-medium/en_GB-alba-medium.onnx",
Language.en_GB,
2.0f);
}
}
31 changes: 31 additions & 0 deletions alba/src/test/java/org/pitest/voices/alba/AlbaTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.pitest.voices.alba;

import org.junit.jupiter.api.Test;
import org.pitest.voices.Language;
import org.pitest.voices.Model;

import java.io.IOException;
import java.nio.file.Path;

import static org.assertj.core.api.Assertions.assertThat;

class AlbaTest {

Model underTest = Alba.albaMedium();

@Test
void speaksProperEnglish() {
assertThat(underTest.language()).isEqualTo(Language.en_GB);
}


@Test
void loadsResources() throws IOException {
assertThat(underTest.asBytes(unused())).hasSizeGreaterThan(50000);
assertThat(underTest.resolveConfig(unused()).sampleRate()).isEqualTo(22050L);
}

private Path unused() {
return null;
}
}
67 changes: 67 additions & 0 deletions bryce/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.pitest.voices</groupId>
<artifactId>voices-parent</artifactId>
<version>${revision}</version>
</parent>

<artifactId>bryce</artifactId>
<name>bryce</name>

<packaging>jar</packaging>

<licenses>
<license>
<name>Apache 2</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<dependencies>

<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>bryce-model</artifactId>
<version>${models.version}</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>

</build>


</project>
14 changes: 14 additions & 0 deletions bryce/src/main/java/org/pitest/voices/bryce/Bryce.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.pitest.voices.bryce;

import org.pitest.voices.ClassPathModel;
import org.pitest.voices.Language;
import org.pitest.voices.Model;

public class Bryce {

public static Model bryceMedium() {
return new ClassPathModel("/models/vits-piper-en_US-bryce-medium/en_US-bryce-medium.onnx",
Language.en_US,
1.0f);
}
}
30 changes: 30 additions & 0 deletions bryce/src/test/java/org/pitest/voices/bryce/BryceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.pitest.voices.bryce;

import org.junit.jupiter.api.Test;
import org.pitest.voices.Language;
import org.pitest.voices.Model;

import java.io.IOException;
import java.nio.file.Path;

import static org.assertj.core.api.Assertions.assertThat;

class BryceTest {

Model underTest = Bryce.bryceMedium();

@Test
void speaksUSEnglish() {
assertThat(underTest.language()).isEqualTo(Language.en_US);
}

@Test
void loadsResources() throws IOException {
assertThat(underTest.asBytes(unused())).hasSizeGreaterThan(50000);
assertThat(underTest.resolveConfig(unused()).sampleRate()).isEqualTo(22050L);
}

private Path unused() {
return null;
}
}
28 changes: 8 additions & 20 deletions chorus/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>g2p</artifactId>
<artifactId>core</artifactId>
<version>${project.parent.version}</version>
</dependency>

Expand All @@ -36,12 +36,6 @@
<version>2.5.5</version>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.13.2</version>
</dependency>

<dependency>
<groupId>com.microsoft.onnxruntime</groupId>
<artifactId>onnxruntime</artifactId>
Expand All @@ -56,25 +50,19 @@
<version>2.0.16</version>
</dependency>


<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.28.0</version>
</dependency>


<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.pitest.voices</groupId>
<artifactId>alba</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>


</dependencies>

Expand Down
Loading