Skip to content

Commit 1376acd

Browse files
authored
Merge pull request #14 from umjammer/0.0.13
0.0.13
2 parents e88906e + 7c7e647 commit 1376acd

File tree

16 files changed

+202
-33
lines changed

16 files changed

+202
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ tmp/
22
lib/
33
local.properties
44
src/test/resources/nicotalk/
5+
sudachi

pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<groupId>vavi</groupId>
1010
<artifactId>vavi-speech2</artifactId>
11-
<version>0.0.12</version>
11+
<version>0.0.13</version>
1212

1313
<name>vavi-speech2</name>
1414
<description/>
@@ -219,7 +219,7 @@
219219
<dependency>
220220
<groupId>com.github.umjammer</groupId> <!-- vavi / com.github.umjammer -->
221221
<artifactId>vavi-speech</artifactId>
222-
<version>0.1.9</version>
222+
<version>0.1.10</version>
223223
<exclusions>
224224
<exclusion>
225225
<groupId>javax.speech</groupId>
@@ -269,9 +269,9 @@
269269
</dependency>
270270

271271
<dependency>
272-
<groupId>com.github.umjammer</groupId>
273-
<artifactId>Gyutan</artifactId>
274-
<version>0.0.2</version>
272+
<groupId>com.github.umjammer</groupId> <!-- icn-lab / com.github.umjammer -->
273+
<artifactId>Gyutan</artifactId> <!-- gyutan / Gyutan -->
274+
<version>0.0.3</version>
275275
</dependency>
276276

277277
<dependency>

