Skip to content

Commit 6cacd0e

Browse files
authored
Testing updates (#56)
1 parent c4b7a64 commit 6cacd0e

File tree

20 files changed

+1656
-1082
lines changed

20 files changed

+1656
-1082
lines changed

binding/android/OrcaTestApp/orca-test-app/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,13 @@ android {
8181
java {
8282
if (System.getProperty("testBuildType", "debug") == "perf") {
8383
exclude "**/StandardTests.java"
84-
exclude "**/ModelTests.java"
84+
exclude "**/AlignmentTests.java"
85+
exclude "**/SentenceTests.java"
8586
exclude "**/IntegrationTest.java"
8687
} else if (System.getProperty("testBuildType", "debug") == "integ") {
8788
exclude "**/StandardTests.java"
88-
exclude "**/ModelTests.java"
89+
exclude "**/AlignmentTests.java"
90+
exclude "**/SentenceTests.java"
8991
exclude "**/PerformanceTest.java"
9092
} else {
9193
exclude "**/IntegrationTest.java"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
Copyright 2025 Picovoice Inc.
3+
4+
You may not use this file except in compliance with the license. A copy of the license is
5+
located in the "LICENSE" file accompanying this source.
6+
7+
Unless required by applicable law or agreed to in writing, software distributed under the
8+
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
9+
express or implied. See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
package ai.picovoice.orca.testapp;
14+
15+
import static org.junit.Assert.assertNotEquals;
16+
import static org.junit.Assert.assertNotNull;
17+
import static org.junit.Assert.assertTrue;
18+
import static org.junit.Assert.fail;
19+
20+
import com.google.gson.JsonArray;
21+
import com.google.gson.JsonElement;
22+
import com.google.gson.JsonObject;
23+
import com.google.gson.JsonParser;
24+
25+
import org.junit.After;
26+
import org.junit.Before;
27+
import org.junit.Test;
28+
import org.junit.runner.RunWith;
29+
import org.junit.runners.Parameterized;
30+
31+
import java.io.File;
32+
33+
import java.io.IOException;
34+
import java.util.ArrayList;
35+
import java.util.Arrays;
36+
import java.util.Collection;
37+
import java.util.List;
38+
import java.util.Objects;
39+
40+
import ai.picovoice.orca.Orca;
41+
import ai.picovoice.orca.OrcaAudio;
42+
import ai.picovoice.orca.OrcaException;
43+
import ai.picovoice.orca.OrcaInvalidArgumentException;
44+
import ai.picovoice.orca.OrcaSynthesizeParams;
45+
import ai.picovoice.orca.OrcaWord;
46+
import ai.picovoice.orca.OrcaPhoneme;
47+
48+
@RunWith(Parameterized.class)
49+
public class AlignmentTests extends BaseTest {
50+
51+
@Parameterized.Parameter(value = 0)
52+
public String language;
53+
54+
@Parameterized.Parameter(value = 1)
55+
public String modelFilename;
56+
57+
@Parameterized.Parameter(value = 2)
58+
public int randomState;
59+
60+
@Parameterized.Parameter(value = 3)
61+
public String textAlignment;
62+
63+
@Parameterized.Parameter(value = 4)
64+
public JsonArray alignments;
65+
66+
@Parameterized.Parameters(name = "{0} {1}")
67+
public static Collection<Object[]> initParameters() throws IOException {
68+
String testDataJsonString = getTestDataString();
69+
70+
JsonParser parser = new JsonParser();
71+
JsonObject testDataJson = parser.parse(testDataJsonString).getAsJsonObject();
72+
73+
final JsonArray testCases = testDataJson.getAsJsonObject("tests").get("alignment_tests").getAsJsonArray();
74+
75+
List<Object[]> parameters = new ArrayList<>();
76+
for (JsonElement testCaseElem : testCases) {
77+
JsonObject testCase = testCaseElem.getAsJsonObject();
78+
79+
String language = testCase.get("language").getAsString();
80+
String model = testCase.get("model").getAsString();
81+
int random_state = testCase.get("random_state").getAsInt();
82+
String text_alignment = testCase.get("text_alignment").getAsString();
83+
JsonArray alignments = testCase.get("alignments").getAsJsonArray();
84+
85+
parameters.add(new Object[]{language, model, random_state, text_alignment, alignments});
86+
}
87+
88+
return parameters;
89+
}
90+
91+
Orca orca;
92+
93+
@Before
94+
public void Setup() throws Exception {
95+
super.Setup();
96+
97+
orca = new Orca.Builder()
98+
.setAccessKey(accessKey)
99+
.setModelPath(getModelFilepath(modelFilename))
100+
.build(appContext);
101+
}
102+
103+
@After
104+
public void TearDown() {
105+
if (orca != null) {
106+
orca.delete();
107+
}
108+
}
109+
110+
@Test
111+
public void testSynthesizeAlignment() throws OrcaException {
112+
final OrcaAudio result = orca.synthesize(
113+
textAlignment,
114+
new OrcaSynthesizeParams.Builder()
115+
.setRandomState(randomState)
116+
.build());
117+
final OrcaWord[] synthesizeTestData = new OrcaWord[alignments.size()];
118+
for (int i = 0; i < alignments.size(); i++) {
119+
final JsonObject testData = alignments.get(i).getAsJsonObject();
120+
final String word = testData.get("word").getAsString();
121+
final float startSec = testData.get("start_sec").getAsFloat();
122+
final float endSec = testData.get("end_sec").getAsFloat();
123+
final JsonArray phonemesJson = testData.getAsJsonArray("phonemes");
124+
final OrcaPhoneme[] phonemes = new OrcaPhoneme[phonemesJson.size()];
125+
for (int j = 0; j < phonemesJson.size(); j++) {
126+
final JsonObject phonemeJson = phonemesJson.get(j).getAsJsonObject();
127+
phonemes[j] = new OrcaPhoneme(
128+
phonemeJson.get("phoneme").getAsString(),
129+
phonemeJson.get("start_sec").getAsFloat(),
130+
phonemeJson.get("end_sec").getAsFloat());
131+
}
132+
synthesizeTestData[i] = new OrcaWord(
133+
word,
134+
startSec,
135+
endSec,
136+
phonemes);
137+
}
138+
validateMetadata(
139+
result.getWordArray(),
140+
synthesizeTestData,
141+
true);
142+
}
143+
144+
@Test
145+
public void testSynthesizeToFileAlignment() throws OrcaException {
146+
final File outputFile = new File(
147+
appContext.getFilesDir(),
148+
"text.wav");
149+
OrcaWord[] result = orca.synthesizeToFile(
150+
textAlignment,
151+
outputFile.getAbsolutePath(),
152+
new OrcaSynthesizeParams.Builder()
153+
.setRandomState(randomState)
154+
.build());
155+
outputFile.delete();
156+
157+
final OrcaWord[] synthesizeTestData = new OrcaWord[alignments.size()];
158+
for (int i = 0; i < alignments.size(); i++) {
159+
final JsonObject testData = alignments.get(i).getAsJsonObject();
160+
final String word = testData.get("word").getAsString();
161+
final float startSec = testData.get("start_sec").getAsFloat();
162+
final float endSec = testData.get("end_sec").getAsFloat();
163+
final JsonArray phonemesJson = testData.getAsJsonArray("phonemes");
164+
final OrcaPhoneme[] phonemes = new OrcaPhoneme[phonemesJson.size()];
165+
for (int j = 0; j < phonemesJson.size(); j++) {
166+
final JsonObject phonemeJson = phonemesJson.get(j).getAsJsonObject();
167+
phonemes[j] = new OrcaPhoneme(
168+
phonemeJson.get("phoneme").getAsString(),
169+
phonemeJson.get("start_sec").getAsFloat(),
170+
phonemeJson.get("end_sec").getAsFloat());
171+
}
172+
synthesizeTestData[i] = new OrcaWord(
173+
word,
174+
startSec,
175+
endSec,
176+
phonemes);
177+
}
178+
validateMetadata(
179+
result,
180+
synthesizeTestData,
181+
true);
182+
}
183+
}

binding/android/OrcaTestApp/orca-test-app/src/androidTest/java/ai/picovoice/orca/testapp/BaseTest.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2024 Picovoice Inc.
2+
Copyright 2024-2025 Picovoice Inc.
33
44
You may not use this file except in compliance with the license. A copy of the license is
55
located in the "LICENSE" file accompanying this source.
@@ -70,19 +70,37 @@ public void Setup() throws Exception {
7070
accessKey = appContext.getString(R.string.pvTestingAccessKey);
7171
}
7272

73-
public static String[] getModelFiles() {
73+
public static String getTestDataString() throws IOException {
74+
Context testContext = InstrumentationRegistry.getInstrumentation().getContext();
75+
AssetManager assetManager = testContext.getAssets();
76+
77+
InputStream is = new BufferedInputStream(assetManager.open("test_resources/test_data.json"), 256);
78+
ByteArrayOutputStream result = new ByteArrayOutputStream();
79+
80+
byte[] buffer = new byte[256];
81+
int bytesRead;
82+
while ((bytesRead = is.read(buffer)) != -1) {
83+
result.write(buffer, 0, bytesRead);
84+
}
85+
86+
return result.toString("UTF-8");
87+
}
88+
89+
public static String getModelFilepath(String modelFilename) {
90+
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
91+
String resPath = new File(
92+
context.getFilesDir(),
93+
"test_resources").getAbsolutePath();
94+
return new File(resPath, String.format("model_files/%s", modelFilename)).getAbsolutePath();
95+
}
96+
97+
public static String getAudioFilepath(String modelFilename, String synthesisType) {
7498
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
7599
String resPath = new File(
76100
context.getFilesDir(),
77101
"test_resources").getAbsolutePath();
78-
return new String[]{
79-
new File(
80-
resPath,
81-
"model_files/orca_params_female.pv").getAbsolutePath(),
82-
new File(
83-
resPath,
84-
"model_files/orca_params_male.pv").getAbsolutePath()
85-
};
102+
String audioFilename = modelFilename.replace(".pv", String.format("_%s.wav", synthesisType));
103+
return new File(resPath, String.format("wav/%s", audioFilename)).getAbsolutePath();
86104
}
87105

88106
protected static boolean compareArrays(short[] arr1, short[] arr2, int step) {

binding/android/OrcaTestApp/orca-test-app/src/androidTest/java/ai/picovoice/orca/testapp/PerformanceTest.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2024 Picovoice Inc.
2+
Copyright 2024-2025 Picovoice Inc.
33
44
You may not use this file except in compliance with the license. A copy of the license is
55
located in the "LICENSE" file accompanying this source.
@@ -14,12 +14,18 @@
1414

1515
import static org.junit.Assert.assertTrue;
1616

17+
import com.google.gson.JsonArray;
18+
import com.google.gson.JsonElement;
19+
import com.google.gson.JsonObject;
20+
import com.google.gson.JsonParser;
21+
1722
import org.junit.Assume;
1823
import org.junit.Before;
1924
import org.junit.Test;
2025
import org.junit.runner.RunWith;
2126
import org.junit.runners.Parameterized;
2227

28+
import java.io.IOException;
2329
import java.util.ArrayList;
2430
import java.util.Collection;
2531
import java.util.List;
@@ -33,10 +39,19 @@ public class PerformanceTest extends BaseTest {
3339
public String modelFile;
3440

3541
@Parameterized.Parameters(name = "{0}")
36-
public static Collection<Object[]> initParameters() {
42+
public static Collection<Object[]> initParameters() throws IOException {
43+
String testDataJsonString = getTestDataString();
44+
45+
JsonParser parser = new JsonParser();
46+
JsonObject testDataJson = parser.parse(testDataJsonString).getAsJsonObject();
47+
48+
final JsonArray testCases = testDataJson.getAsJsonObject("tests").get("sentence_tests").getAsJsonArray();
49+
JsonObject testCase = testCases.get(0).getAsJsonObject();
50+
3751
List<Object[]> parameters = new ArrayList<>();
38-
for (String modelFile : getModelFiles()) {
39-
parameters.add(new Object[]{modelFile});
52+
for (JsonElement modelJson : testCase.get("models").getAsJsonArray()) {
53+
String model = modelJson.getAsString();
54+
parameters.add(new Object[]{model});
4055
}
4156
return parameters;
4257
}

0 commit comments

Comments
 (0)