diff --git a/.github/workflows/android-perf.yml b/.github/workflows/android-perf.yml index d542ca0..694d7db 100644 --- a/.github/workflows/android-perf.yml +++ b/.github/workflows/android-perf.yml @@ -82,7 +82,7 @@ jobs: run: ./gradlew assembleDebug - name: Build androidTest - run: ./gradlew assembleDebugAndroidTest + run: ./gradlew assembleDebugAndroidTest -DtestBuildType=perf - name: Run tests on AppCenter run: appcenter test run espresso diff --git a/README.md b/README.md index 9489b65..f8dfcc7 100644 --- a/README.md +++ b/README.md @@ -235,7 +235,7 @@ dependencies { } ``` -Create an instance of the engine and generate speech: +Create an instance of the engine and perform speaker diarization on an audio file: ```java import ai.picovoice.falcon.*; @@ -247,7 +247,7 @@ try { .build(appContext); File audioFile = new File("${AUDIO_FILE_PATH}"); - FalconSegments segments = falcon.processFile(audioFile.getAbsolutePath()); + FalconSegment[] segments = falcon.processFile(audioFile.getAbsolutePath()); } catch (FalconException ex) { } ``` diff --git a/binding/android/Falcon/falcon/consumer-rules.pro b/binding/android/Falcon/falcon/consumer-rules.pro index b010a39..2c9f8b1 100644 --- a/binding/android/Falcon/falcon/consumer-rules.pro +++ b/binding/android/Falcon/falcon/consumer-rules.pro @@ -1,2 +1,2 @@ -keep class ai.picovoice.falcon.*Exception { (...); } --keep class ai.picovoice.falcon.FalconSegments { (...); } +-keep class ai.picovoice.falcon.FalconSegment { (...); } diff --git a/binding/android/Falcon/falcon/proguard-rules.pro b/binding/android/Falcon/falcon/proguard-rules.pro index b010a39..2c9f8b1 100644 --- a/binding/android/Falcon/falcon/proguard-rules.pro +++ b/binding/android/Falcon/falcon/proguard-rules.pro @@ -1,2 +1,2 @@ -keep class ai.picovoice.falcon.*Exception { (...); } --keep class ai.picovoice.falcon.FalconSegments { (...); } +-keep class ai.picovoice.falcon.FalconSegment { (...); } diff --git a/binding/android/Falcon/falcon/src/main/java/ai/picovoice/Falcon.java b/binding/android/Falcon/falcon/src/main/java/ai/picovoice/Falcon.java index c9de00b..251e294 100644 --- a/binding/android/Falcon/falcon/src/main/java/ai/picovoice/Falcon.java +++ b/binding/android/Falcon/falcon/src/main/java/ai/picovoice/Falcon.java @@ -89,10 +89,10 @@ public void delete() { * equal to {@link #getSampleRate()} and be 16-bit linearly-encoded. Furthermore, * Falcon operates on single channel audio. If you wish to process data in a different * sample rate or format, consider using {@link #processFile(String)}. - * @return FalconSegments object which contains the diarization results of the engine. + * @return FalconSegment[] object which contains the diarization results of the engine. * @throws FalconException if there is an error while processing the audio frame. */ - public FalconSegments process(short[] pcm) throws FalconException { + public FalconSegment[] process(short[] pcm) throws FalconException { if (handle == 0) { throw new FalconInvalidStateException("Attempted to call Falcon process after delete."); } @@ -109,10 +109,10 @@ public FalconSegments process(short[] pcm) throws FalconException { * * @param path Absolute path to the audio file. The supported formats are: * `3gp (AMR)`, `FLAC`, `MP3`, `MP4/m4a (AAC)`, `Ogg`, `WAV` and `WebM`. - * @return FalconSegments object which contains the diarization results of the engine. + * @return FalconSegment[] object which contains the diarization results of the engine. * @throws FalconException if there is an error while processing the audio frame. */ - public FalconSegments processFile(String path) throws FalconException { + public FalconSegment[] processFile(String path) throws FalconException { if (handle == 0) { throw new FalconInvalidStateException("Attempted to call Falcon processFile after delete."); } diff --git a/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconNative.java b/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconNative.java index b96d39e..2521252 100644 --- a/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconNative.java +++ b/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconNative.java @@ -26,12 +26,12 @@ static native long init( static native void delete(long object); - static native FalconSegments process( + static native FalconSegment[] process( long object, short[] pcm, int numSamples) throws FalconException; - static native FalconSegments processFile( + static native FalconSegment[] processFile( long object, String path) throws FalconException; } diff --git a/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconSegment.java b/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconSegment.java new file mode 100644 index 0000000..e7c3d3b --- /dev/null +++ b/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconSegment.java @@ -0,0 +1,66 @@ +/* + Copyright 2024 Picovoice Inc. + + You may not use this file except in compliance with the license. A copy of the license is + located in the "LICENSE" file accompanying this source. + + Unless required by applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + express or implied. See the License for the specific language governing permissions and + limitations under the License. +*/ + +package ai.picovoice.falcon; + +/** + * FalconSegment class. + */ +public class FalconSegment { + private final float startSec; + private final float endSec; + private final int speakerTag; + + /** + * Constructor. + * + * @param startSec Start of segment in seconds. + * @param endSec End of segment in seconds. + * @param speakerTag A non-negative integer that identifies unique speakers. + */ + public FalconSegment( + float startSec, + float endSec, + int speakerTag + ) { + this.startSec = startSec; + this.endSec = endSec; + this.speakerTag = speakerTag; + } + + /** + * Getter for the start of segment in seconds. + * + * @return Start of segment in seconds. + */ + public float getStartSec() { + return startSec; + } + + /** + * Getter for the end of segment in seconds. + * + * @return End of segment in seconds. + */ + public float getEndSec() { + return endSec; + } + + /** + * Getter for the speaker tag. + * + * @return Speaker tag. + */ + public int getSpeakerTag() { + return speakerTag; + } +} diff --git a/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconSegments.java b/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconSegments.java deleted file mode 100644 index 6cabec5..0000000 --- a/binding/android/Falcon/falcon/src/main/java/ai/picovoice/FalconSegments.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright 2024 Picovoice Inc. - - You may not use this file except in compliance with the license. A copy of the license is - located in the "LICENSE" file accompanying this source. - - Unless required by applicable law or agreed to in writing, software distributed under the - License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - express or implied. See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ai.picovoice.falcon; - -/** - * FalconSegments Class. - */ -public class FalconSegments { - - private final Segment[] segmentArray; - - /** - * Constructor. - * - * @param segmentArray Diarized segments and their associated metadata. - */ - public FalconSegments(Segment[] segmentArray) { - this.segmentArray = segmentArray; - } - - /** - * Getter for diarized segments and their associated metadata. - * - * @return Diarized segments and their associated metadata. - */ - public Segment[] getSegmentArray() { - return segmentArray; - } - - /** - * FalconSegments.Segment class - */ - public static class Segment { - private final float startSec; - private final float endSec; - private final int speakerTag; - - /** - * Constructor. - * - * @param startSec Start of segment in seconds. - * @param endSec End of segment in seconds. - * @param speakerTag A non-negative integer that identifies unique speakers. - */ - public Segment( - float startSec, - float endSec, - int speakerTag - ) { - this.startSec = startSec; - this.endSec = endSec; - this.speakerTag = speakerTag; - } - - /** - * Getter for the start of segment in seconds. - * - * @return Start of segment in seconds. - */ - public float getStartSec() { - return startSec; - } - - /** - * Getter for the end of segment in seconds. - * - * @return End of segment in seconds. - */ - public float getEndSec() { - return endSec; - } - - /** - * Getter for the speaker tag. - * - * @return Speaker tag. - */ - public int getSpeakerTag() { - return speakerTag; - } - } -} diff --git a/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/BaseTest.java b/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/BaseTest.java index 0c1c68d..97cc0ab 100644 --- a/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/BaseTest.java +++ b/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/BaseTest.java @@ -39,7 +39,7 @@ import java.nio.ByteOrder; import java.util.Arrays; -import ai.picovoice.falcon.FalconSegments; +import ai.picovoice.falcon.FalconSegment; public class BaseTest { @@ -105,8 +105,8 @@ protected static short[] readAudioFile(String audioFile) throws Exception { } protected void validateMetadata( - FalconSegments.Segment[] segments, - FalconSegments.Segment[] expectedSegments + FalconSegment[] segments, + FalconSegment[] expectedSegments ) { assertEquals(segments.length, expectedSegments.length); for (int i = 0; i < segments.length; i++) { diff --git a/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/FalconTest.java b/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/FalconTest.java index 9d9c07f..5c9a0db 100644 --- a/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/FalconTest.java +++ b/binding/android/FalconTestApp/falcon-test-app/src/androidTest/java/ai/picovoice/falcon/testapp/FalconTest.java @@ -31,7 +31,7 @@ import ai.picovoice.falcon.Falcon; import ai.picovoice.falcon.FalconException; -import ai.picovoice.falcon.FalconSegments; +import ai.picovoice.falcon.FalconSegment; @RunWith(Enclosed.class) @@ -136,7 +136,7 @@ public static class DiarizationTests extends BaseTest { public String testAudioFile; @Parameterized.Parameter(value = 1) - public FalconSegments.Segment[] expectedSegments; + public FalconSegment[] expectedSegments; @Parameterized.Parameters(name = "{0}") public static Collection initParameters() throws IOException { @@ -157,7 +157,7 @@ public static Collection initParameters() throws IOException { String testAudioFile = String.format("audio_samples/%s", audioFile); - FalconSegments.Segment[] paramSegments = new FalconSegments.Segment[segments.size()]; + FalconSegment[] paramSegments = new FalconSegment[segments.size()]; for (int j = 0; j < segments.size(); j++) { JsonObject segmentObject = segments.get(j).getAsJsonObject(); @@ -165,7 +165,7 @@ public static Collection initParameters() throws IOException { float endSec = segmentObject.get("end_sec").getAsFloat(); int speakerTag = segmentObject.get("speaker_tag").getAsInt(); - paramSegments[j] = new FalconSegments.Segment( + paramSegments[j] = new FalconSegment( startSec, endSec, speakerTag @@ -190,11 +190,11 @@ public void testDiarization() throws Exception { File audioFile = new File(testResourcesPath, testAudioFile); short[] pcm = readAudioFile(audioFile.getAbsolutePath()); - FalconSegments result = falcon.process(pcm); + FalconSegment[] result = falcon.process(pcm); - assertEquals(result.getSegmentArray().length, expectedSegments.length); - for (int i = 0; i < result.getSegmentArray().length; i++) { - validateMetadata(result.getSegmentArray(), expectedSegments); + assertEquals(result.length, expectedSegments.length); + for (int i = 0; i < result.length; i++) { + validateMetadata(result, expectedSegments); } falcon.delete(); } diff --git a/binding/android/FalconTestApp/falcon-test-app/src/main/java/ai/picovoice/falcon/testapp/MainActivity.java b/binding/android/FalconTestApp/falcon-test-app/src/main/java/ai/picovoice/falcon/testapp/MainActivity.java index fbf8778..1c0b6c6 100644 --- a/binding/android/FalconTestApp/falcon-test-app/src/main/java/ai/picovoice/falcon/testapp/MainActivity.java +++ b/binding/android/FalconTestApp/falcon-test-app/src/main/java/ai/picovoice/falcon/testapp/MainActivity.java @@ -40,7 +40,7 @@ import ai.picovoice.falcon.Falcon; import ai.picovoice.falcon.FalconException; -import ai.picovoice.falcon.FalconSegments; +import ai.picovoice.falcon.FalconSegment; public class MainActivity extends AppCompatActivity { @@ -93,7 +93,7 @@ public void runTest() { result = new TestResult(); result.testName = "Test Process"; try { - FalconSegments processResult = processTestAudio(falcon, "audio_samples/test.wav"); + FalconSegment[] processResult = processTestAudio(falcon, "audio_samples/test.wav"); if (processResult != null) { result.success = true; } else { @@ -176,7 +176,7 @@ private String getModelFile() { return "models/falcon_params.pv"; } - private FalconSegments processTestAudio(@NonNull Falcon l, String audioPath) throws Exception { + private FalconSegment[] processTestAudio(@NonNull Falcon l, String audioPath) throws Exception { File testAudio = new File(getApplicationContext().getFilesDir(), audioPath); if (!testAudio.exists()) { diff --git a/binding/android/README.md b/binding/android/README.md index b8c0047..b61fccc 100644 --- a/binding/android/README.md +++ b/binding/android/README.md @@ -62,7 +62,7 @@ Perform diarization on an audio file by providing the absolute path to the file: ```java File audioFile = new File("${AUDIO_FILE_PATH}"); -FalconSegments segments = falcon.processFile(audioFile.getAbsolutePath()); +FalconSegment[] segments = falcon.processFile(audioFile.getAbsolutePath()); ``` Perform diarization on raw audio data (sample rate of 16 kHz, 16-bit linearly encoded and 1 channel): @@ -71,7 +71,7 @@ Perform diarization on raw audio data (sample rate of 16 kHz, 16-bit linearly en short[] getAudioData() { // ... } -FalconSegments segments = falcon.process(getAudioData()); +FalconSegment[] segments = falcon.process(getAudioData()); ``` The return value `segments` represents an array of segments, each with the following metadata items: diff --git a/demo/android/FalconDemo/README.md b/demo/android/FalconDemo/README.md index 862e76f..d44c8fb 100644 --- a/demo/android/FalconDemo/README.md +++ b/demo/android/FalconDemo/README.md @@ -29,5 +29,3 @@ Ensure you have an Android device connected or simulator running. Then run the f cd demo/android/FalconDemo ./gradlew connectedAndroidTest -PpvTestingAccessKey="YOUR_ACCESS_KEY_HERE" ``` - -The test results are stored in `falcon-demo-app/build/reports`. diff --git a/demo/android/FalconDemo/build.gradle b/demo/android/FalconDemo/build.gradle index 45dbaac..a5129f4 100644 --- a/demo/android/FalconDemo/build.gradle +++ b/demo/android/FalconDemo/build.gradle @@ -7,7 +7,7 @@ buildscript { google() mavenCentral() maven { - url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1322/' + url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1323/' } } dependencies { @@ -20,7 +20,7 @@ allprojects { google() mavenCentral() maven { - url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1322/' + url 'https://s01.oss.sonatype.org/content/repositories/aipicovoice-1323/' } } } diff --git a/demo/android/FalconDemo/falcon-demo-app/src/main/java/ai/picovoice/falcondemo/MainActivity.java b/demo/android/FalconDemo/falcon-demo-app/src/main/java/ai/picovoice/falcondemo/MainActivity.java index 17d70f1..94dfdaf 100644 --- a/demo/android/FalconDemo/falcon-demo-app/src/main/java/ai/picovoice/falcondemo/MainActivity.java +++ b/demo/android/FalconDemo/falcon-demo-app/src/main/java/ai/picovoice/falcondemo/MainActivity.java @@ -46,7 +46,7 @@ import ai.picovoice.falcon.FalconActivationThrottledException; import ai.picovoice.falcon.FalconException; import ai.picovoice.falcon.FalconInvalidArgumentException; -import ai.picovoice.falcon.FalconSegments; +import ai.picovoice.falcon.FalconSegment; public class MainActivity extends AppCompatActivity { private static final String ACCESS_KEY = "${YOUR_ACCESS_KEY_HERE}"; @@ -208,7 +208,7 @@ private void stopRecording() { new Thread(() -> { try { long diarizationStart = System.currentTimeMillis(); - FalconSegments segments = falcon.process(pcmDataArray); + FalconSegment[] segments = falcon.process(pcmDataArray); long diarizationEnd = System.currentTimeMillis(); float diarizationTime = (diarizationEnd - diarizationStart) / 1000f; @@ -228,7 +228,7 @@ private void stopRecording() { ResultsViewAdaptor searchResultsViewAdaptor = new ResultsViewAdaptor( getApplicationContext(), - Arrays.asList(segments.getSegmentArray())); + Arrays.asList(segments)); resultsView.setAdapter(searchResultsViewAdaptor); }); } catch (FalconException e) { @@ -280,10 +280,10 @@ private enum UIState { } private static class ResultsViewAdaptor extends RecyclerView.Adapter { - private final List data; + private final List data; private final LayoutInflater inflater; - ResultsViewAdaptor(Context context, List data) { + ResultsViewAdaptor(Context context, List data) { this.inflater = LayoutInflater.from(context); this.data = data; } @@ -298,7 +298,7 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @SuppressLint("DefaultLocale") @Override public void onBindViewHolder(ViewHolder holder, int position) { - FalconSegments.Segment segment = data.get(position); + FalconSegment segment = data.get(position); holder.speakerTag.setText(String.format("%d", segment.getSpeakerTag())); holder.startSec.setText(String.format("%.2fs", segment.getStartSec())); holder.endSec.setText(String.format("%.2fs", segment.getEndSec())); diff --git a/lib/android/arm64-v8a/libpv_falcon.so b/lib/android/arm64-v8a/libpv_falcon.so index d694886..b20847e 100755 Binary files a/lib/android/arm64-v8a/libpv_falcon.so and b/lib/android/arm64-v8a/libpv_falcon.so differ diff --git a/lib/android/armeabi-v7a/libpv_falcon.so b/lib/android/armeabi-v7a/libpv_falcon.so index ccd5302..9ca2d2b 100755 Binary files a/lib/android/armeabi-v7a/libpv_falcon.so and b/lib/android/armeabi-v7a/libpv_falcon.so differ diff --git a/lib/android/x86/libpv_falcon.so b/lib/android/x86/libpv_falcon.so index 5b29804..195869a 100755 Binary files a/lib/android/x86/libpv_falcon.so and b/lib/android/x86/libpv_falcon.so differ diff --git a/lib/android/x86_64/libpv_falcon.so b/lib/android/x86_64/libpv_falcon.so index 75432de..114891a 100755 Binary files a/lib/android/x86_64/libpv_falcon.so and b/lib/android/x86_64/libpv_falcon.so differ