src/main/java/vavi/speech/aquestalk10/jsapi2/AquesTalk10Synthesizer.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import java.io.IOException;
1111
import java.io.InputStream;
1212
import java.util.logging.Logger;
13-
1413
import javax.sound.sampled.AudioFormat;
1514
import javax.sound.sampled.AudioSystem;
1615
import javax.sound.sampled.UnsupportedAudioFileException;
@@ -25,7 +24,6 @@
2524
import org.jvoicexml.jsapi2.BaseAudioSegment;
2625
import org.jvoicexml.jsapi2.BaseEngineProperties;
2726
import org.jvoicexml.jsapi2.synthesis.BaseSynthesizer;
28-
2927
import vavi.beans.InstanciationBinder;
3028
import vavi.speech.Phonemizer;
3129
import vavi.speech.aquestalk10.jna.AquesTalk10.AQTK_VOICE;
@@ -142,7 +140,7 @@ public boolean handleResume() {
142140
public AudioSegment handleSpeak(int id, String item) {
143141
try {
144142
aquesTalk10.setVoice(toNativeVoice(getSynthesizerProperties().getVoice()));
145-
byte[] bytes = aquesTalk10.synthe(phonemizer.phoneme(item));
143+
byte[] bytes = aquesTalk10.synthesize(phonemizer.phoneme(item));
146144
AudioManager manager = getAudioManager();
147145
String locator = manager.getMediaLocator();
148146
// you should pass bytes to BaseAudioSegment as AudioInputStream or causes crackling!

src/main/java/vavi/speech/googlecloud/jsapi2/GoogleCloudTextToSpeechSynthesizer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public boolean handleResume() {
139139
@Override
140140
public AudioSegment handleSpeak(int id, String item) {
141141
try {
142-
byte[] bytes = synthesis(item);
142+
byte[] bytes = synthesize(item);
143143
AudioManager manager = getAudioManager();
144144
String locator = manager.getMediaLocator();
145145
// you should pass bytes to BaseAudioSegment as AudioInputStream or causes crackling!
@@ -157,7 +157,7 @@ public AudioSegment handleSpeak(int id, String item) {
157157
}
158158

159159
/** */
160-
private byte[] synthesis(String text) {
160+
private byte[] synthesize(String text) {
161161
SynthesisInput input = SynthesisInput.newBuilder().setText(text).build();
162162

163163
VoiceSelectionParams voice = VoiceSelectionParams.newBuilder()

src/main/java/vavi/speech/gyutan/jsapi2/GyutanSynthesizer.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.nio.file.Path;
1515
import java.nio.file.Paths;
1616
import java.util.Scanner;
17+
import java.util.logging.Level;
1718
import java.util.logging.Logger;
1819
import javax.sound.sampled.AudioFormat;
1920
import javax.sound.sampled.AudioInputStream;
@@ -31,6 +32,7 @@
3132
import org.jvoicexml.jsapi2.BaseAudioSegment;
3233
import org.jvoicexml.jsapi2.BaseEngineProperties;
3334
import org.jvoicexml.jsapi2.synthesis.BaseSynthesizer;
35+
import vavi.util.Debug;
3436

3537

3638
/**
@@ -44,9 +46,6 @@ public final class GyutanSynthesizer extends BaseSynthesizer {
4446
/** Logger for this class. */
4547
private static final Logger logger = Logger.getLogger(GyutanSynthesizer.class.getName());
4648

47-
/** */
48-
private final Gyutan gyutan = new Gyutan();
49-
5049
/**
5150
* Constructs a new synthesizer object.
5251
*
@@ -115,7 +114,7 @@ public void handleDeallocate() {
115114
// Leave some time to let all resources detach
116115
try {
117116
Thread.sleep(500);
118-
} catch (InterruptedException e) {
117+
} catch (InterruptedException ignored) {
119118
}
120119

121120
//
@@ -151,14 +150,11 @@ public AudioSegment handleSpeak(int id, String item) {
151150
/** */
152151
private AudioInputStream synthe(String text) {
153152
try {
154-
//System.err.println("vioce: " + getSynthesizerProperties().getVoice());
153+
Debug.println(Level.FINER, "vioce: " + getSynthesizerProperties().getVoice());
155154
Path wave = Files.createTempFile(getClass().getName(), ".wav");
156155
Path voice = toNativeVoice(getSynthesizerProperties().getVoice());
157-
boolean flag = gyutan.initialize(System.getProperty("sen.home"), voice.toString());
158-
if (!flag) {
159-
throw new IOException("initialize");
160-
}
161-
gyutan.synthesis(text, new FileOutputStream(wave.toFile()), null);
156+
Gyutan gyutan = new Gyutan(System.getProperty("sen.home"), voice.toString());
157+
gyutan.synthesize(text, new FileOutputStream(wave.toFile()), null);
162158
byte[] wav = Files.readAllBytes(wave);
163159
ByteArrayInputStream bais = new ByteArrayInputStream(wav);
164160
// you should pass bytes to BaseAudioSegment as AudioInputStream or causes crackling!

src/main/java/vavi/speech/openjtalk/jsapi2/OpenJTalkSynthesizer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public AudioSegment handleSpeak(int id, String item) {
130130
AudioManager manager = getAudioManager();
131131
String locator = manager.getMediaLocator();
132132
// you should pass bytes to BaseAudioSegment as AudioInputStream or causes crackling!
133-
InputStream in = synthesis(item);
133+
InputStream in = synthesize(item);
134134
AudioSegment segment;
135135
if (locator == null) {
136136
segment = new BaseAudioSegment(item, in);
@@ -141,7 +141,7 @@ public AudioSegment handleSpeak(int id, String item) {
141141
}
142142

143143
/** */
144-
private AudioInputStream synthesis(String text) {
144+
private AudioInputStream synthesize(String text) {
145145
try {
146146
//logger.log(Level.DEBUG, "vioce: " + getSynthesizerProperties().getVoice());
147147
openJTalk.setVoice(toNativeVoice(getSynthesizerProperties().getVoice()));

src/main/java/vavi/speech/rococoa/jsapi2/RococoaSynthesizer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public AudioSegment handleSpeak(int id, String item) {
160160
if (false) {
161161
AudioManager manager = getAudioManager();
162162
String locator = manager.getMediaLocator();
163-
InputStream in = synthesis(item);
163+
InputStream in = synthesize(item);
164164
AudioSegment segment;
165165
if (locator == null) {
166166
segment = new BaseAudioSegment(item, in);
@@ -184,7 +184,7 @@ public AudioSegment handleSpeak(int id, String item) {
184184
}
185185

186186
/** */
187-
private AudioInputStream synthesis(String text) {
187+
private AudioInputStream synthesize(String text) {
188188
try {
189189
//Debug.println(Level.FINER, "voice: " + getSynthesizerProperties().getVoice());
190190
AVSpeechUtterance utterance = AVSpeechUtterance.of(text);

src/main/java/vavi/speech/voicevox/VoiceVox.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public AudioQuery getQuery(String text, int speakerId) {
159159
}
160160

161161
/** */
162-
public InputStream synthesis(AudioQuery audioQuery, int speakerId) {
162+
public InputStream synthesize(AudioQuery audioQuery, int speakerId) {
163163
Entity<String> entity = Entity.entity(gson.toJson(audioQuery), MediaType.APPLICATION_JSON);
164164
return target.path("synthesis")
165165
.queryParam("speaker", speakerId)

src/main/java/vavi/speech/voicevox/jsapi2/VoiceVoxSynthesizer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public AudioSegment handleSpeak(int id, String item) {
125125
// audioQuery.setSpeed(props.getSpeakingRate() / 200f);
126126
// audioQuery.setPitch(props.getPitch() / 300f);
127127
// audioQuery.setIntonation(props.getPitchRange());
128-
InputStream wave = client.synthesis(audioQuery, voiceId);
128+
InputStream wave = client.synthesize(audioQuery, voiceId);
129129
AudioManager manager = getAudioManager();
130130
String locator = manager.getMediaLocator();
131131
// you should pass bytes to BaseAudioSegment as AudioInputStream or causes crackling!

src/test/java/Jsapi2Test_aquestalk10.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@
1414
import javax.speech.synthesis.SynthesizerMode;
1515
import javax.speech.synthesis.Voice;
1616

17+
import org.junit.jupiter.api.BeforeEach;
1718
import org.junit.jupiter.api.Test;
1819
import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable;
20+
import org.junit.jupiter.api.condition.EnabledIf;
1921
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
22+
import vavi.util.Debug;
23+
import vavi.util.properties.annotation.Property;
24+
import vavi.util.properties.annotation.PropsEntity;
2025

2126

2227
/**
@@ -25,10 +30,25 @@
2530
* @author <a href="mailto:umjammer@gmail.com">Naohide Sano</a> (umjammer)
2631
* @version 0.00 2019/09/21 umjammer initial version <br>
2732
*/
33+
@PropsEntity(url = "file:local.properties")
2834
@EnabledIfSystemProperty(named = "os.arch", matches = "x86_64")
2935
@DisabledIfEnvironmentVariable(named = "GITHUB_WORKFLOW", matches = ".*")
3036
class Jsapi2Test_aquestalk10 {
3137

38+
static boolean localPropertiesExists() {
39+
return Files.exists(Paths.get("local.properties"));
40+
}
41+
42+
@Property(name = "text")
43+
String text = "src/test/resources/test.txt";
44+
45+
@BeforeEach
46+
void setup() throws Exception {
47+
if (localPropertiesExists()) {
48+
PropsEntity.Util.bind(this);
49+
}
50+
}
51+
3252
/**
3353
* @param args 0: text
3454
*/
@@ -47,8 +67,9 @@ void test01() throws Exception {
4767
}
4868

4969
@Test
70+
@EnabledIf("localPropertiesExists")
5071
void test02() throws Exception {
51-
Path path = Paths.get("tmp/repezen.txt");
72+
Path path = Paths.get(text);
5273
String text = String.join("\n", Files.readAllLines(path));
5374
speak(text);
5475
}
@@ -69,6 +90,7 @@ void speak(String text) throws Exception {
6990
synthesizer.getSynthesizerProperties().setVoice(voice);
7091
synthesizer.getSynthesizerProperties().setVolume(2);
7192

93+
Debug.println("split " + text.split("[。\n]").length);
7294
for (String line : text.split("[。\n]")) {
7395
System.out.println(line);
7496
synthesizer.speak(line + "。", System.err::println);
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2023 by Naohide Sano, All rights reserved.
3+
*
4+
* Programmed by Naohide Sano
5+
*/
6+
7+
package vavi.speech.voicevox;
8+
9+
import java.io.BufferedInputStream;
10+
import java.io.InputStream;
11+
import java.util.Arrays;
12+
import java.util.concurrent.CountDownLatch;
13+
import javax.sound.sampled.AudioInputStream;
14+
import javax.sound.sampled.AudioSystem;
15+
import javax.sound.sampled.Clip;
16+
import javax.sound.sampled.DataLine;
17+
import javax.sound.sampled.LineEvent;
18+
import javax.speech.synthesis.Voice;
19+
20+
import com.google.gson.Gson;
21+
import com.google.gson.GsonBuilder;
22+
import jakarta.ws.rs.client.Client;
23+
import jakarta.ws.rs.client.ClientBuilder;
24+
import jakarta.ws.rs.client.Entity;
25+
import jakarta.ws.rs.client.WebTarget;
26+
import jakarta.ws.rs.core.MediaType;
27+
import org.junit.jupiter.api.BeforeEach;
28+
import org.junit.jupiter.api.DisplayName;
29+
import org.junit.jupiter.api.Test;
30+
import vavi.speech.voicevox.VoiceVox.AudioQuery;
31+
import vavi.speech.voicevox.VoiceVox.Speaker;
32+
import vavi.speech.voicevox.VoiceVox.SpeakerInfo;
33+
import vavi.util.Debug;
34+
35+
import static org.junit.jupiter.api.Assertions.assertEquals;
36+
37+
38+
/**
39+
* CoeiroInkTest.
40+
*
41+
* @author <a href="mailto:umjammer@gmail.com">Naohide Sano</a> (nsano)
42+
* @version 0.00 2023-04-22 nsano initial version <br>
43+
*/
44+
class CoeiroInkTest {
45+
46+
private WebTarget target;
47+
48+
@BeforeEach
49+
public void setUp() throws Exception {
50+
Client c = ClientBuilder.newClient();
51+
target = c.target("http://localhost:50032/");
52+
}
53+
54+
@Test
55+
@DisplayName("raw rest api")
56+
void test1() throws Exception {
57+
String text = "これはテストです。";
58+
59+
int speakerId = 1; // つくよみちゃん(れいせい)
60+
61+
String query = target
62+
.path("audio_query")
63+
.queryParam("text", text)
64+
.queryParam("speaker", 1)
65+
.request()
66+
.post(null, String.class);
67+
Debug.println(query);
68+
69+
Entity<String> entity = Entity.entity(query, MediaType.APPLICATION_JSON);
70+
InputStream wav = target
71+
.path("synthesis")
72+
.queryParam("speaker", 1)
73+
.request()
74+
.post(entity, InputStream.class);
75+
speak(wav);
76+
}
77+
78+
/** */
79+
static void speak(InputStream is) throws Exception {
80+
AudioInputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(is));
81+
DataLine.Info line = new DataLine.Info(Clip.class, ais.getFormat());
82+
Clip clip = (Clip) AudioSystem.getLine(line);
83+
CountDownLatch cdl = new CountDownLatch(1);
84+
clip.addLineListener(e -> { if (e.getType() == LineEvent.Type.STOP) cdl.countDown(); });
85+
clip.open(ais);
86+
clip.start();
87+
cdl.await();
88+
clip.stop();
89+
clip.close();
90+
}
91+
92+
static Gson gson = new GsonBuilder().setPrettyPrinting().create();
93+
94+
@Test
95+
void test2() throws Exception {
96+
//
97+
String version = target
98+
.path("version")
99+
.request()
100+
.get(String.class);
101+
Debug.println("version: " + version);
102+
103+
//
104+
String presets = target
105+
.path("presets")
106+
.request()
107+
.get(String.class);
108+
Debug.println("presets: " + presets);
109+
110+
//
111+
String speakersJson = target
112+
.path("speakers")
113+
.request()
114+
.get(String.class);
115+
//Debug.println("speakers: " + speakers);
116+
117+
Speaker[] speakers = gson.fromJson(speakersJson, Speaker[].class);
118+
Arrays.stream(speakers).forEach(System.err::println);
119+
120+
Arrays.stream(speakers).forEach(s -> {
121+
String speakerInfoJson = target
122+
.path("speaker_info")
123+
.queryParam("speaker_uuid", s.speaker_uuid)
124+
.request()
125+
.get(String.class);
126+
SpeakerInfo speakerInfo = gson.fromJson(speakerInfoJson, SpeakerInfo.class);
127+
Debug.println("SpeakerInfo: " + speakerInfo);
128+
});
129+
}
130+
131+
@Test
132+
@DisplayName("use wrapped api")
133+
void test3() throws Exception {
134+
int speakerId = 3; // ずんだもん(ノーマル)
135+
VoiceVox voiceVox = new VoiceVox();
136+
AudioQuery audioQuery = voiceVox.getQuery("ひざまずくが良いのだ、この愚かな地球人共よ", speakerId);
137+
audioQuery.setSpeed(1.1f);
138+
audioQuery.setVolume(0.2f);
139+
speak(voiceVox.synthesize(audioQuery, speakerId));
140+
}
141+
142+
@Test
143+
@DisplayName("wrapped api list voices")
144+
void test4() throws Exception {
145+
VoiceVox voiceVox = new VoiceVox();
146+
Voice[] voices = voiceVox.getAllVoices();
147+
Arrays.stream(voices).forEach(System.err::println);
148+
assertEquals(22, voiceVox.getId(voices[10]));
149+
}
150+
}

0 commit comments

Comments
 (0)